diff --git a/.gitignore b/.gitignore
index 00cedaff9e97e5fa3dfe53f7a5297d472bbb6265..d376fff67dc0f5c877ed8b353572fd93d7614793 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,6 +53,7 @@ coverage.xml
 .pytest_cache/
 .benchmarks/
 cover/
+*_report.xml
 
 # Translations
 *.mo
@@ -130,6 +131,9 @@ venv.bak/
 # VSCode project settings
 .vscode/
 
+# Visual Studio project settings
+/.vs
+
 # Rope project settings
 .ropeproject
 
@@ -158,6 +162,9 @@ cython_debug/
 
 # TeraFlowSDN-generated files
 tfs_runtime_env_vars.sh
+delete_local_deployment.sh
+local_docker_deployment.sh
+local_k8s_deployment.sh
 
 # Symlink for generated proto-files in host
 src/context/proto
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ffbf9e9f5f02bd0514d4584f6f2ad32761b6264f..3de792462d28b2d42e71b0329aefce2c2928984e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -41,3 +41,4 @@ include:
   #- local: '/src/l3_attackmitigator/.gitlab-ci.yml'
   #- local: '/src/slice/.gitlab-ci.yml'
   #- local: '/src/interdomain/.gitlab-ci.yml'
+  - local: '/src/pathcomp/.gitlab-ci.yml'
diff --git a/common_requirements.in b/common_requirements.in
index 8a027cfbd1ecf8bf4adc535dd9d5e3a769a2f2f8..772c1115d857664ed113007b89a6f7f9d9c48b99 100644
--- a/common_requirements.in
+++ b/common_requirements.in
@@ -6,3 +6,4 @@ prometheus-client==0.13.0
 protobuf==3.20.*
 pytest==6.2.5
 pytest-benchmark==3.4.1
+python-dateutil==2.8.2
diff --git a/deploy.sh b/deploy.sh
index 172889c07acdc2347b2dee2ddee8bf3061fdc53a..c5dee68a06e000bf7df90ef437e77c14232f2cec 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -58,18 +58,6 @@ kubectl delete namespace $TFS_K8S_NAMESPACE
 kubectl create namespace $TFS_K8S_NAMESPACE
 printf "\n"
 
-if [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then
-    echo "Creating secrets for InfluxDB..."
-    #TODO: make sure to change this when having a production deployment
-    kubectl create secret generic influxdb-secrets --namespace=$TFS_K8S_NAMESPACE \
-        --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=$TFS_K8S_NAMESPACE \
-        --from-literal=INFLUXDB_DATABASE="monitoring" --from-literal=INFLUXDB_USER="teraflow" \
-        --from-literal=INFLUXDB_PASSWORD="teraflow" --from-literal=INFLUXDB_HOSTNAME="localhost"
-    printf "\n"
-fi
-
 echo "Deploying components and collecting environment variables..."
 ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh
 echo "# Environment variables for TeraFlowSDN deployment" > $ENV_VARS_SCRIPT
@@ -86,35 +74,80 @@ for COMPONENT in $TFS_COMPONENTS; do
 
     if [ "$COMPONENT" == "automation" ] || [ "$COMPONENT" == "policy" ]; then
         docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
-    else 
+    elif [ "$COMPONENT" == "pathcomp" ]; then
+        BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-frontend.log"
+        docker build -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . >> "$BUILD_LOG"
+
+        BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-backend.log"
+        docker build -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
+        # next command is redundant, but helpful to keep cache updated between rebuilds
+        docker build -t "$COMPONENT-backend:$TFS_IMAGE_TAG-builder" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
+    else
         docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG"
     fi
 
     if [ -n "$TFS_REGISTRY_IMAGE" ]; then
         echo "  Pushing Docker image to '$TFS_REGISTRY_IMAGE'..."
 
-        TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log"
-        docker tag "$IMAGE_NAME" "$IMAGE_URL" > "$TAG_LOG"
+        if [ "$COMPONENT" == "pathcomp" ]; then
+            TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log"
+            docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL-frontend" > "$TAG_LOG"
+
+            TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log"
+            docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL-backend" > "$TAG_LOG"
 
-        PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log"
-        docker push "$IMAGE_URL" > "$PUSH_LOG"
+            PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log"
+            docker push "$IMAGE_URL-frontend" > "$PUSH_LOG"
+
+            PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log"
+            docker push "$IMAGE_URL-backend" > "$PUSH_LOG"
+        else
+            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
     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 "$TFS_REGISTRY_IMAGE" ]; then
         # Registry is set
-        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
-        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+        if [ "$COMPONENT" == "pathcomp" ]; then
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_URL-frontend#g" "$MANIFEST"
+
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_URL-backend#g" "$MANIFEST"
+
+            sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+        else
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+            sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+        fi
     else
         # Registry is not set
-        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_NAME#g" "$MANIFEST"
-        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" "$MANIFEST"        
+        if [ "$COMPONENT" == "pathcomp" ]; then
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_NAME-frontend#g" "$MANIFEST"
+
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_NAME-backend#g" "$MANIFEST"
+
+            sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" "$MANIFEST"
+        else
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3)
+            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
     fi
 
+    # TODO: harmonize names of the monitoring component
+
     echo "  Deploying '$COMPONENT' component to Kubernetes..."
     DEPLOY_LOG="$TMP_LOGS_FOLDER/deploy_${COMPONENT}.log"
     kubectl --namespace $TFS_K8S_NAMESPACE apply -f "$MANIFEST" > "$DEPLOY_LOG"
@@ -169,12 +202,12 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"
     echo "Configuring WebUI DataStores and Dashboards..."
     sleep 3
 
-    INFLUXDB_HOST="monitoringservice"
-    INFLUXDB_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service/monitoringservice -o jsonpath='{.spec.ports[?(@.name=="influxdb")].port}')
-    INFLUXDB_URL="http://${INFLUXDB_HOST}:${INFLUXDB_PORT}"
-    INFLUXDB_USER=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode)
-    INFLUXDB_PASSWORD=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode)
-    INFLUXDB_DATABASE=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode)
+    # INFLUXDB_HOST="monitoringservice"
+    # INFLUXDB_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service/monitoringservice -o jsonpath='{.spec.ports[?(@.name=="influxdb")].port}')
+    # INFLUXDB_URL="http://${INFLUXDB_HOST}:${INFLUXDB_PORT}"
+    # INFLUXDB_USER=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode)
+    # INFLUXDB_PASSWORD=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode)
+    # INFLUXDB_DATABASE=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode)
 
     # Exposed through the ingress controller "tfs-ingress"
     GRAFANA_HOSTNAME="127.0.0.1"
@@ -191,6 +224,8 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"
     # Updated Grafana API URL
     GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}"
 
+    echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT
+
     echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..."
 
     # Configure Grafana Admin Password
@@ -202,26 +237,38 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"
     }' ${GRAFANA_URL_DEFAULT}/api/user/password
     echo
 
-    # Create InfluxDB DataSource
     # Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/
-    curl -X POST -H "Content-Type: application/json" -d '{
-        "type"     : "influxdb",
-        "name"     : "InfluxDB",
-        "url"      : "'"$INFLUXDB_URL"'",
+    # TODO: replace user, password and database by variables to be saved
+    echo "Creating a datasource..."
+    curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{
         "access"   : "proxy",
-        "basicAuth": false,
-        "user"     : "'"$INFLUXDB_USER"'",
-        "password" : "'"$INFLUXDB_PASSWORD"'",
+        "type"     : "postgres",
+        "name"     : "monitoringdb",
+        "url"      : "monitoringservice:8812",
+        "database" : "monitoring",
+        "user"     : "admin",
+        "password" : "quest",
+        "basicAuth" : false,
         "isDefault": true,
-        "database" : "'"$INFLUXDB_DATABASE"'"
+        "jsonData" : {
+            "sslmode"         : "disable",
+            "postgresVersion" : 1100,
+            "tlsAuth"         : false,
+            "tlsAuthWithCACert": false,
+            "tlsConfigurationMethod": "file-path",
+            "tlsSkipVerify": true
+        },
+        "secureJsonFields" : {
+            "password" : true
+        }
     }' ${GRAFANA_URL_UPDATED}/api/datasources
     echo
 
     # Create Monitoring Dashboard
     # Ref: https://grafana.com/docs/grafana/latest/http_api/dashboard/
     curl -X POST -H "Content-Type: application/json" \
-    -d '@src/webui/grafana_dashboard.json' \
-    ${GRAFANA_URL_UPDATED}/api/dashboards/db
+        -d '@src/webui/grafana_dashboard.json' \
+        ${GRAFANA_URL_UPDATED}/api/dashboards/db
     echo
 
     DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tf-l3-monit"
diff --git a/deploy_component.sh b/deploy_component.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a4cf6184c83ef026562abe8e084430bba3ead9c8
--- /dev/null
+++ b/deploy_component.sh
@@ -0,0 +1,186 @@
+#!/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.
+
+
+########################################################################################################################
+# Read deployment settings
+########################################################################################################################
+
+# If not already set, set the URL of your local Docker registry where the images will be uploaded to.
+# Leave it blank if you do not want to use any Docker registry.
+export TFS_REGISTRY_IMAGE=${TFS_REGISTRY_IMAGE:-""}
+#export TFS_REGISTRY_IMAGE="http://my-container-registry.local/"
+
+TFS_COMPONENTS=$1
+
+# If not already set, set the tag you want to use for your images.
+export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"}
+
+# If not already set, set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+# If not already set, set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS=${TFS_EXTRA_MANIFESTS:-""}
+
+# If not already set, set the neew Grafana admin password
+export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"}
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+# 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"
+TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
+
+echo "Deploying component and collecting environment variables..."
+ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh
+
+for COMPONENT in $TFS_COMPONENTS; do
+    echo "Processing '$COMPONENT' component..."
+    IMAGE_NAME="$COMPONENT:$TFS_IMAGE_TAG"
+    IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGE/$IMAGE_NAME" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+    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"
+    elif [ "$COMPONENT" == "pathcomp" ]; then
+        BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-frontend.log"
+        docker build -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . >> "$BUILD_LOG"
+
+        BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-backend.log"
+        docker build -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
+        # next command is redundant, but helpful to keep cache updated between rebuilds
+        docker build -t "$COMPONENT-backend:$TFS_IMAGE_TAG-builder" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
+    else
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG"
+    fi
+
+    if [ -n "$TFS_REGISTRY_IMAGE" ]; then
+        echo "  Pushing Docker image to '$TFS_REGISTRY_IMAGE'..."
+
+        if [ "$COMPONENT" == "pathcomp" ]; then
+            TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log"
+            docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL-frontend" > "$TAG_LOG"
+
+            TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log"
+            docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL-backend" > "$TAG_LOG"
+
+            PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log"
+            docker push "$IMAGE_URL-frontend" > "$PUSH_LOG"
+
+            PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log"
+            docker push "$IMAGE_URL-backend" > "$PUSH_LOG"
+        else
+            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
+    fi
+
+    echo "  Adapting '$COMPONENT' manifest file..."
+    MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml"
+    cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST"
+
+    if [ -n "$TFS_REGISTRY_IMAGE" ]; then
+        # Registry is set
+        if [ "$COMPONENT" == "pathcomp" ]; then
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_URL-frontend#g" "$MANIFEST"
+
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_URL-backend#g" "$MANIFEST"
+
+            sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+        else
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+            sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+        fi
+    else
+        # Registry is not set
+        if [ "$COMPONENT" == "pathcomp" ]; then
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_NAME-frontend#g" "$MANIFEST"
+
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f3)
+            sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_NAME-backend#g" "$MANIFEST"
+
+            sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" "$MANIFEST"
+        else
+            VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3)
+            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
+    fi
+
+    # TODO: harmonize names of the monitoring component
+
+    echo "  Deploying '$COMPONENT' component to Kubernetes..."
+    DEPLOY_LOG="$TMP_LOGS_FOLDER/deploy_${COMPONENT}.log"
+    kubectl --namespace $TFS_K8S_NAMESPACE delete -f "$MANIFEST" > "$DEPLOY_LOG"
+    kubectl --namespace $TFS_K8S_NAMESPACE apply -f "$MANIFEST" > "$DEPLOY_LOG"
+    COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/")
+    kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=0 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG"
+    kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=1 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG"
+
+    echo "  Collecting env-vars for '$COMPONENT' component..."
+
+    SERVICE_DATA=$(kubectl get service ${COMPONENT}service --namespace $TFS_K8S_NAMESPACE -o json)
+    if [ -z "${SERVICE_DATA}" ]; then continue; fi
+
+    # Env vars for service's host address
+    SERVICE_HOST=$(echo ${SERVICE_DATA} | jq -r '.spec.clusterIP')
+    if [ -z "${SERVICE_HOST}" ]; then continue; fi
+    # TODO: remove previous value from file
+    ENVVAR_HOST=$(echo "${COMPONENT}service_SERVICE_HOST" | tr '[:lower:]' '[:upper:]')
+    echo "export ${ENVVAR_HOST}=${SERVICE_HOST}" >> $ENV_VARS_SCRIPT
+
+    # Env vars for service's 'grpc' port (if any)
+    SERVICE_PORT_GRPC=$(echo ${SERVICE_DATA} | jq -r '.spec.ports[] | select(.name=="grpc") | .port')
+    if [ -n "${SERVICE_PORT_GRPC}" ]; then
+        ENVVAR_PORT_GRPC=$(echo "${COMPONENT}service_SERVICE_PORT_GRPC" | tr '[:lower:]' '[:upper:]')
+        echo "export ${ENVVAR_PORT_GRPC}=${SERVICE_PORT_GRPC}" >> $ENV_VARS_SCRIPT
+    fi
+
+    # Env vars for service's 'http' port (if any)
+    SERVICE_PORT_HTTP=$(echo ${SERVICE_DATA} | jq -r '.spec.ports[] | select(.name=="http") | .port')
+    if [ -n "${SERVICE_PORT_HTTP}" ]; then
+        ENVVAR_PORT_HTTP=$(echo "${COMPONENT}service_SERVICE_PORT_HTTP" | tr '[:lower:]' '[:upper:]')
+        echo "export ${ENVVAR_PORT_HTTP}=${SERVICE_PORT_HTTP}" >> $ENV_VARS_SCRIPT
+    fi
+
+    printf "\n"
+done
+
+# By now, leave this control here. Some component dependencies are not well handled
+for COMPONENT in $TFS_COMPONENTS; do
+    echo "Waiting for '$COMPONENT' component..."
+    kubectl wait --namespace $TFS_K8S_NAMESPACE \
+        --for='condition=available' --timeout=300s deployment/${COMPONENT}service
+    printf "\n"
+done
+
+./show_deploy.sh
+
+echo "Done!"
diff --git a/ecoc22 b/ecoc22
new file mode 120000
index 0000000000000000000000000000000000000000..3c61895e5ac62d0b38ce058ba5ff042442542320
--- /dev/null
+++ b/ecoc22
@@ -0,0 +1 @@
+src/tests/ecoc22/
\ No newline at end of file
diff --git a/expose_ingress_grpc.sh b/expose_ingress_grpc.sh
index 8a4c837406d06ae8971a4d6ab2c5a8ae30cfc87f..e2667247afdf72cc2f48317ace24275408eb11aa 100755
--- a/expose_ingress_grpc.sh
+++ b/expose_ingress_grpc.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 # If not already set, set the list of components you want to build images for, and deploy.
 export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device automation policy service compute monitoring dbscanserving opticalattackmitigator opticalcentralizedattackdetector webui"}
@@ -32,6 +32,7 @@ for COMPONENT in $TFS_COMPONENTS; do
     echo "Processing '$COMPONENT' component..."
 
     SERVICE_GRPC_PORT=$(kubectl get service ${COMPONENT}service --namespace $TFS_K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.name=="grpc")].port}')
+    echo "    '$COMPONENT' service port: $SERVICE_GRPC_PORT"
     if [ -z "${SERVICE_GRPC_PORT}" ]; then
         printf "\n"
         continue;
diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml
index 171394f7c43b2447e898902c78d5276fe1bcbc7c..46c7557d9178d1bb2bc36eda13a088606f56cede 100644
--- a/manifests/deviceservice.yaml
+++ b/manifests/deviceservice.yaml
@@ -34,7 +34,7 @@ spec:
         - containerPort: 2020
         env:
         - name: LOG_LEVEL
-          value: "INFO"
+          value: "DEBUG"
         readinessProbe:
           exec:
             command: ["/bin/grpc_health_probe", "-addr=:2020"]
diff --git a/manifests/monitoringservice.yaml b/manifests/monitoringservice.yaml
index e6fa36d1a68e4e0f85776b511631b0b619ec100c..3924ba2d116a522b23fbfd272fd1bb23c2f0572c 100644
--- a/manifests/monitoringservice.yaml
+++ b/manifests/monitoringservice.yaml
@@ -13,13 +13,14 @@
 # limitations under the License.
 
 apiVersion: apps/v1
-kind: Deployment
+kind: StatefulSet
 metadata:
-  name: monitoringservice
+  name: monitoringdb
 spec:
   selector:
     matchLabels:
       app: monitoringservice
+  serviceName: "monitoringservice"
   replicas: 1
   template:
     metadata:
@@ -29,47 +30,65 @@ spec:
       terminationGracePeriodSeconds: 5
       restartPolicy: Always
       containers:
-      - name: influxdb
-        image: influxdb:1.8
+      - name: metricsdb
+        image: questdb/questdb
         ports:
-        - containerPort: 8086
-        envFrom:
-          - secretRef:
-              name: influxdb-secrets
-        readinessProbe:
-          exec:
-            command: ["curl", "-XGET", "localhost:8086/health"]
-        livenessProbe:
-          exec:
-            command: ["curl", "-XGET", "localhost:8086/health"]
-        resources:
-          requests:
-            cpu: 250m
-            memory: 512Mi
-          limits:
-            cpu: 700m
-            memory: 1024Mi
+        - name: http
+          containerPort: 9000
+          protocol: TCP
+        - name: influxdb
+          containerPort: 9009
+          protocol: TCP
+        - name: postgre
+          containerPort: 8812
+          protocol: TCP
+        env:
+        - name: QDB_CAIRO_COMMIT_LAG
+          value: "1000"
+        - name: QDB_CAIRO_MAX_UNCOMMITTED_ROWS
+          value: "100000"
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: monitoringserver
+spec:
+  selector:
+    matchLabels:
+      app: monitoringservice
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: monitoringservice
+    spec:
+      terminationGracePeriodSeconds: 5
+      restartPolicy: Always
+      containers:
       - name: server
         image: registry.gitlab.com/teraflow-h2020/controller/monitoring:latest
         imagePullPolicy: Always
         ports:
-        - containerPort: 7070
-        envFrom:
-          - secretRef:
-              name: monitoring-secrets
+        - name: grpc
+          containerPort: 7070
+          protocol: TCP
+        env:
+        - name: LOG_LEVEL
+          value: "INFO"
+        - name: METRICSDB_HOSTNAME
+          value: "monitoringservice"
+        - name: METRICSDB_ILP_PORT
+          value: "9009"
+        - name: METRICSDB_REST_PORT
+          value: "9000"
+        - name: METRICSDB_TABLE
+          value: "monitoring"
         readinessProbe:
           exec:
             command: ["/bin/grpc_health_probe", "-addr=:7070"]
         livenessProbe:
           exec:
             command: ["/bin/grpc_health_probe", "-addr=:7070"]
-        resources:
-          requests:
-            cpu: 250m
-            memory: 512Mi
-          limits:
-            cpu: 700m
-            memory: 1024Mi
 ---
 apiVersion: v1
 kind: Service
@@ -84,7 +103,37 @@ spec:
     protocol: TCP
     port: 7070
     targetPort: 7070
+  - name: http
+    protocol: TCP
+    port: 9000
+    targetPort: 9000
   - name: influxdb
     protocol: TCP
-    port: 8086
-    targetPort: 8086
+    port: 9009
+    targetPort: 9009
+  - name: postgre
+    protocol: TCP
+    port: 8812
+    targetPort: 8812
+
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: access-monitoring
+spec:
+  podSelector:
+    matchLabels:
+      app: monitoringservice 
+  ingress:
+  - from: []
+    ports:
+    - port: 7070
+    - port: 8812
+  - from:
+    - podSelector:
+        matchLabels:
+          app: monitoringservice
+    ports:
+    - port: 9009
+    - port: 9000
diff --git a/manifests/pathcompservice.yaml b/manifests/pathcompservice.yaml
index b5316e22f1eefd4177ae33f4fc89da256f65bff8..d5939cb154443139be88d8e0ac23c281a3b18c4d 100644
--- a/manifests/pathcompservice.yaml
+++ b/manifests/pathcompservice.yaml
@@ -27,8 +27,8 @@ spec:
     spec:
       terminationGracePeriodSeconds: 5
       containers:
-      - name: server
-        image: registry.gitlab.com/teraflow-h2020/controller/pathcomp:latest
+      - name: frontend
+        image: registry.gitlab.com/teraflow-h2020/controller/pathcomp-frontend:latest
         imagePullPolicy: Always
         ports:
         - containerPort: 10020
@@ -48,6 +48,28 @@ spec:
           limits:
             cpu: 700m
             memory: 1024Mi
+      - name: backend
+        image: registry.gitlab.com/teraflow-h2020/controller/pathcomp-backend:latest
+        imagePullPolicy: Always
+        #readinessProbe:
+        #  httpGet:
+        #    path: /health
+        #    port: 8081
+        #  initialDelaySeconds: 5
+        #  timeoutSeconds: 5
+        #livenessProbe:
+        #  httpGet:
+        #    path: /health
+        #    port: 8081
+        #  initialDelaySeconds: 5
+        #  timeoutSeconds: 5
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
 ---
 apiVersion: v1
 kind: Service
@@ -62,3 +84,7 @@ spec:
     protocol: TCP
     port: 10020
     targetPort: 10020
+  - name: http
+    protocol: TCP
+    port: 8081
+    targetPort: 8081
diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml
index 75832b94fa2a6ba97617641e7b249157508614bf..efe43fe229a7f7ba862b10a04d44c6e9de06b5fb 100644
--- a/manifests/serviceservice.yaml
+++ b/manifests/serviceservice.yaml
@@ -34,7 +34,7 @@ spec:
         - containerPort: 3030
         env:
         - name: LOG_LEVEL
-          value: "INFO"
+          value: "DEBUG"
         readinessProbe:
           exec:
             command: ["/bin/grpc_health_probe", "-addr=:3030"]
diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml
index 52fc75a9868001d50f7380cfe238fa344de27f6e..cac64a816075f1a0ad91a21c519463aa5cd8f973 100644
--- a/manifests/webuiservice.yaml
+++ b/manifests/webuiservice.yaml
@@ -35,12 +35,12 @@ spec:
         image: registry.gitlab.com/teraflow-h2020/controller/webui:latest
         imagePullPolicy: Always
         ports:
-        - containerPort: 8004 # TODO: define the real port
+        - containerPort: 8004
         env:
         - name: LOG_LEVEL
           value: "DEBUG"
         - name: WEBUISERVICE_SERVICE_BASEURL_HTTP
-          value: "/webui"
+          value: "/webui/"
         readinessProbe:
           httpGet:
             path: /healthz/ready
@@ -61,7 +61,7 @@ spec:
             cpu: 700m
             memory: 1024Mi
       - name: grafana
-        image: grafana/grafana:8.2.6
+        image: grafana/grafana:8.5.11
         imagePullPolicy: IfNotPresent
         ports:
           - containerPort: 3000
diff --git a/my_deploy.sh b/my_deploy.sh
index 67a2e0558c25d767e14b635e6dd9174433827156..23917c253ba82d2380441730af17c803ce32aea2 100644
--- a/my_deploy.sh
+++ b/my_deploy.sh
@@ -1,22 +1,15 @@
-# Set the URL of your local Docker registry where the images will be uploaded to.
 export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
 
-# Set the list of components, separated by comas, you want to build images for, and deploy.
+# Set the list of components, separated by spaces, you want to build images for, and deploy.
 # Supported components are:
 #   context device automation policy service compute monitoring webui
 #   interdomain slice pathcomp dlt
-#   dbscanserving opticalattackmitigator opticalcentralizedattackdetector
+#   dbscanserving opticalattackmitigator opticalattackdetector
 #   l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector
-export TFS_COMPONENTS="context device automation service compute monitoring webui"
+export TFS_COMPONENTS="context device automation pathcomp service slice compute monitoring webui"
 
 # Set the tag you want to use for your images.
 export TFS_IMAGE_TAG="dev"
-
-# Set the name of the Kubernetes namespace to deploy to.
 export TFS_K8S_NAMESPACE="tfs"
-
-# Set additional manifest files to be applied after the deployment
 export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
-
-# Set the neew Grafana admin password
 export TFS_GRAFANA_PASSWORD="admin123+"
diff --git a/open_webui.sh b/open_webui.sh
deleted file mode 100755
index e4dfdb709ef5008091f3f73357087272dfd7c34e..0000000000000000000000000000000000000000
--- a/open_webui.sh
+++ /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.
-
-# this script opens the webui
-
-K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'}
-
-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}
-
-# 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/proto/automation.proto b/proto/automation.proto
index f41bef9e28588fbd2a0acf416d347eb530c48df0..9297236766a28878a5f0c0de6a4aeae0487d330a 100644
--- a/proto/automation.proto
+++ b/proto/automation.proto
@@ -21,7 +21,7 @@ service AutomationService {
   rpc ZtpGetDeviceRole(DeviceRoleId) returns (DeviceRole) {}
   rpc ZtpGetDeviceRolesByDeviceId(context.DeviceId) returns (DeviceRoleList) {}
   rpc ZtpAdd(DeviceRole) returns (DeviceRoleState) {}
-  rpc ZtpUpdate(DeviceRole) returns (DeviceRoleState) {}
+  rpc ZtpUpdate(DeviceRoleConfig) returns (DeviceRoleState) {}
   rpc ZtpDelete(DeviceRole) returns (DeviceRoleState) {}
   rpc ZtpDeleteAll(context.Empty) returns (DeviceDeletionResult) {}
 }
@@ -43,6 +43,11 @@ message DeviceRole {
   DeviceRoleType devRoleType = 2;
 }
 
+message DeviceRoleConfig {
+  DeviceRole devRole = 1;
+  context.DeviceConfig devConfig = 2;
+}
+
 message DeviceRoleList {
   repeated DeviceRole devRole = 1;
 }
diff --git a/proto/context.proto b/proto/context.proto
index e17b2acfa99a1abb9e8f4ec4c619a007d9bca5c3..5b49bd28866af919332ab7188bbf66203e8b766d 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -51,6 +51,7 @@ service ContextService {
   rpc ListServices       (ContextId   ) returns (       ServiceList     ) {}
   rpc GetService         (ServiceId   ) returns (       Service         ) {}
   rpc SetService         (Service     ) returns (       ServiceId       ) {}
+  rpc UnsetService       (Service     ) returns (       ServiceId       ) {}
   rpc RemoveService      (ServiceId   ) returns (       Empty           ) {}
   rpc GetServiceEvents   (Empty       ) returns (stream ServiceEvent    ) {}
 
@@ -58,6 +59,7 @@ service ContextService {
   rpc ListSlices         (ContextId   ) returns (       SliceList       ) {}
   rpc GetSlice           (SliceId     ) returns (       Slice           ) {}
   rpc SetSlice           (Slice       ) returns (       SliceId         ) {}
+  rpc UnsetSlice         (Slice       ) returns (       SliceId         ) {}
   rpc RemoveSlice        (SliceId     ) returns (       Empty           ) {}
   rpc GetSliceEvents     (Empty       ) returns (stream SliceEvent      ) {}
 
@@ -189,6 +191,7 @@ message DeviceList {
 message DeviceEvent {
   Event event = 1;
   DeviceId device_id = 2;
+  DeviceConfig device_config = 3;
 }
 
 
diff --git a/proto/monitoring.proto b/proto/monitoring.proto
index 2c7b98d2ca3392906e0f42896907bb887b45e80b..8b83afa47b49c130d37dcbcc1024f079ebc2a2fe 100644
--- a/proto/monitoring.proto
+++ b/proto/monitoring.proto
@@ -19,56 +19,35 @@ import "context.proto";
 import "kpi_sample_types.proto";
 
 service MonitoringService {
-  rpc CreateKpi                (KpiDescriptor        )     returns (KpiId            ) {}
-  rpc EditKpiDescriptor        (EditedKpiDescriptor  )     returns (context.Empty    ) {}
-  rpc DeleteKpi                (KpiId                )     returns (context.Empty    ) {}
-  rpc GetKpiDescriptorList     (context.Empty        )     returns (KpiDescriptorList) {}
-  rpc CreateBundleKpi          (BundleKpiDescriptor  )     returns (KpiId            ) {}
-  rpc GetKpiDescriptor         (KpiId                )     returns (KpiDescriptor    ) {}
-  rpc IncludeKpi               (Kpi                  )     returns (context.Empty    ) {}
-  rpc MonitorKpi               (MonitorKpiRequest    )     returns (context.Empty    ) {}
-  rpc QueryKpiData             (KpiQuery             )     returns (KpiList          ) {}
-  rpc SubscribeKpi             (SubsDescriptor       )     returns (stream KpiList   ) {}
-  rpc GetSubsDescriptor        (SubscriptionID       )     returns (SubsDescriptor   ) {}
-  rpc GetSubscriptions         (context.Empty        )     returns (SubsIDList       ) {}
-  rpc EditKpiSubscription      (SubsDescriptor       )     returns (context.Empty    ) {}
-  rpc CreateKpiAlarm           (AlarmDescriptor      )     returns ( AlarmID ) {}
-  rpc EditKpiAlarm             (AlarmDescriptor      )     returns (context.Empty    ) {}
-  rpc GetAlarms                (context.Empty        )     returns (AlarmIDList      ) {}
-  rpc GetAlarmDescriptor       (AlarmID              )     returns (AlarmDescriptor  ) {}
-  rpc GetAlarmResponseStream   (AlarmID              )     returns (stream AlarmResponse ) {}
-  //  rpc GetStreamKpi            (KpiId                )     returns (stream Kpi       ) {}
-  //  rpc GetInstantKpi           (KpiId                )     returns (KpiList          ) {}
+  rpc SetKpi                (KpiDescriptor      ) returns (KpiId               ) {}
+  rpc DeleteKpi             (KpiId              ) returns (context.Empty       ) {}
+  rpc GetKpiDescriptor      (KpiId              ) returns (KpiDescriptor       ) {}
+  rpc GetKpiDescriptorList  (context.Empty      ) returns (KpiDescriptorList   ) {}
+  rpc IncludeKpi            (Kpi                ) returns (context.Empty       ) {}
+  rpc MonitorKpi            (MonitorKpiRequest  ) returns (context.Empty       ) {}
+  rpc QueryKpiData          (KpiQuery           ) returns (KpiList             ) {}
+  rpc SetKpiSubscription    (SubsDescriptor     ) returns (stream KpiList      ) {}
+  rpc GetSubsDescriptor     (SubscriptionID     ) returns (SubsDescriptor      ) {}
+  rpc GetSubscriptions      (context.Empty      ) returns (SubsIDList          ) {}
+  rpc DeleteSubscription    (SubscriptionID     ) returns (context.Empty       ) {}
+  rpc SetKpiAlarm           (AlarmDescriptor    ) returns (AlarmID             ) {}
+  rpc GetAlarms             (context.Empty      ) returns (AlarmIDList         ) {}
+  rpc GetAlarmDescriptor    (AlarmID            ) returns (AlarmDescriptor     ) {}
+  rpc GetAlarmResponseStream(AlarmSubscription  ) returns (stream AlarmResponse) {}
+  rpc DeleteAlarm           (AlarmID            ) returns (context.Empty       ) {}
+  rpc GetStreamKpi          (KpiId              ) returns (stream Kpi          ) {}
+  rpc GetInstantKpi         (KpiId              ) returns (KpiList             ) {}
 }
 
 message KpiDescriptor {
-  string kpi_description                          = 1;
-  kpi_sample_types.KpiSampleType kpi_sample_type  = 2;
-  context.DeviceId device_id                      = 3;
-  context.EndPointId endpoint_id                  = 4;
-  context.ServiceId  service_id                   = 5;
-  context.SliceId    slice_id                     = 6;
-}
-
-message BundleKpiDescriptor {
-  string kpi_description                          = 1;
-  repeated KpiId kpi_id_list                      = 2;
-  kpi_sample_types.KpiSampleType kpi_sample_type  = 3;
-  context.DeviceId device_id                      = 4;
-  context.EndPointId endpoint_id                  = 5;
-  context.ServiceId  service_id                   = 6;
-  context.SliceId    slice_id                     = 7;
-}
-
-message EditedKpiDescriptor {
-  KpiId kpi_id                                    = 1;
-  string kpi_description                          = 2;
-  repeated KpiId kpi_id_list                      = 3;
-  kpi_sample_types.KpiSampleType kpi_sample_type  = 4;
-  context.DeviceId device_id                      = 5;
-  context.EndPointId endpoint_id                  = 6;
-  context.ServiceId  service_id                   = 7;
-  context.SliceId    slice_id                     = 8;
+  KpiId                          kpi_id          = 1;
+  string                         kpi_description = 2;
+  repeated KpiId                 kpi_id_list     = 3;
+  kpi_sample_types.KpiSampleType kpi_sample_type = 4;
+  context.DeviceId               device_id       = 5;
+  context.EndPointId             endpoint_id     = 6;
+  context.ServiceId              service_id      = 7;
+  context.SliceId                slice_id        = 8;
 }
 
 message MonitorKpiRequest {
@@ -79,12 +58,12 @@ message MonitorKpiRequest {
 }
 
 message KpiQuery {
-  repeated KpiId kpi_id     = 1;
-  float monitoring_window_s = 2;
-  float sampling_rate_s     = 3;
-  uint32 last_n_samples     = 4;  // used when you want something like "get the last N many samples
-  string start_date         = 5;  // used when you want something like "get the samples since X date/time"
-  string end_date           = 6;  // used when you want something like "get the samples until X date/time"
+  repeated KpiId    kpi_id              = 1;
+  float             monitoring_window_s = 2;
+  float             sampling_rate_s     = 3;
+  uint32            last_n_samples      = 4;  // used when you want something like "get the last N many samples
+  context.Timestamp start_timestamp     = 5;  // used when you want something like "get the samples since X date/time"
+  context.Timestamp end_timestamp       = 6;  // used when you want something like "get the samples until X date/time"
   // Pending add field to reflect Available Device Protocols
 }
 
@@ -93,39 +72,47 @@ message KpiId {
 }
 
 message Kpi {
-  KpiId kpi_id        = 1;
-  string timestamp    = 2;
-  KpiValue kpi_value  = 3;
+  KpiId             kpi_id    = 1;
+  context.Timestamp timestamp = 2;
+  KpiValue          kpi_value = 3;
 }
 
 message KpiValueRange {
-  KpiValue kpiMinValue = 1;
-  KpiValue kpiMaxValue = 2;
+  KpiValue  kpiMinValue     = 1;
+  KpiValue  kpiMaxValue     = 2;
+  bool      inRange         = 3;  // by default True
+  bool      includeMinValue = 4;  // False is outside the interval
+  bool      includeMaxValue = 5;  // False is outside the interval
 }
 
 message KpiValue {
   oneof value {
-    uint32 intVal     = 1;
-    float floatVal    = 2;
-    string stringVal  = 3;
-    bool boolVal      = 4;
+    int32  int32Val  = 1;
+    uint32 uint32Val = 2;
+    int64  int64Val  = 3;
+    uint64 uint64Val = 4;
+    float  floatVal  = 5;
+    string stringVal = 6;
+    bool   boolVal   = 7;
   }
 }
 
+
 message KpiList {
-    repeated Kpi kpi_list = 1;
+  repeated Kpi kpi_list = 1;
 }
 
 message KpiDescriptorList {
-    repeated KpiDescriptor kpi_descriptor_list = 1;
+  repeated KpiDescriptor kpi_descriptor_list = 1;
 }
 
 message SubsDescriptor{
-  KpiId kpi_id              = 1;
-  float sampling_duration_s = 2;
-  float sampling_interval_s = 3;
-  string start_date         = 4;  // used when you want something like "get the samples since X date/time"
-  string end_date           = 5;  // used when you want something like "get the samples until X date/time"
+  SubscriptionID    subs_id             = 1;
+  KpiId             kpi_id              = 2;
+  float             sampling_duration_s = 3;
+  float             sampling_interval_s = 4;
+  context.Timestamp start_timestamp     = 5;  // used when you want something like "get the samples since X date/time"
+  context.Timestamp end_timestamp       = 6;  // used when you want something like "get the samples until X date/time"
   // Pending add field to reflect Available Device Protocols
 }
 
@@ -134,30 +121,38 @@ message SubscriptionID {
 }
 
 message SubsResponse {
-  SubscriptionID subs_id    = 1;
+  SubscriptionID   subs_id  = 1;
   repeated KpiList kpi_list = 2;
 }
 
 message SubsIDList {
-    repeated SubscriptionID subs_list = 1;
+  repeated SubscriptionID subs_list = 1;
 }
 
 message AlarmDescriptor {
-  string alarm_description      = 1;
-  string name                   = 2;
-  KpiId kpi_id                  = 3;
-  KpiValueRange kpi_value_range = 4;
-  string timestamp              = 5;
+  AlarmID                     alarm_id              = 1;
+  string                      alarm_description     = 2;
+  string                      name                  = 3;
+  repeated KpiId              kpi_id                = 4;
+  repeated KpiValueRange      kpi_value_range       = 5;
+  context.Timestamp           timestamp             = 6;
 }
 
 message AlarmID{
   context.Uuid alarm_id = 1;
 }
 
+message AlarmSubscription{
+  AlarmID alarmID                   = 1;
+  float   subscription_timeout_s    = 2;
+  float   subscription_frequency_ms = 3;
+}
+
 message AlarmResponse {
-  AlarmID alarm_id    = 1;
-  string text         = 2;
-  KpiValue kpi_value  = 3;
+  AlarmID           alarm_id  = 1;
+  string            text      = 2;
+  KpiValue          kpi_value = 3;
+  context.Timestamp timestamp = 4;
 }
 
 message AlarmIDList {
diff --git a/proto/pathcomp.proto b/proto/pathcomp.proto
index 9eb650fb9981b4b84f31b63796eec0c7a8e780b6..08f33efe99b6a25c568c8be14f1355b3d4521909 100644
--- a/proto/pathcomp.proto
+++ b/proto/pathcomp.proto
@@ -28,11 +28,16 @@ message Algorithm_KShortestPath {
   uint32 k_return     = 2;
 }
 
+message Algorithm_KDisjointPath {
+  uint32 num_disjoint = 1;
+}
+
 message PathCompRequest {
   repeated context.Service services = 1;
   oneof algorithm {
     Algorithm_ShortestPath  shortest_path   = 10;
     Algorithm_KShortestPath k_shortest_path = 11;
+    Algorithm_KDisjointPath k_disjoint_path = 12;
   }
 }
 
diff --git a/proto/te.proto b/proto/te.proto
index f85f94f48322d85e2c6bd7e667f7dfc9cb2febda..d639cb7f45f682d3e95d77e8b6d10d404ee51b9f 100644
--- a/proto/te.proto
+++ b/proto/te.proto
@@ -18,7 +18,7 @@ package te;
 import "context.proto";
 
 service TEService {
-  rpc RequestLSP (context.Service) returns (context.ServiceStatus) {}
+  rpc RequestLSP(context.Service  ) returns (context.ServiceStatus) {}
   rpc UpdateLSP (context.ServiceId) returns (context.ServiceStatus) {}
-  rpc DeleteLSP (context.ServiceId) returns (context.Empty) {}
+  rpc DeleteLSP (context.ServiceId) returns (context.Empty        ) {}
 }
diff --git a/report_coverage_slice.sh b/report_coverage_slice.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f783ec069329a9efe100154a2702a72a93e0ad8a
--- /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/run_tests_docker.sh b/run_tests_docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fd885140999ac0f045c162f361f0075af96a8d48
--- /dev/null
+++ b/run_tests_docker.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# Set the URL of your local Docker registry where the images will be uploaded to. Leave it blank if you do not want to
+# use any Docker registry.
+REGISTRY_IMAGE=""
+#REGISTRY_IMAGE="http://my-container-registry.local/"
+
+# Set the list of components you want to build images for, and deploy.
+COMPONENTS="context device automation policy service compute monitoring centralizedattackdetector"
+
+# Set the tag you want to use for your images.
+IMAGE_TAG="tf-dev"
+
+# Constants
+TMP_FOLDER="./tmp"
+
+TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
+mkdir -p $TMP_LOGS_FOLDER
+
+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
+done
+
+echo "Preparing for running the tests..."
+
+if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create -d bridge teraflowbridge; fi  
+
+for COMPONENT in $COMPONENTS; do
+    IMAGE_NAME="$COMPONENT:$IMAGE_TAG"
+    echo "  Running tests for $COMPONENT:"
+    docker run -it -d --name $COMPONENT $IMAGE_NAME --network=teraflowbridge
+    docker exec -it $COMPONENT bash -c "pytest --log-level=DEBUG --verbose $COMPONENT/tests/test_unitary.py"
+    docker stop $COMPONENT
+done
diff --git a/scripts/build_run_report_tests_locally.sh b/scripts/build_run_report_tests_locally.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9bdc81d9894df35a6bcc325d78e7f1f5214e8a96
--- /dev/null
+++ b/scripts/build_run_report_tests_locally.sh
@@ -0,0 +1,57 @@
+#!/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.
+
+die () {
+    echo >&2 "$@"
+    exit 1
+}
+
+[ "$#" -eq 1 ] || die "component name required but not provided"
+
+COMPONENT_NAME=$1 # parameter
+IMAGE_NAME="${COMPONENT_NAME}-local"
+IMAGE_TAG="latest"
+
+if docker ps | grep $IMAGE_NAME
+then
+    docker stop $IMAGE_NAME
+fi
+
+if docker network list | grep teraflowbridge
+then
+    echo "teraflowbridge is already created"
+else
+    docker network create -d bridge teraflowbridge
+fi
+
+docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$COMPONENT_NAME/Dockerfile .
+
+docker run --name $IMAGE_NAME -d -v "${PWD}/src/${COMPONENT_NAME}/tests:/home/${COMPONENT_NAME}/results" --network=teraflowbridge --rm $IMAGE_NAME:$IMAGE_TAG
+
+docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $COMPONENT_NAME/tests/ --junitxml=/home/${COMPONENT_NAME}/results/${COMPONENT_NAME}_report.xml"
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+echo
+echo "Coverage report:"
+echo "----------------"
+docker exec -i $IMAGE_NAME bash -c "coverage report --include='${COMPONENT_NAME}/*' --show-missing"
+
+# docker stop $IMAGE_NAME
+docker rm -f $IMAGE_NAME
+docker network rm teraflowbridge
diff --git a/scripts/dump_logs.sh b/scripts/dump_logs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a6db945d245b832564353de71610bf720eb0acb8
--- /dev/null
+++ b/scripts/dump_logs.sh
@@ -0,0 +1,37 @@
+#!/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.
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# If not already set, set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+mkdir -p tmp/exec_logs/$TFS_K8S_NAMESPACE/
+rm tmp/exec_logs/$TFS_K8S_NAMESPACE/*
+
+PODS=$(kubectl get pods --namespace $TFS_K8S_NAMESPACE --no-headers --output=custom-columns=":metadata.name")
+for POD in $PODS; do
+    CONTAINERS=$(kubectl get pods --namespace $TFS_K8S_NAMESPACE $POD -o jsonpath='{.spec.containers[*].name}')
+    for CONTAINER in $CONTAINERS; do
+        kubectl --namespace $TFS_K8S_NAMESPACE logs pod/${POD} --container ${CONTAINER} \
+            > tmp/exec_logs/$TFS_K8S_NAMESPACE/$POD\_\_$CONTAINER.log
+    done
+done
diff --git a/scripts/old/deploy_in_kubernetes.sh b/scripts/old/deploy_in_kubernetes.sh
index 5e16120bb3b47e993e1d331ccdef3186380304ec..89f45a5484f95f065f6656249f3fb04bf507a782 100755
--- a/scripts/old/deploy_in_kubernetes.sh
+++ b/scripts/old/deploy_in_kubernetes.sh
@@ -81,7 +81,7 @@ for COMPONENT in $COMPONENTS; do
     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"
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG"
     fi
 
     if [ -n "$REGISTRY_IMAGE" ]; then
diff --git a/open_dashboard.sh b/scripts/old/open_dashboard.sh
similarity index 73%
rename from open_dashboard.sh
rename to scripts/old/open_dashboard.sh
index 8291a22c75cd2c2b83bedcab2ac0167c56c966a6..d0529a00921be896ae976c86d10d67139719de9c 100755
--- a/open_dashboard.sh
+++ b/scripts/old/open_dashboard.sh
@@ -16,10 +16,10 @@
 
 # this script opens the dashboard
 
-K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'}
+K8S_NAMESPACE=${K8S_NAMESPACE:-'tfs'}
 
-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}')
+GRAFANA_IP=$(kubectl get service/webuiservice -n ${TFS_K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}')
+GRAFANA_PORT=3000 #$(kubectl get service webuiservice --namespace $TFS_K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==3000)].nodePort}')
 URL=http://${GRAFANA_IP}:${GRAFANA_PORT}
 
 echo Opening Dashboard on URL ${URL}
diff --git a/scripts/old/open_webui.sh b/scripts/old/open_webui.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d539c1970adb7882c9621fc909acf21c2dde743a
--- /dev/null
+++ b/scripts/old/open_webui.sh
@@ -0,0 +1,88 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# this script opens the webui
+
+K8S_NAMESPACE=${K8S_NAMESPACE:-'tfs'}
+
+WEBUI_SERVICE_NAME="webuiservice"
+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
+
+echo "Configuring WebUI DataStores and Dashboards..."
+sleep 3
+INFLUXDB_HOST="monitoringservice"
+INFLUXDB_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service/monitoringservice -o jsonpath='{.spec.ports[?(@.name=="influxdb")].port}')
+INFLUXDB_URL="http://${INFLUXDB_HOST}:${INFLUXDB_PORT}"
+INFLUXDB_USER=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode)
+INFLUXDB_PASSWORD=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode)
+INFLUXDB_DATABASE=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode)
+# Exposed through the ingress controller "tfs-ingress"
+# GRAFANA_HOSTNAME="127.0.0.1"
+# GRAFANA_PORT="80"
+# GRAFANA_BASEURL="/grafana"
+# Default Grafana credentials
+GRAFANA_USERNAME="admin"
+GRAFANA_PASSWORD="admin"
+# Default Grafana API URL
+GRAFANA_URL_DEFAULT=http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${WEBUI_IP}:${GRAFANA_PORT} #"http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}"
+# Updated Grafana API URL
+GRAFANA_URL_UPDATED=http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${WEBUI_IP}:${GRAFANA_PORT} #"http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}"
+echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..."
+# Configure Grafana Admin Password
+# Ref: https://grafana.com/docs/grafana/latest/http_api/user/#change-password
+curl -X PUT -H "Content-Type: application/json" -d '{
+    "oldPassword": "'${GRAFANA_PASSWORD}'",
+    "newPassword": "'${TFS_GRAFANA_PASSWORD}'",
+    "confirmNew" : "'${TFS_GRAFANA_PASSWORD}'"
+}' ${GRAFANA_URL_DEFAULT}/api/user/password
+echo
+# Create InfluxDB DataSource
+# Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/
+curl -X POST -H "Content-Type: application/json" -d '{
+    "type"     : "influxdb",
+    "name"     : "InfluxDB",
+    "url"      : "'"$INFLUXDB_URL"'",
+    "access"   : "proxy",
+    "basicAuth": false,
+    "user"     : "'"$INFLUXDB_USER"'",
+    "password" : "'"$INFLUXDB_PASSWORD"'",
+    "isDefault": true,
+    "database" : "'"$INFLUXDB_DATABASE"'"
+}' ${GRAFANA_URL_UPDATED}/api/datasources
+echo
+# Create Monitoring Dashboard
+# Ref: https://grafana.com/docs/grafana/latest/http_api/dashboard/
+curl -X POST -H "Content-Type: application/json" \
+-d '@src/webui/grafana_dashboard.json' \
+${GRAFANA_URL_UPDATED}/api/dashboards/db
+echo
+DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tf-l3-monit"
+DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id')
+curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID}
+
+# Open WebUI
+UI_URL="http://${WEBUI_IP}:${WEBUI_PORT}"
+echo "Opening web UI on URL ${UI_URL}"
+# curl -kL ${UI_URL}
+python3 -m webbrowser ${UI_URL}
+
+# Open Dashboard
+DASHB_URL="http://${WEBUI_IP}:${GRAFANA_PORT}"
+echo "Opening Dashboard on URL ${DASHB_URL}"
+# curl -kL ${DASHB_URL}
+python3 -m webbrowser ${DASHB_URL}
diff --git a/scripts/run_tests_locally-pathcomp.sh b/scripts/run_tests_locally-pathcomp-frontend.sh
similarity index 95%
rename from scripts/run_tests_locally-pathcomp.sh
rename to scripts/run_tests_locally-pathcomp-frontend.sh
index f56f47a8b592939243a2ec5d9fd95d89046582d1..1bcf5e7f3792622622f9e59978fddbf11c54e492 100755
--- a/scripts/run_tests_locally-pathcomp.sh
+++ b/scripts/run_tests_locally-pathcomp-frontend.sh
@@ -25,4 +25,4 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc
 #-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 \
-    pathcomp/tests/test_unitary.py
+    pathcomp/frontend/tests/test_unitary.py
diff --git a/scripts/run_tests_locally-service.sh b/scripts/run_tests_locally-service.sh
index 8a2a8d0be1d1960c6197a67e471ae29abba501a7..8816b9faa24e55e486a54852632fdb8e00db1d04 100755
--- a/scripts/run_tests_locally-service.sh
+++ b/scripts/run_tests_locally-service.sh
@@ -21,4 +21,5 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc
 
 # Run unitary tests and analyze coverage of code at same time
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    service/tests/test_unitary_task_scheduler.py \
     service/tests/test_unitary.py
diff --git a/scripts/show_logs_automation.sh b/scripts/show_logs_automation.sh
index 8823f29c09960ce980f48d76463682d34e2ea09f..0c0615d9915db6e5b9958ec1205c7a99f096f019 100755
--- a/scripts/show_logs_automation.sh
+++ b/scripts/show_logs_automation.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/scripts/show_logs_compute.sh b/scripts/show_logs_compute.sh
index 5e061bb9eb49047b96027a39d3bc846a3e502b5c..759918f11a366450b5c7058a9a2c46bbb701f2cd 100755
--- a/scripts/show_logs_compute.sh
+++ b/scripts/show_logs_compute.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/scripts/show_logs_context.sh b/scripts/show_logs_context.sh
index ece545a7e32131880079c2ce65a950c64a16273e..f4b6c620b89d566c8af6950d7240a8286152417d 100755
--- a/scripts/show_logs_context.sh
+++ b/scripts/show_logs_context.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/scripts/show_logs_device.sh b/scripts/show_logs_device.sh
index e1c2e4aa8a5fd39e525fcf61ffcf5572e3e6c8d0..d3ef781c92274ecf6b9f2b9ef8eb44b2fde497d6 100755
--- a/scripts/show_logs_device.sh
+++ b/scripts/show_logs_device.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/scripts/show_logs_monitoring.sh b/scripts/show_logs_monitoring.sh
index 5978035127735c20ddc6387666a5434cbac61ff8..520a9da1c652553eb90acd083caf5724275f4efe 100755
--- a/scripts/show_logs_monitoring.sh
+++ b/scripts/show_logs_monitoring.sh
@@ -18,10 +18,10 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
 ########################################################################################################################
 
-kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/monitoringservice -c server
+kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/monitoringserver
diff --git a/scripts/show_logs_pathcomp_backend.sh b/scripts/show_logs_pathcomp_backend.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cee99ee4bd19de9b7cd4e45eb651e809397ccaeb
--- /dev/null
+++ b/scripts/show_logs_pathcomp_backend.sh
@@ -0,0 +1,27 @@
+#!/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.
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# If not already set, set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/pathcompservice -c backend
diff --git a/scripts/show_logs_pathcomp_frontend.sh b/scripts/show_logs_pathcomp_frontend.sh
new file mode 100755
index 0000000000000000000000000000000000000000..32f92b59d53b5804e9f1a0b145576667cfa21131
--- /dev/null
+++ b/scripts/show_logs_pathcomp_frontend.sh
@@ -0,0 +1,27 @@
+#!/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.
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# If not already set, set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/pathcompservice -c frontend
diff --git a/scripts/show_logs_service.sh b/scripts/show_logs_service.sh
index 251add7e1641862f3c95dbf038920bc86b3c89ff..6089d0ac6f3008bd5f35e2f813fd1cab2c4d4060 100755
--- a/scripts/show_logs_service.sh
+++ b/scripts/show_logs_service.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/scripts/show_logs_slice.sh b/scripts/show_logs_slice.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c7bc0b69588307092b22ea3c600669359f04de99
--- /dev/null
+++ b/scripts/show_logs_slice.sh
@@ -0,0 +1,27 @@
+#!/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.
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# If not already set, set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/sliceservice
diff --git a/scripts/show_logs_webui.sh b/scripts/show_logs_webui.sh
index c73f5f51a6aefe0caee2620cccca272f1abb8622..38cffd624b35ce8196c7bbde2838a0971a7d7024 100755
--- a/scripts/show_logs_webui.sh
+++ b/scripts/show_logs_webui.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/show_deploy.sh b/show_deploy.sh
index e894d44f3d7f79ac18ce4f3d5b2708a6402764e6..68a5659aab529be5644015d6e6fbdf9885f7a1ec 100755
--- a/show_deploy.sh
+++ b/show_deploy.sh
@@ -18,7 +18,7 @@
 ########################################################################################################################
 
 # If not already set, set the name of the Kubernetes namespace to deploy to.
-export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs-dev"}
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
 
 ########################################################################################################################
 # Automated steps start here
diff --git a/src/automation/README.md b/src/automation/README.md
index 099980bcc4172bf9e5c2d59459f40ae4331696cf..e98d2b8ab62563f43cf2c1011e91fb2a1d08d378 100644
--- a/src/automation/README.md
+++ b/src/automation/README.md
@@ -1,28 +1,57 @@
-# Automation TeraFlow OS service 
+# TeraFlowSDN Automation service
 
-The Automation service, also known as Zero-Touch Provisioning (ZTP), is tested on Ubuntu 20.04. Follow the instructions below to build, test, and run this service on your local environment.
+This repository hosts the TeraFlowSDN Automation service, also known as Zero-Touch Provisioning (ZTP) service.
+Follow the instructions below to build, test, and run this service on your local environment.
 
-## Automation Teraflow OS service architecture
+## TeraFlowSDN Automation service architecture
 
-| The Automation Teraflow OS service architecture consists of six (6) interfaces listed below:                                                                                                                                                 | 
+The TeraFlowSDN Automation architecture consists of six (6) interfaces listed below:
+
+Interfaces |
 |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1. The `AutomationGateway` interface that implements all the rpc functions that are described in `automation.proto` file.                                                                                                                    | 
-| 2. The `ContextGateway` interface that communicates with a `Context` Service gRPC client and implements all the rpc functions that are described in `context.proto` file.                                                                    |
-| 3. The `DeviceGateway` interface that communicates with a `Device` Service gRPC client and implements all the rpc functions that are described in `device.proto` file.                                                                       |
-| 4. The `AutomationService` interface that implements the `addDevice()` method by communicating with a `Context` gRPC client & a `Device` gRPC client through the use of `ContextService` interface & `DeviceService` interface respectively. |
-| 5. The `ContextService` interface that implements the `getDevice()` & `getDeviceEvents()` methods by communicating with a `Context` gRPC client through the use of `ContextGateway` interface.                                               |
-| 6. The `DeviceService` interface that implements the `getInitialConfiguration()` & `configureDevice()` methods by communicating with a `Device` gRPC client through the use of `DeviceGateway` interface.                                    |
+| 1. The `AutomationGateway` interface that implements all the RPC functions that are described in `automation.proto` file. |
+| 2. The `ContextGateway` interface that communicates with a `Context` Service gRPC client to invoke key RPC functions described in `context.proto` file. |
+| 3. The `DeviceGateway` interface that communicates with a `Device` Service gRPC client to invoke key RPC functions described in `device.proto` file. |
+| 4. The `AutomationService` interface that implements the `addDevice()`, `updateDevice()`, and `deleteDevice()` methods by communicating with a `Context` gRPC client and a `Device` gRPC client through the use of `ContextService` interface and `DeviceService` interface respectively. |
+| 5. The `ContextService` interface that implements the `getDevice()` and `getDeviceEvents()` methods by communicating with a `Context` gRPC client through the use of `ContextGateway` interface. |
+| 6. The `DeviceService` interface that implements the `getInitialConfiguration()`, `configureDevice()`, and `deleteDevice()` methods by communicating with a `Device` gRPC client through the use of `DeviceGateway` interface. |
+
+
+## Prerequisites
 
+The Automation service is currently tested against Ubuntu 20.04 and Java 11.
 
-## Run with dev profile
+To quickly install Java 11 on a Debian-based Linux distro do:
 
 ```bash
-./mvnw clean quarkus:dev
+sudo apt-get install openjdk-11-jdk -y
 ```
 
-## Running tests
+Feel free to try more recent Java versions.
+
+## Compile
+
+```bash
+./mvnw compile
+```
+
+## Run tests
+
+```bash
+./mvnw test
+```
 
-Run unit and functional tests `./mvnw clean test`
+## Run service
+
+```bash
+./mvnw quarkus:dev
+````
+
+## Clean
+
+```bash
+./mvnw clean
+```
 
 ## Deploying on a Kubernetes cluster
 
@@ -30,10 +59,16 @@ To create the K8s manifest file under `target/kubernetes/kubernetes.yml` to be u
 
 ```bash
 ./mvnw clean package -DskipUTs -DskipITs
-``` 
+```
 
 To deploy the application in a K8s cluster run
 
 ```bash
 kubectl apply -f "manifests/automationservice.yaml"
 ```
+
+## Maintainers
+
+This TeraFlowSDN service is implemented by [UBITECH](https://www.ubitech.eu).
+
+Feel free to contact Georgios Katsikas (gkatsikas at ubitech dot eu) in case you have questions.
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 c160387c3e3448f29d01a185afc31127b025c2b6..6d672fdea2c3e97f9f2a50c7efa8d77c05532357 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
@@ -17,9 +17,12 @@
 package eu.teraflow.automation;
 
 import automation.Automation;
+import automation.Automation.DeviceRoleConfig;
+import automation.Automation.DeviceRoleState;
 import context.ContextOuterClass;
 import eu.teraflow.automation.context.model.Device;
 import eu.teraflow.automation.model.DeviceRoleId;
+import eu.teraflow.automation.model.DeviceState;
 import io.quarkus.grpc.GrpcService;
 import io.smallrye.mutiny.Uni;
 import javax.inject.Inject;
@@ -56,17 +59,19 @@ public class AutomationGatewayImpl implements AutomationGateway {
         return automationService
                 .addDevice(deviceId)
                 .onItem()
-                .transform(device -> transformToDeviceRoleState(device, devRoleId));
+                .transform(device -> transformToDeviceRoleState(device, devRoleId, DeviceState.CREATED));
     }
 
     @Override
-    public Uni<Automation.DeviceRoleState> ztpUpdate(Automation.DeviceRole request) {
-        return Uni.createFrom()
-                .item(
-                        () ->
-                                Automation.DeviceRoleState.newBuilder()
-                                        .setDevRoleId(request.getDevRoleId())
-                                        .build());
+    public Uni<DeviceRoleState> ztpUpdate(DeviceRoleConfig request) {
+        final var devRoleId = request.getDevRole().getDevRoleId().getDevRoleId().getUuid();
+        final var deviceId = serializer.deserialize(request.getDevRole().getDevRoleId().getDevId());
+        final var deviceConfig = serializer.deserialize(request.getDevConfig());
+
+        return automationService
+                .updateDevice(deviceId, deviceConfig)
+                .onItem()
+                .transform(device -> transformToDeviceRoleState(device, devRoleId, DeviceState.UPDATED));
     }
 
     @Override
@@ -84,16 +89,15 @@ 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) {
-
+    private Automation.DeviceRoleState transformToDeviceRoleState(
+            Device device, String devRoleId, DeviceState deviceState) {
         final var deviceRoleId = new DeviceRoleId(devRoleId, device.getDeviceId());
         final var serializeDeviceRoleId = serializer.serialize(deviceRoleId);
+        final var serializedDeviceState = serializer.serialize(deviceState);
 
         return Automation.DeviceRoleState.newBuilder()
                 .setDevRoleId(serializeDeviceRoleId)
-                .setDevRoleState(Automation.ZtpDeviceState.ZTP_DEV_STATE_CREATED)
+                .setDevRoleState(serializedDeviceState)
                 .build();
     }
 }
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 5c8e95a442d7f6134b6817d144ff2ad646d2b5c3..b9f34d8e4bd3e1703bff1cf48a18a0a2b84e61b1 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
@@ -17,9 +17,14 @@
 package eu.teraflow.automation;
 
 import eu.teraflow.automation.context.model.Device;
+import eu.teraflow.automation.context.model.DeviceConfig;
 import io.smallrye.mutiny.Uni;
 
 public interface AutomationService {
 
     Uni<Device> addDevice(String deviceId);
+
+    Uni<Device> deleteDevice(String deviceId);
+
+    Uni<Device> updateDevice(String deviceId, DeviceConfig deviceConfig);
 }
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 13e56645384938b4eff42aa73ca9e8a5ff73a1bd..773c99de6d94b5f8806a8a354b2371c0a6748f9f 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
@@ -18,6 +18,7 @@ package eu.teraflow.automation;
 
 import eu.teraflow.automation.context.ContextService;
 import eu.teraflow.automation.context.model.Device;
+import eu.teraflow.automation.context.model.DeviceConfig;
 import eu.teraflow.automation.device.DeviceService;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
@@ -27,6 +28,7 @@ import org.jboss.logging.Logger;
 @ApplicationScoped
 public class AutomationServiceImpl implements AutomationService {
     private static final Logger LOGGER = Logger.getLogger(AutomationServiceImpl.class);
+    private static final String MESSAGE = "Retrieved %s";
 
     private final DeviceService deviceService;
     private final ContextService contextService;
@@ -43,14 +45,13 @@ public class AutomationServiceImpl implements AutomationService {
         final var deserializedDeviceUni = contextService.getDevice(deviceId);
 
         deserializedDeviceUni
-                // TODO fix subscribe
                 .subscribe()
                 .with(
                         device -> {
                             final var id = deviceId;
 
                             if (!device.isEnabled()) {
-                                LOGGER.infof("Retrieved %s", device);
+                                LOGGER.infof(MESSAGE, device);
 
                                 final var initialConfiguration =
                                         deviceService.getInitialConfiguration(device.getDeviceId());
@@ -80,4 +81,52 @@ public class AutomationServiceImpl implements AutomationService {
 
         return deserializedDeviceUni;
     }
+
+    @Override
+    public Uni<Device> deleteDevice(String deviceId) {
+        final var deserializedDeviceUni = contextService.getDevice(deviceId);
+
+        deserializedDeviceUni
+                .subscribe()
+                .with(
+                        device -> {
+                            final var id = deviceId;
+
+                            LOGGER.infof(MESSAGE, device);
+
+                            final var empty = deviceService.deleteDevice(device.getDeviceId());
+
+                            empty
+                                    .subscribe()
+                                    .with(emptyMessage -> LOGGER.infof("Device [%s] has been deleted.\n", id));
+                        });
+
+        return deserializedDeviceUni;
+    }
+
+    @Override
+    public Uni<Device> updateDevice(String deviceId, DeviceConfig deviceConfig) {
+        final var deserializedDeviceUni = contextService.getDevice(deviceId);
+
+        deserializedDeviceUni
+                .subscribe()
+                .with(
+                        device -> {
+                            final var id = deviceId;
+
+                            LOGGER.infof(MESSAGE, device);
+                            device.setDeviceConfiguration(deviceConfig);
+                            final var updatedDeviceIdUni = deviceService.configureDevice(device);
+
+                            updatedDeviceIdUni
+                                    .subscribe()
+                                    .with(
+                                            configuredDeviceId ->
+                                                    LOGGER.infof(
+                                                            "Device [%s] has been updated successfully with %s.\n",
+                                                            id, deviceConfig));
+                        });
+
+        return deserializedDeviceUni;
+    }
 }
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 df5f14081711a22c3896dfadbe14b659bcb426cf..c4d636b6b4dca7241808ade421f32a77861e4d3f 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
@@ -73,9 +73,14 @@ public class ContextSubscriber {
                                     LOGGER.infof("Received %s for device [%s]", event, deviceId);
                                     automationService.addDevice(deviceEvent.getDeviceId());
                                     break;
-
-                                case UPDATE:
                                 case REMOVE:
+                                    LOGGER.infof("Received %s for device [%s]", event, deviceId);
+                                    automationService.deleteDevice(deviceEvent.getDeviceId());
+                                    break;
+                                case UPDATE:
+                                    LOGGER.infof("Received %s for device [%s]", event, deviceId);
+                                    automationService.updateDevice(
+                                            deviceEvent.getDeviceId(), deviceEvent.getDeviceConfig().orElse(null));
                                 case UNDEFINED:
                                     logWarningMessage(event, deviceId, eventType);
                                     break;
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 9d9c3430fcfc1915552bedc8441d98dc36e3d991..445dea540b57717f1005d8b37269777f7e2147ee 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/Serializer.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/Serializer.java
@@ -18,6 +18,7 @@ package eu.teraflow.automation;
 
 import acl.Acl;
 import automation.Automation;
+import automation.Automation.ZtpDeviceState;
 import context.ContextOuterClass;
 import context.ContextOuterClass.ConfigRule_ACL;
 import context.ContextOuterClass.ConfigRule_Custom;
@@ -44,6 +45,7 @@ import eu.teraflow.automation.context.model.DeviceConfig;
 import eu.teraflow.automation.context.model.DeviceDriverEnum;
 import eu.teraflow.automation.context.model.DeviceEvent;
 import eu.teraflow.automation.context.model.DeviceOperationalStatus;
+import eu.teraflow.automation.context.model.Empty;
 import eu.teraflow.automation.context.model.EndPoint;
 import eu.teraflow.automation.context.model.EndPointId;
 import eu.teraflow.automation.context.model.Event;
@@ -55,8 +57,10 @@ import eu.teraflow.automation.context.model.LocationTypeRegion;
 import eu.teraflow.automation.context.model.TopologyId;
 import eu.teraflow.automation.kpi_sample_types.model.KpiSampleType;
 import eu.teraflow.automation.model.DeviceRole;
+import eu.teraflow.automation.model.DeviceRoleConfig;
 import eu.teraflow.automation.model.DeviceRoleId;
 import eu.teraflow.automation.model.DeviceRoleType;
+import eu.teraflow.automation.model.DeviceState;
 import java.util.stream.Collectors;
 import javax.inject.Singleton;
 import kpi_sample_types.KpiSampleTypes;
@@ -131,6 +135,36 @@ public class Serializer {
         }
     }
 
+    public Automation.ZtpDeviceState serialize(DeviceState deviceState) {
+        switch (deviceState) {
+            case CREATED:
+                return ZtpDeviceState.ZTP_DEV_STATE_CREATED;
+            case UPDATED:
+                return ZtpDeviceState.ZTP_DEV_STATE_UPDATED;
+            case DELETED:
+                return ZtpDeviceState.ZTP_DEV_STATE_DELETED;
+            case UNDEFINED:
+                return ZtpDeviceState.ZTP_DEV_STATE_UNDEFINED;
+            default:
+                return ZtpDeviceState.UNRECOGNIZED;
+        }
+    }
+
+    public DeviceState deserialize(Automation.ZtpDeviceState serializedDeviceState) {
+        switch (serializedDeviceState) {
+            case ZTP_DEV_STATE_CREATED:
+                return DeviceState.CREATED;
+            case ZTP_DEV_STATE_UPDATED:
+                return DeviceState.UPDATED;
+            case ZTP_DEV_STATE_DELETED:
+                return DeviceState.DELETED;
+            case ZTP_DEV_STATE_UNDEFINED:
+            case UNRECOGNIZED:
+            default:
+                return DeviceState.UNDEFINED;
+        }
+    }
+
     public Automation.DeviceRole serialize(DeviceRole deviceRole) {
         final var builder = Automation.DeviceRole.newBuilder();
         final var serializedDeviceRoleId = serialize(deviceRole.getDeviceRoleId());
@@ -149,6 +183,24 @@ public class Serializer {
         return new DeviceRole(deviceRoleId, deviceRoleType);
     }
 
+    public Automation.DeviceRoleConfig serialize(DeviceRoleConfig deviceRoleConfig) {
+        final var builder = Automation.DeviceRoleConfig.newBuilder();
+        final var serializedDeviceRole = serialize(deviceRoleConfig.getDeviceRole());
+        final var serializedDeviceConfig = serialize(deviceRoleConfig.getDeviceConfig());
+
+        builder.setDevRole(serializedDeviceRole);
+        builder.setDevConfig(serializedDeviceConfig);
+
+        return builder.build();
+    }
+
+    public DeviceRoleConfig deserialize(Automation.DeviceRoleConfig deviceRoleConfig) {
+        final var deviceRole = deserialize(deviceRoleConfig.getDevRole());
+        final var deviceConfig = deserialize(deviceRoleConfig.getDevConfig());
+
+        return new DeviceRoleConfig(deviceRole, deviceConfig);
+    }
+
     public ContextOuterClass.EventTypeEnum serialize(EventTypeEnum eventTypeEnum) {
         switch (eventTypeEnum) {
             case CREATE:
@@ -217,6 +269,7 @@ public class Serializer {
 
         builder.setDeviceId(deviceId);
         builder.setEvent(serialize(deviceEvent.getEvent()));
+        builder.setDeviceConfig(serialize(deviceEvent.getDeviceConfig().orElse(null)));
 
         return builder.build();
     }
@@ -224,8 +277,9 @@ public class Serializer {
     public DeviceEvent deserialize(ContextOuterClass.DeviceEvent deviceEvent) {
         final var deviceId = deserialize(deviceEvent.getDeviceId());
         final var event = deserialize(deviceEvent.getEvent());
+        final var deviceConfig = deserialize(deviceEvent.getDeviceConfig());
 
-        return new DeviceEvent(deviceId, event);
+        return new DeviceEvent(deviceId, event, deviceConfig);
     }
 
     public ContextOuterClass.ConfigActionEnum serialize(ConfigActionEnum configAction) {
@@ -924,6 +978,17 @@ public class Serializer {
                 deviceEndPoints);
     }
 
+    public ContextOuterClass.Empty serializeEmpty(Empty empty) {
+
+        final var builder = ContextOuterClass.Empty.newBuilder();
+
+        return builder.build();
+    }
+
+    public Empty deserializeEmpty(ContextOuterClass.Empty serializedEmpty) {
+        return new Empty();
+    }
+
     public Uuid serializeUuid(String uuid) {
         return Uuid.newBuilder().setUuid(uuid).build();
     }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceEvent.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceEvent.java
index efc0be8308fb9a75132cd604a84fd5b4822f3af7..526b9b7b2ba34edc6d538619bdb190a9aefa9d97 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceEvent.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/DeviceEvent.java
@@ -16,14 +16,23 @@
 
 package eu.teraflow.automation.context.model;
 
+import java.util.Optional;
+
 public class DeviceEvent {
 
     private final Event event;
     private final String deviceId;
+    private final Optional<DeviceConfig> deviceConfig;
 
     public DeviceEvent(String deviceId, Event event) {
+        this(deviceId, event, null);
+    }
+
+    public DeviceEvent(String deviceId, Event event, DeviceConfig deviceConfig) {
         this.event = event;
         this.deviceId = deviceId;
+        this.deviceConfig =
+                (deviceConfig == null) ? Optional.empty() : Optional.ofNullable(deviceConfig);
     }
 
     public Event getEvent() {
@@ -34,8 +43,14 @@ public class DeviceEvent {
         return deviceId;
     }
 
+    public Optional<DeviceConfig> getDeviceConfig() {
+        return deviceConfig;
+    }
+
     @Override
     public String toString() {
-        return String.format("%s[%s, %s]", getClass().getSimpleName(), deviceId, event.toString());
+        return String.format(
+                "%s[%s, %s, %s]",
+                getClass().getSimpleName(), deviceId, event.toString(), deviceConfig.orElse(null));
     }
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/Empty.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/Empty.java
new file mode 100644
index 0000000000000000000000000000000000000000..67649243bc356a58e3df64c491c73aee132feecc
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/Empty.java
@@ -0,0 +1,24 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+
+public class Empty {
+
+    public Empty() {
+        // Empty constructor to represent the Empty rpc message of context service
+    }
+}
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 8cbf0885ba6537e7bca31e5bb6efd0494e4fe879..5244f8ea63abdf88ce50cd6c30074809a1fb0c7b 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
@@ -18,10 +18,13 @@ package eu.teraflow.automation.device;
 
 import eu.teraflow.automation.context.model.Device;
 import eu.teraflow.automation.context.model.DeviceConfig;
+import eu.teraflow.automation.context.model.Empty;
 import io.smallrye.mutiny.Uni;
 
 public interface DeviceGateway {
     Uni<DeviceConfig> getInitialConfiguration(String deviceId);
 
     Uni<String> configureDevice(Device device);
+
+    Uni<Empty> deleteDevice(String deviceId);
 }
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 7849e36e6965df293381e5bc8a04db552d3f28d4..f045833eb98e3ce2e784ff11c9ba28bb3e955a84 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
@@ -20,6 +20,7 @@ import device.DeviceService;
 import eu.teraflow.automation.Serializer;
 import eu.teraflow.automation.context.model.Device;
 import eu.teraflow.automation.context.model.DeviceConfig;
+import eu.teraflow.automation.context.model.Empty;
 import io.quarkus.grpc.GrpcClient;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
@@ -57,4 +58,14 @@ public class DeviceGatewayImpl implements DeviceGateway {
                 .onItem()
                 .transform(serializer::deserialize);
     }
+
+    @Override
+    public Uni<Empty> deleteDevice(String deviceId) {
+        final var serializedDeviceId = serializer.serializeDeviceId(deviceId);
+
+        return deviceDelegate
+                .deleteDevice(serializedDeviceId)
+                .onItem()
+                .transform(serializer::deserializeEmpty);
+    }
 }
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 229aea7dfe29a11487d3e61709981300a2ff9600..d9f03d612743a765adbbe6b8ecbabaf48c39a9a0 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
@@ -18,6 +18,7 @@ package eu.teraflow.automation.device;
 
 import eu.teraflow.automation.context.model.Device;
 import eu.teraflow.automation.context.model.DeviceConfig;
+import eu.teraflow.automation.context.model.Empty;
 import io.smallrye.mutiny.Uni;
 
 public interface DeviceService {
@@ -25,4 +26,6 @@ public interface DeviceService {
     Uni<DeviceConfig> getInitialConfiguration(String deviceId);
 
     Uni<String> configureDevice(Device device);
+
+    Uni<Empty> deleteDevice(String deviceId);
 }
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 d5dd6fc2be73b55da9f6d31efbc21bf40c431c20..e6a8fc675479ba61a045445fdb03e2c7f7b924e2 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
@@ -18,6 +18,7 @@ package eu.teraflow.automation.device;
 
 import eu.teraflow.automation.context.model.Device;
 import eu.teraflow.automation.context.model.DeviceConfig;
+import eu.teraflow.automation.context.model.Empty;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
@@ -43,4 +44,9 @@ public class DeviceServiceImpl implements DeviceService {
 
         return deviceGateway.configureDevice(device);
     }
+
+    @Override
+    public Uni<Empty> deleteDevice(String deviceId) {
+        return deviceGateway.deleteDevice(deviceId);
+    }
 }
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 6dffcd1c0300672a3e23fc0ee8372b77b1bb55b7..da2f1c80e2f1433fe0cff6ba5397a86dd1c2da55 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
@@ -34,4 +34,10 @@ public class DeviceRole {
     public DeviceRoleType getType() {
         return type;
     }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{%s, deviceRoleType:\"%s\"}", getClass().getSimpleName(), id, type.toString());
+    }
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleConfig.java b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..aae556fff704ec22dac16304e55f31cc185517ad
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleConfig.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.automation.model;
+
+import eu.teraflow.automation.context.model.DeviceConfig;
+
+public class DeviceRoleConfig {
+
+    private final DeviceRole deviceRole;
+    private final DeviceConfig deviceConfig;
+
+    public DeviceRoleConfig(DeviceRole deviceRole, DeviceConfig deviceConfig) {
+        this.deviceRole = deviceRole;
+        this.deviceConfig = deviceConfig;
+    }
+
+    public DeviceRole getDeviceRole() {
+        return deviceRole;
+    }
+
+    public DeviceConfig getDeviceConfig() {
+        return deviceConfig;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{%s, %s}", getClass().getSimpleName(), deviceRole, deviceConfig);
+    }
+}
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 b11f42ad054a3446370e123e37c7c13b025711f3..064c4f1e647ce6fded0f67925924d50d582f29e2 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
@@ -33,4 +33,10 @@ public class DeviceRoleId {
     public String getDeviceId() {
         return deviceId;
     }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{id:\"%s\", deviceId:\"%s\"}", getClass().getSimpleName(), id, deviceId);
+    }
 }
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 e250a905c8379c01383c149cc944fdd4a55a81b4..75045288c99ff041e9fdc1d4a1bdf7365f9dd48a 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
@@ -300,4 +300,80 @@ class AutomationFunctionalServiceTest {
                             assertThat(deviceConfig.getDeviceId()).isEqualTo(deviceId);
                         });
     }
+
+    @Test
+    void shouldDeleteDevice() {
+        final var uuidForDeviceRoleId =
+                ContextOuterClass.Uuid.newBuilder()
+                        .setUuid(UUID.fromString("0f14d0ab-9608-7862-a9e4-5ed26688389b").toString())
+                        .build();
+
+        final var uuidForDeviceId =
+                ContextOuterClass.Uuid.newBuilder()
+                        .setUuid(UUID.fromString("9f14d0ab-9608-7862-a9e4-5ed26688389c").toString())
+                        .build();
+
+        final var outDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuidForDeviceId).build();
+
+        final var outDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(uuidForDeviceRoleId)
+                        .setDevId(outDeviceId)
+                        .build();
+
+        String deviceId = outDeviceRoleId.getDevRoleId().toString();
+        String deviceType = "cisco";
+
+        final var deviceDrivers = List.of(DeviceDriverEnum.IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.P4);
+
+        final var topologyIdA = new TopologyId("contextIdA", "idA");
+        final var deviceIdA = "deviceIdA";
+        final var idA = "idA";
+        final var endPointIdA = new EndPointId(topologyIdA, deviceIdA, idA);
+
+        final var endPointTypeA = "endPointTypeA";
+        final var kpiSampleTypesA =
+                List.of(KpiSampleType.BYTES_RECEIVED, KpiSampleType.BYTES_TRANSMITTED);
+        final var locationTypeRegionA = new LocationTypeRegion("ATH");
+        final var locationA = new Location(locationTypeRegionA);
+        final var endPointA =
+                new EndPointBuilder(endPointIdA, endPointTypeA, kpiSampleTypesA)
+                        .location(locationA)
+                        .build();
+
+        final var topologyIdB = new TopologyId("contextIdB", "idB");
+        final var deviceIdB = "deviceIdB";
+        final var idB = "idB";
+        final var endPointIdB = new EndPointId(topologyIdB, deviceIdB, idB);
+        final var endPointTypeB = "endPointTypeB";
+        final var kpiSampleTypesB =
+                List.of(KpiSampleType.BYTES_RECEIVED, KpiSampleType.BYTES_TRANSMITTED);
+        final var locationTypeRegionB = new LocationTypeRegion("ATH");
+        final var locationB = new Location(locationTypeRegionB);
+        final var endPointB =
+                new EndPointBuilder(endPointIdB, endPointTypeB, kpiSampleTypesB)
+                        .location(locationB)
+                        .build();
+
+        final var endPoints = List.of(endPointA, endPointB);
+
+        Device device =
+                new Device(
+                        deviceId, deviceType, DeviceOperationalStatus.DISABLED, deviceDrivers, endPoints);
+        Uni<Device> deviceUni = Uni.createFrom().item(device);
+
+        Mockito.when(contextGateway.getDevice(Mockito.any())).thenReturn(deviceUni);
+
+        final var deletedDevice = automationService.deleteDevice(deviceId);
+
+        Assertions.assertThat(deletedDevice).isNotNull();
+
+        deletedDevice
+                .subscribe()
+                .with(
+                        removedDevice -> {
+                            assertThat(removedDevice).isEqualTo(deletedDevice);
+                        });
+    }
 }
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 b1a70a7e0f0933d9d8aa6049c53d75a40ebf14d8..85ed170efbf938b11303d92a6697c89836e0bf70 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
@@ -38,6 +38,7 @@ import eu.teraflow.automation.context.model.TopologyId;
 import eu.teraflow.automation.device.DeviceGateway;
 import eu.teraflow.automation.kpi_sample_types.model.KpiSampleType;
 import eu.teraflow.automation.model.DeviceRole;
+import eu.teraflow.automation.model.DeviceRoleConfig;
 import eu.teraflow.automation.model.DeviceRoleId;
 import eu.teraflow.automation.model.DeviceRoleType;
 import io.quarkus.grpc.GrpcClient;
@@ -160,16 +161,68 @@ class AutomationServiceTest {
     @Test
     void shouldUpdateDeviceRole() throws ExecutionException, InterruptedException, TimeoutException {
         CompletableFuture<String> message = new CompletableFuture<>();
+
         final var DEVICE_ID = "0f14d0ab-9608-7862-a9e4-5ed26688389b";
         final var DEVICE_ROLE_ID = "0f14d0ab-9608-7862-a9e4-5ed26688389a";
+        final var DEVICE_TYPE = "ztp";
+
+        final var deviceDrivers = List.of(DeviceDriverEnum.IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.P4);
+
+        final var topologyIdA = new TopologyId("contextIdA", "idA");
+        final var deviceIdA = "deviceIdA";
+        final var idA = "idA";
+        final var endPointIdA = new EndPointId(topologyIdA, deviceIdA, idA);
+
+        final var endPointTypeA = "endPointTypeA";
+        final var kpiSampleTypesA =
+                List.of(KpiSampleType.BYTES_RECEIVED, KpiSampleType.BYTES_TRANSMITTED);
+        final var locationTypeRegionA = new LocationTypeRegion("ATH");
+        final var locationA = new Location(locationTypeRegionA);
+        final var endPointA =
+                new EndPointBuilder(endPointIdA, endPointTypeA, kpiSampleTypesA)
+                        .location(locationA)
+                        .build();
+
+        final var topologyIdB = new TopologyId("contextIdB", "idB");
+        final var deviceIdB = "deviceIdB";
+        final var idB = "idB";
+        final var endPointIdB = new EndPointId(topologyIdB, deviceIdB, idB);
+        final var endPointTypeB = "endPointTypeB";
+        final var kpiSampleTypesB =
+                List.of(KpiSampleType.BYTES_RECEIVED, KpiSampleType.BYTES_TRANSMITTED);
+        final var locationTypeRegionB = new LocationTypeRegion("ATH");
+        final var locationB = new Location(locationTypeRegionB);
+        final var endPointB =
+                new EndPointBuilder(endPointIdB, endPointTypeB, kpiSampleTypesB)
+                        .location(locationB)
+                        .build();
+
+        final var endPoints = List.of(endPointA, endPointB);
+
+        final var emptyDeviceConfig = new DeviceConfig(List.of());
+        final var device =
+                new Device(
+                        DEVICE_ID,
+                        DEVICE_TYPE,
+                        emptyDeviceConfig,
+                        DeviceOperationalStatus.ENABLED,
+                        deviceDrivers,
+                        endPoints);
+        Mockito.when(contextGateway.getDevice(Mockito.any())).thenReturn(Uni.createFrom().item(device));
 
         final var deviceRoleId = new DeviceRoleId(DEVICE_ROLE_ID, DEVICE_ID);
-        final var deviceRoleType = DeviceRoleType.DEV_CONF;
-        final var deviceRole = new DeviceRole(deviceRoleId, deviceRoleType);
-        final var serializedDeviceRole = serializer.serialize(deviceRole);
+        final var deviceRole = new DeviceRole(deviceRoleId, DeviceRoleType.DEV_OPS);
+
+        final var configRuleCustomA = new ConfigRuleCustom("resourceKeyA", "resourceValueA");
+        final var configRuleTypeA = new ConfigRuleTypeCustom(configRuleCustomA);
+        final var deviceConfig =
+                new DeviceConfig(List.of(new ConfigRule(ConfigActionEnum.SET, configRuleTypeA)));
+
+        final var deviceRoleConfig = new DeviceRoleConfig(deviceRole, deviceConfig);
+        final var serializedDeviceRoleConfig = serializer.serialize(deviceRoleConfig);
 
         client
-                .ztpUpdate(serializedDeviceRole)
+                .ztpUpdate(serializedDeviceRoleConfig)
                 .subscribe()
                 .with(
                         deviceRoleState -> {
diff --git a/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java b/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java
index e8a97d7922b49878af533c23918cf7b23aa20c06..6f8834a1f68e96d3f0be38f8d918ad1be7d391e9 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java
@@ -61,6 +61,7 @@ class ContextSubscriberTest {
 
         contextSubscriber.listenForDeviceEvents();
 
+        verify(automationService, times(0)).deleteDevice(deviceId);
         verify(automationService, times(1)).addDevice(deviceId);
     }
 
@@ -95,7 +96,7 @@ class ContextSubscriberTest {
     }
 
     @Test
-    void shouldNotCallAddDeviceUponRemoveEvent() {
+    void shouldCallRemoveDeviceUponRemoveEvent() {
         final var uuidForDeviceRoleId =
                 ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ROLE_ID).build();
 
@@ -122,6 +123,7 @@ class ContextSubscriberTest {
         contextSubscriber.listenForDeviceEvents();
 
         verify(automationService, times(0)).addDevice(deviceId);
+        verify(automationService, times(1)).deleteDevice(deviceId);
     }
 
     @Test
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 35ba1422b29e8e827dd1b46dd93e35571dfe3f51..efb5c97a6fbd71f66be88255b31e6757f85338b7 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java
@@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 
 import acl.Acl;
 import automation.Automation;
+import automation.Automation.ZtpDeviceState;
 import context.ContextOuterClass;
 import context.ContextOuterClass.DeviceId;
 import context.ContextOuterClass.DeviceOperationalStatusEnum;
@@ -43,6 +44,7 @@ import eu.teraflow.automation.context.model.DeviceConfig;
 import eu.teraflow.automation.context.model.DeviceDriverEnum;
 import eu.teraflow.automation.context.model.DeviceEvent;
 import eu.teraflow.automation.context.model.DeviceOperationalStatus;
+import eu.teraflow.automation.context.model.Empty;
 import eu.teraflow.automation.context.model.EndPoint.EndPointBuilder;
 import eu.teraflow.automation.context.model.EndPointId;
 import eu.teraflow.automation.context.model.Event;
@@ -54,8 +56,10 @@ import eu.teraflow.automation.context.model.LocationTypeRegion;
 import eu.teraflow.automation.context.model.TopologyId;
 import eu.teraflow.automation.kpi_sample_types.model.KpiSampleType;
 import eu.teraflow.automation.model.DeviceRole;
+import eu.teraflow.automation.model.DeviceRoleConfig;
 import eu.teraflow.automation.model.DeviceRoleId;
 import eu.teraflow.automation.model.DeviceRoleType;
+import eu.teraflow.automation.model.DeviceState;
 import io.quarkus.test.junit.QuarkusTest;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -242,6 +246,61 @@ class SerializerTest {
         assertThat(deviceRole).usingRecursiveComparison().isEqualTo(expectedDeviceRole);
     }
 
+    @Test
+    void shouldSerializeDeviceRoleConfig() {
+        final var expectedDevRoleId = new DeviceRoleId("expectedDevRoleId", "expectedDeviceId");
+        final var expectedDevRoleType = DeviceRoleType.DEV_OPS;
+
+        final var deviceRole = new DeviceRole(expectedDevRoleId, expectedDevRoleType);
+        final var serializedDeviceRole = serializer.serialize(deviceRole);
+
+        final var configRuleCustomA = new ConfigRuleCustom("resourceKeyA", "resourceValueA");
+        final var configRuleTypeA = new ConfigRuleTypeCustom(configRuleCustomA);
+        final var deviceConfig =
+                new DeviceConfig(List.of(new ConfigRule(ConfigActionEnum.SET, configRuleTypeA)));
+        final var serializedDeviceConfig = serializer.serialize(deviceConfig);
+
+        final var expectedDeviceRoleConfig =
+                Automation.DeviceRoleConfig.newBuilder()
+                        .setDevRole(serializedDeviceRole)
+                        .setDevConfig(serializedDeviceConfig)
+                        .build();
+
+        final var deviceRoleConfig = new DeviceRoleConfig(deviceRole, deviceConfig);
+        final var serializedDeviceRoleConfig = serializer.serialize(deviceRoleConfig);
+
+        assertThat(serializedDeviceRoleConfig)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedDeviceRoleConfig);
+    }
+
+    @Test
+    void shouldDeserializeDeviceRoleConfig() {
+        final var expectedDevRoleId = new DeviceRoleId("expectedDevRoleId", "expectedDeviceId");
+        final var expectedDevRoleType = DeviceRoleType.DEV_OPS;
+
+        final var deviceRole = new DeviceRole(expectedDevRoleId, expectedDevRoleType);
+        final var serializedDeviceRole = serializer.serialize(deviceRole);
+
+        final var configRuleCustomA = new ConfigRuleCustom("resourceKeyA", "resourceValueA");
+        final var configRuleTypeA = new ConfigRuleTypeCustom(configRuleCustomA);
+        final var deviceConfig =
+                new DeviceConfig(List.of(new ConfigRule(ConfigActionEnum.SET, configRuleTypeA)));
+        final var serializedDeviceConfig = serializer.serialize(deviceConfig);
+
+        final var expectedDeviceRoleConfig = new DeviceRoleConfig(deviceRole, deviceConfig);
+
+        final var serializedDeviceRoleConfig =
+                Automation.DeviceRoleConfig.newBuilder()
+                        .setDevRole(serializedDeviceRole)
+                        .setDevConfig(serializedDeviceConfig)
+                        .build();
+
+        final var deviceRoleConfig = serializer.deserialize(serializedDeviceRoleConfig);
+
+        assertThat(deviceRoleConfig).usingRecursiveComparison().isEqualTo(expectedDeviceRoleConfig);
+    }
+
     private static Stream<Arguments> provideEventTypeEnum() {
         return Stream.of(
                 Arguments.of(EventTypeEnum.CREATE, ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE),
@@ -266,6 +325,31 @@ class SerializerTest {
         assertThat(eventType).isEqualTo(expectedEventType);
     }
 
+    private static Stream<Arguments> provideDeviceState() {
+        return Stream.of(
+                Arguments.of(DeviceState.CREATED, ZtpDeviceState.ZTP_DEV_STATE_CREATED),
+                Arguments.of(DeviceState.UPDATED, ZtpDeviceState.ZTP_DEV_STATE_UPDATED),
+                Arguments.of(DeviceState.DELETED, ZtpDeviceState.ZTP_DEV_STATE_DELETED),
+                Arguments.of(DeviceState.UNDEFINED, ZtpDeviceState.ZTP_DEV_STATE_UNDEFINED));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideDeviceState")
+    void shouldSerializeDeviceState(
+            DeviceState deviceState, ZtpDeviceState expectedSerializedDeviceState) {
+        final var serializedDeviceState = serializer.serialize(deviceState);
+        assertThat(serializedDeviceState.getNumber())
+                .isEqualTo(expectedSerializedDeviceState.getNumber());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideDeviceState")
+    void shouldDeserializeDeviceState(
+            DeviceState expectedDeviceState, ZtpDeviceState serializedDeviceState) {
+        final var deviceState = serializer.deserialize(serializedDeviceState);
+        assertThat(deviceState).isEqualTo(expectedDeviceState);
+    }
+
     @Test
     void shouldSerializeEvent() {
         final var timestamp = ContextOuterClass.Timestamp.newBuilder().setTimestamp(1).build();
@@ -308,14 +392,51 @@ class SerializerTest {
                         .setTimestamp(expectedTimestamp)
                         .setEventType(ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE)
                         .build();
+
+        final var expectedConfigRuleCustomA =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey("resourceKeyA")
+                        .setResourceValue("resourceValueA")
+                        .build();
+
+        final var expectedConfigRuleCustomB =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey("resourceKeyB")
+                        .setResourceValue("resourceValueB")
+                        .build();
+
+        final var expectedConfigRuleA =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET)
+                        .setCustom(expectedConfigRuleCustomA)
+                        .build();
+        final var expectedConfigRuleB =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_DELETE)
+                        .setCustom(expectedConfigRuleCustomB)
+                        .build();
+
+        final var expectedDeviceConfig =
+                ContextOuterClass.DeviceConfig.newBuilder()
+                        .addAllConfigRules(List.of(expectedConfigRuleA, expectedConfigRuleB))
+                        .build();
+
         final var expectedDeviceEvent =
                 ContextOuterClass.DeviceEvent.newBuilder()
                         .setDeviceId(expectedDeviceId)
                         .setEvent(expectedEvent)
+                        .setDeviceConfig(expectedDeviceConfig)
                         .build();
 
         final var creationEvent = new Event(1, EventTypeEnum.CREATE);
-        final var deviceEvent = new DeviceEvent("deviceId", creationEvent);
+        final var configRuleCustomA = new ConfigRuleCustom("resourceKeyA", "resourceValueA");
+        final var configRuleCustomB = new ConfigRuleCustom("resourceKeyB", "resourceValueB");
+        final var configRuleTypeA = new ConfigRuleTypeCustom(configRuleCustomA);
+        final var configRuleTypeB = new ConfigRuleTypeCustom(configRuleCustomB);
+        final var configRuleA = new ConfigRule(ConfigActionEnum.SET, configRuleTypeA);
+        final var configRuleB = new ConfigRule(ConfigActionEnum.DELETE, configRuleTypeB);
+        final var deviceConfig = new DeviceConfig(List.of(configRuleA, configRuleB));
+        final var deviceEvent = new DeviceEvent("deviceId", creationEvent, deviceConfig);
         final var serializedDeviceEvent = serializer.serialize(deviceEvent);
 
         assertThat(serializedDeviceEvent).usingRecursiveComparison().isEqualTo(expectedDeviceEvent);
@@ -328,7 +449,22 @@ class SerializerTest {
         final var expectedTimestamp = ContextOuterClass.Timestamp.newBuilder().setTimestamp(1).build();
 
         final var creationEvent = new Event(1, expectedEventType);
-        final var expectedDeviceEvent = new DeviceEvent(dummyDeviceId, creationEvent);
+
+        final var expectedConfigRuleCustomA = new ConfigRuleCustom("resourceKeyA", "resourceValueA");
+        final var expectedConfigRuleCustomB = new ConfigRuleCustom("resourceKeyB", "resourceValueB");
+
+        final var expectedConfigRuleTypeA = new ConfigRuleTypeCustom(expectedConfigRuleCustomA);
+        final var expectedConfigRuleTypeB = new ConfigRuleTypeCustom(expectedConfigRuleCustomB);
+
+        final var expectedConfigRuleA = new ConfigRule(ConfigActionEnum.SET, expectedConfigRuleTypeA);
+        final var expectedConfigRuleB =
+                new ConfigRule(ConfigActionEnum.DELETE, expectedConfigRuleTypeB);
+
+        final var expectedDeviceConfig =
+                new DeviceConfig(List.of(expectedConfigRuleA, expectedConfigRuleB));
+
+        final var expectedDeviceEvent =
+                new DeviceEvent(dummyDeviceId, creationEvent, expectedDeviceConfig);
 
         final var deviceUuid = Uuid.newBuilder().setUuid("deviceId");
         final var deviceId = DeviceId.newBuilder().setDeviceUuid(deviceUuid).build();
@@ -337,8 +473,38 @@ class SerializerTest {
                         .setTimestamp(expectedTimestamp)
                         .setEventType(ContextOuterClass.EventTypeEnum.EVENTTYPE_REMOVE)
                         .build();
+
+        final var configRuleCustomA =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey("resourceKeyA")
+                        .setResourceValue("resourceValueA")
+                        .build();
+        final var configRuleCustomB =
+                ContextOuterClass.ConfigRule_Custom.newBuilder()
+                        .setResourceKey("resourceKeyB")
+                        .setResourceValue("resourceValueB")
+                        .build();
+        final var configRuleA =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_SET)
+                        .setCustom(configRuleCustomA)
+                        .build();
+        final var configRuleB =
+                ContextOuterClass.ConfigRule.newBuilder()
+                        .setAction(ContextOuterClass.ConfigActionEnum.CONFIGACTION_DELETE)
+                        .setCustom(configRuleCustomB)
+                        .build();
+        final var deviceConfig =
+                ContextOuterClass.DeviceConfig.newBuilder()
+                        .addAllConfigRules(List.of(configRuleA, configRuleB))
+                        .build();
+
         final var serializedDeviceEvent =
-                ContextOuterClass.DeviceEvent.newBuilder().setDeviceId(deviceId).setEvent(event).build();
+                ContextOuterClass.DeviceEvent.newBuilder()
+                        .setDeviceId(deviceId)
+                        .setEvent(event)
+                        .setDeviceConfig(deviceConfig)
+                        .build();
         final var deviceEvent = serializer.deserialize(serializedDeviceEvent);
 
         assertThat(deviceEvent).usingRecursiveComparison().isEqualTo(expectedDeviceEvent);
@@ -1592,6 +1758,27 @@ class SerializerTest {
         assertThat(device).usingRecursiveComparison().isEqualTo(expectedDevice);
     }
 
+    @Test
+    void shouldSerializeEmpty() {
+        final var empty = new Empty();
+        final var expectedEmpty = ContextOuterClass.Empty.newBuilder().build();
+
+        final var serializeEmpty = serializer.serializeEmpty(empty);
+
+        assertThat(serializeEmpty).isEqualTo(expectedEmpty);
+    }
+
+    @Test
+    void shouldDeserializeEmpty() {
+        final var expectedEmpty = new Empty();
+
+        final var serializedEmpty = serializer.serializeEmpty(expectedEmpty);
+
+        final var empty = serializer.deserializeEmpty(serializedEmpty);
+
+        assertThat(empty).usingRecursiveComparison().isEqualTo(expectedEmpty);
+    }
+
     @Test
     void shouldSerializeUuid() {
         final var expectedUuid = "uuid";
diff --git a/src/automation/target/generated-sources/grpc/automation/Automation.java b/src/automation/target/generated-sources/grpc/automation/Automation.java
index f3918e0fc18e6d97b8fd669fb307dcb94964b0e0..cd82f7423092c72c6c2fa02836db645db52f7041 100644
--- a/src/automation/target/generated-sources/grpc/automation/Automation.java
+++ b/src/automation/target/generated-sources/grpc/automation/Automation.java
@@ -1818,6 +1818,830 @@ public final class Automation {
 
   }
 
+  public interface DeviceRoleConfigOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:automation.DeviceRoleConfig)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.automation.DeviceRole devRole = 1;</code>
+     * @return Whether the devRole field is set.
+     */
+    boolean hasDevRole();
+    /**
+     * <code>.automation.DeviceRole devRole = 1;</code>
+     * @return The devRole.
+     */
+    automation.Automation.DeviceRole getDevRole();
+    /**
+     * <code>.automation.DeviceRole devRole = 1;</code>
+     */
+    automation.Automation.DeviceRoleOrBuilder getDevRoleOrBuilder();
+
+    /**
+     * <code>.context.DeviceConfig devConfig = 2;</code>
+     * @return Whether the devConfig field is set.
+     */
+    boolean hasDevConfig();
+    /**
+     * <code>.context.DeviceConfig devConfig = 2;</code>
+     * @return The devConfig.
+     */
+    context.ContextOuterClass.DeviceConfig getDevConfig();
+    /**
+     * <code>.context.DeviceConfig devConfig = 2;</code>
+     */
+    context.ContextOuterClass.DeviceConfigOrBuilder getDevConfigOrBuilder();
+  }
+  /**
+   * Protobuf type {@code automation.DeviceRoleConfig}
+   */
+  public static final class DeviceRoleConfig extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:automation.DeviceRoleConfig)
+      DeviceRoleConfigOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use DeviceRoleConfig.newBuilder() to construct.
+    private DeviceRoleConfig(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private DeviceRoleConfig() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new DeviceRoleConfig();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DeviceRoleConfig(
+        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: {
+              automation.Automation.DeviceRole.Builder subBuilder = null;
+              if (devRole_ != null) {
+                subBuilder = devRole_.toBuilder();
+              }
+              devRole_ = input.readMessage(automation.Automation.DeviceRole.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(devRole_);
+                devRole_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              context.ContextOuterClass.DeviceConfig.Builder subBuilder = null;
+              if (devConfig_ != null) {
+                subBuilder = devConfig_.toBuilder();
+              }
+              devConfig_ = input.readMessage(context.ContextOuterClass.DeviceConfig.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(devConfig_);
+                devConfig_ = 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 automation.Automation.internal_static_automation_DeviceRoleConfig_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return automation.Automation.internal_static_automation_DeviceRoleConfig_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              automation.Automation.DeviceRoleConfig.class, automation.Automation.DeviceRoleConfig.Builder.class);
+    }
+
+    public static final int DEVROLE_FIELD_NUMBER = 1;
+    private automation.Automation.DeviceRole devRole_;
+    /**
+     * <code>.automation.DeviceRole devRole = 1;</code>
+     * @return Whether the devRole field is set.
+     */
+    @java.lang.Override
+    public boolean hasDevRole() {
+      return devRole_ != null;
+    }
+    /**
+     * <code>.automation.DeviceRole devRole = 1;</code>
+     * @return The devRole.
+     */
+    @java.lang.Override
+    public automation.Automation.DeviceRole getDevRole() {
+      return devRole_ == null ? automation.Automation.DeviceRole.getDefaultInstance() : devRole_;
+    }
+    /**
+     * <code>.automation.DeviceRole devRole = 1;</code>
+     */
+    @java.lang.Override
+    public automation.Automation.DeviceRoleOrBuilder getDevRoleOrBuilder() {
+      return getDevRole();
+    }
+
+    public static final int DEVCONFIG_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.DeviceConfig devConfig_;
+    /**
+     * <code>.context.DeviceConfig devConfig = 2;</code>
+     * @return Whether the devConfig field is set.
+     */
+    @java.lang.Override
+    public boolean hasDevConfig() {
+      return devConfig_ != null;
+    }
+    /**
+     * <code>.context.DeviceConfig devConfig = 2;</code>
+     * @return The devConfig.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceConfig getDevConfig() {
+      return devConfig_ == null ? context.ContextOuterClass.DeviceConfig.getDefaultInstance() : devConfig_;
+    }
+    /**
+     * <code>.context.DeviceConfig devConfig = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceConfigOrBuilder getDevConfigOrBuilder() {
+      return getDevConfig();
+    }
+
+    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 (devRole_ != null) {
+        output.writeMessage(1, getDevRole());
+      }
+      if (devConfig_ != null) {
+        output.writeMessage(2, getDevConfig());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (devRole_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getDevRole());
+      }
+      if (devConfig_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getDevConfig());
+      }
+      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 automation.Automation.DeviceRoleConfig)) {
+        return super.equals(obj);
+      }
+      automation.Automation.DeviceRoleConfig other = (automation.Automation.DeviceRoleConfig) obj;
+
+      if (hasDevRole() != other.hasDevRole()) return false;
+      if (hasDevRole()) {
+        if (!getDevRole()
+            .equals(other.getDevRole())) return false;
+      }
+      if (hasDevConfig() != other.hasDevConfig()) return false;
+      if (hasDevConfig()) {
+        if (!getDevConfig()
+            .equals(other.getDevConfig())) 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 (hasDevRole()) {
+        hash = (37 * hash) + DEVROLE_FIELD_NUMBER;
+        hash = (53 * hash) + getDevRole().hashCode();
+      }
+      if (hasDevConfig()) {
+        hash = (37 * hash) + DEVCONFIG_FIELD_NUMBER;
+        hash = (53 * hash) + getDevConfig().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static automation.Automation.DeviceRoleConfig parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.DeviceRoleConfig parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.DeviceRoleConfig parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.DeviceRoleConfig parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.DeviceRoleConfig parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.DeviceRoleConfig parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.DeviceRoleConfig parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static automation.Automation.DeviceRoleConfig 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 automation.Automation.DeviceRoleConfig parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static automation.Automation.DeviceRoleConfig 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 automation.Automation.DeviceRoleConfig parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static automation.Automation.DeviceRoleConfig 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(automation.Automation.DeviceRoleConfig 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 automation.DeviceRoleConfig}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:automation.DeviceRoleConfig)
+        automation.Automation.DeviceRoleConfigOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return automation.Automation.internal_static_automation_DeviceRoleConfig_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return automation.Automation.internal_static_automation_DeviceRoleConfig_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                automation.Automation.DeviceRoleConfig.class, automation.Automation.DeviceRoleConfig.Builder.class);
+      }
+
+      // Construct using automation.Automation.DeviceRoleConfig.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 (devRoleBuilder_ == null) {
+          devRole_ = null;
+        } else {
+          devRole_ = null;
+          devRoleBuilder_ = null;
+        }
+        if (devConfigBuilder_ == null) {
+          devConfig_ = null;
+        } else {
+          devConfig_ = null;
+          devConfigBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return automation.Automation.internal_static_automation_DeviceRoleConfig_descriptor;
+      }
+
+      @java.lang.Override
+      public automation.Automation.DeviceRoleConfig getDefaultInstanceForType() {
+        return automation.Automation.DeviceRoleConfig.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public automation.Automation.DeviceRoleConfig build() {
+        automation.Automation.DeviceRoleConfig result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public automation.Automation.DeviceRoleConfig buildPartial() {
+        automation.Automation.DeviceRoleConfig result = new automation.Automation.DeviceRoleConfig(this);
+        if (devRoleBuilder_ == null) {
+          result.devRole_ = devRole_;
+        } else {
+          result.devRole_ = devRoleBuilder_.build();
+        }
+        if (devConfigBuilder_ == null) {
+          result.devConfig_ = devConfig_;
+        } else {
+          result.devConfig_ = devConfigBuilder_.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 automation.Automation.DeviceRoleConfig) {
+          return mergeFrom((automation.Automation.DeviceRoleConfig)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(automation.Automation.DeviceRoleConfig other) {
+        if (other == automation.Automation.DeviceRoleConfig.getDefaultInstance()) return this;
+        if (other.hasDevRole()) {
+          mergeDevRole(other.getDevRole());
+        }
+        if (other.hasDevConfig()) {
+          mergeDevConfig(other.getDevConfig());
+        }
+        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 {
+        automation.Automation.DeviceRoleConfig parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (automation.Automation.DeviceRoleConfig) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private automation.Automation.DeviceRole devRole_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          automation.Automation.DeviceRole, automation.Automation.DeviceRole.Builder, automation.Automation.DeviceRoleOrBuilder> devRoleBuilder_;
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       * @return Whether the devRole field is set.
+       */
+      public boolean hasDevRole() {
+        return devRoleBuilder_ != null || devRole_ != null;
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       * @return The devRole.
+       */
+      public automation.Automation.DeviceRole getDevRole() {
+        if (devRoleBuilder_ == null) {
+          return devRole_ == null ? automation.Automation.DeviceRole.getDefaultInstance() : devRole_;
+        } else {
+          return devRoleBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      public Builder setDevRole(automation.Automation.DeviceRole value) {
+        if (devRoleBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          devRole_ = value;
+          onChanged();
+        } else {
+          devRoleBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      public Builder setDevRole(
+          automation.Automation.DeviceRole.Builder builderForValue) {
+        if (devRoleBuilder_ == null) {
+          devRole_ = builderForValue.build();
+          onChanged();
+        } else {
+          devRoleBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      public Builder mergeDevRole(automation.Automation.DeviceRole value) {
+        if (devRoleBuilder_ == null) {
+          if (devRole_ != null) {
+            devRole_ =
+              automation.Automation.DeviceRole.newBuilder(devRole_).mergeFrom(value).buildPartial();
+          } else {
+            devRole_ = value;
+          }
+          onChanged();
+        } else {
+          devRoleBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      public Builder clearDevRole() {
+        if (devRoleBuilder_ == null) {
+          devRole_ = null;
+          onChanged();
+        } else {
+          devRole_ = null;
+          devRoleBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      public automation.Automation.DeviceRole.Builder getDevRoleBuilder() {
+        
+        onChanged();
+        return getDevRoleFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      public automation.Automation.DeviceRoleOrBuilder getDevRoleOrBuilder() {
+        if (devRoleBuilder_ != null) {
+          return devRoleBuilder_.getMessageOrBuilder();
+        } else {
+          return devRole_ == null ?
+              automation.Automation.DeviceRole.getDefaultInstance() : devRole_;
+        }
+      }
+      /**
+       * <code>.automation.DeviceRole devRole = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          automation.Automation.DeviceRole, automation.Automation.DeviceRole.Builder, automation.Automation.DeviceRoleOrBuilder> 
+          getDevRoleFieldBuilder() {
+        if (devRoleBuilder_ == null) {
+          devRoleBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              automation.Automation.DeviceRole, automation.Automation.DeviceRole.Builder, automation.Automation.DeviceRoleOrBuilder>(
+                  getDevRole(),
+                  getParentForChildren(),
+                  isClean());
+          devRole_ = null;
+        }
+        return devRoleBuilder_;
+      }
+
+      private context.ContextOuterClass.DeviceConfig devConfig_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder> devConfigBuilder_;
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       * @return Whether the devConfig field is set.
+       */
+      public boolean hasDevConfig() {
+        return devConfigBuilder_ != null || devConfig_ != null;
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       * @return The devConfig.
+       */
+      public context.ContextOuterClass.DeviceConfig getDevConfig() {
+        if (devConfigBuilder_ == null) {
+          return devConfig_ == null ? context.ContextOuterClass.DeviceConfig.getDefaultInstance() : devConfig_;
+        } else {
+          return devConfigBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      public Builder setDevConfig(context.ContextOuterClass.DeviceConfig value) {
+        if (devConfigBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          devConfig_ = value;
+          onChanged();
+        } else {
+          devConfigBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      public Builder setDevConfig(
+          context.ContextOuterClass.DeviceConfig.Builder builderForValue) {
+        if (devConfigBuilder_ == null) {
+          devConfig_ = builderForValue.build();
+          onChanged();
+        } else {
+          devConfigBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      public Builder mergeDevConfig(context.ContextOuterClass.DeviceConfig value) {
+        if (devConfigBuilder_ == null) {
+          if (devConfig_ != null) {
+            devConfig_ =
+              context.ContextOuterClass.DeviceConfig.newBuilder(devConfig_).mergeFrom(value).buildPartial();
+          } else {
+            devConfig_ = value;
+          }
+          onChanged();
+        } else {
+          devConfigBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      public Builder clearDevConfig() {
+        if (devConfigBuilder_ == null) {
+          devConfig_ = null;
+          onChanged();
+        } else {
+          devConfig_ = null;
+          devConfigBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      public context.ContextOuterClass.DeviceConfig.Builder getDevConfigBuilder() {
+        
+        onChanged();
+        return getDevConfigFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      public context.ContextOuterClass.DeviceConfigOrBuilder getDevConfigOrBuilder() {
+        if (devConfigBuilder_ != null) {
+          return devConfigBuilder_.getMessageOrBuilder();
+        } else {
+          return devConfig_ == null ?
+              context.ContextOuterClass.DeviceConfig.getDefaultInstance() : devConfig_;
+        }
+      }
+      /**
+       * <code>.context.DeviceConfig devConfig = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder> 
+          getDevConfigFieldBuilder() {
+        if (devConfigBuilder_ == null) {
+          devConfigBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder>(
+                  getDevConfig(),
+                  getParentForChildren(),
+                  isClean());
+          devConfig_ = null;
+        }
+        return devConfigBuilder_;
+      }
+      @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:automation.DeviceRoleConfig)
+    }
+
+    // @@protoc_insertion_point(class_scope:automation.DeviceRoleConfig)
+    private static final automation.Automation.DeviceRoleConfig DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new automation.Automation.DeviceRoleConfig();
+    }
+
+    public static automation.Automation.DeviceRoleConfig getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<DeviceRoleConfig>
+        PARSER = new com.google.protobuf.AbstractParser<DeviceRoleConfig>() {
+      @java.lang.Override
+      public DeviceRoleConfig parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DeviceRoleConfig(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<DeviceRoleConfig> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DeviceRoleConfig> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public automation.Automation.DeviceRoleConfig getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
   public interface DeviceRoleListOrBuilder extends
       // @@protoc_insertion_point(interface_extends:automation.DeviceRoleList)
       com.google.protobuf.MessageOrBuilder {
@@ -3987,6 +4811,11 @@ public final class Automation {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_automation_DeviceRole_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_DeviceRoleConfig_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_DeviceRoleConfig_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_automation_DeviceRoleList_descriptor;
   private static final 
@@ -4016,29 +4845,32 @@ public final class Automation {
       "2\r.context.Uuid\022 \n\005devId\030\002 \001(\0132\021.context" +
       ".DeviceId\"j\n\nDeviceRole\022+\n\tdevRoleId\030\001 \001" +
       "(\0132\030.automation.DeviceRoleId\022/\n\013devRoleT" +
-      "ype\030\002 \001(\0162\032.automation.DeviceRoleType\"9\n" +
-      "\016DeviceRoleList\022\'\n\007devRole\030\001 \003(\0132\026.autom" +
-      "ation.DeviceRole\"p\n\017DeviceRoleState\022+\n\td" +
-      "evRoleId\030\001 \001(\0132\030.automation.DeviceRoleId" +
-      "\0220\n\014devRoleState\030\002 \001(\0162\032.automation.ZtpD" +
-      "eviceState\"\'\n\024DeviceDeletionResult\022\017\n\007de" +
-      "leted\030\001 \003(\t*H\n\016DeviceRoleType\022\010\n\004NONE\020\000\022" +
-      "\013\n\007DEV_OPS\020\001\022\014\n\010DEV_CONF\020\002\022\021\n\rPIPELINE_C" +
-      "ONF\020\003*~\n\016ZtpDeviceState\022\033\n\027ZTP_DEV_STATE" +
-      "_UNDEFINED\020\000\022\031\n\025ZTP_DEV_STATE_CREATED\020\001\022" +
-      "\031\n\025ZTP_DEV_STATE_UPDATED\020\002\022\031\n\025ZTP_DEV_ST" +
-      "ATE_DELETED\020\0032\270\003\n\021AutomationService\022F\n\020Z" +
-      "tpGetDeviceRole\022\030.automation.DeviceRoleI" +
-      "d\032\026.automation.DeviceRole\"\000\022N\n\033ZtpGetDev" +
-      "iceRolesByDeviceId\022\021.context.DeviceId\032\032." +
-      "automation.DeviceRoleList\"\000\022?\n\006ZtpAdd\022\026." +
-      "automation.DeviceRole\032\033.automation.Devic" +
-      "eRoleState\"\000\022B\n\tZtpUpdate\022\026.automation.D" +
-      "eviceRole\032\033.automation.DeviceRoleState\"\000" +
-      "\022B\n\tZtpDelete\022\026.automation.DeviceRole\032\033." +
-      "automation.DeviceRoleState\"\000\022B\n\014ZtpDelet" +
-      "eAll\022\016.context.Empty\032 .automation.Device" +
-      "DeletionResult\"\000b\006proto3"
+      "ype\030\002 \001(\0162\032.automation.DeviceRoleType\"e\n" +
+      "\020DeviceRoleConfig\022\'\n\007devRole\030\001 \001(\0132\026.aut" +
+      "omation.DeviceRole\022(\n\tdevConfig\030\002 \001(\0132\025." +
+      "context.DeviceConfig\"9\n\016DeviceRoleList\022\'" +
+      "\n\007devRole\030\001 \003(\0132\026.automation.DeviceRole\"" +
+      "p\n\017DeviceRoleState\022+\n\tdevRoleId\030\001 \001(\0132\030." +
+      "automation.DeviceRoleId\0220\n\014devRoleState\030" +
+      "\002 \001(\0162\032.automation.ZtpDeviceState\"\'\n\024Dev" +
+      "iceDeletionResult\022\017\n\007deleted\030\001 \003(\t*H\n\016De" +
+      "viceRoleType\022\010\n\004NONE\020\000\022\013\n\007DEV_OPS\020\001\022\014\n\010D" +
+      "EV_CONF\020\002\022\021\n\rPIPELINE_CONF\020\003*~\n\016ZtpDevic" +
+      "eState\022\033\n\027ZTP_DEV_STATE_UNDEFINED\020\000\022\031\n\025Z" +
+      "TP_DEV_STATE_CREATED\020\001\022\031\n\025ZTP_DEV_STATE_" +
+      "UPDATED\020\002\022\031\n\025ZTP_DEV_STATE_DELETED\020\0032\276\003\n" +
+      "\021AutomationService\022F\n\020ZtpGetDeviceRole\022\030" +
+      ".automation.DeviceRoleId\032\026.automation.De" +
+      "viceRole\"\000\022N\n\033ZtpGetDeviceRolesByDeviceI" +
+      "d\022\021.context.DeviceId\032\032.automation.Device" +
+      "RoleList\"\000\022?\n\006ZtpAdd\022\026.automation.Device" +
+      "Role\032\033.automation.DeviceRoleState\"\000\022H\n\tZ" +
+      "tpUpdate\022\034.automation.DeviceRoleConfig\032\033" +
+      ".automation.DeviceRoleState\"\000\022B\n\tZtpDele" +
+      "te\022\026.automation.DeviceRole\032\033.automation." +
+      "DeviceRoleState\"\000\022B\n\014ZtpDeleteAll\022\016.cont" +
+      "ext.Empty\032 .automation.DeviceDeletionRes" +
+      "ult\"\000b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -4057,20 +4889,26 @@ public final class Automation {
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_automation_DeviceRole_descriptor,
         new java.lang.String[] { "DevRoleId", "DevRoleType", });
-    internal_static_automation_DeviceRoleList_descriptor =
+    internal_static_automation_DeviceRoleConfig_descriptor =
       getDescriptor().getMessageTypes().get(2);
+    internal_static_automation_DeviceRoleConfig_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_DeviceRoleConfig_descriptor,
+        new java.lang.String[] { "DevRole", "DevConfig", });
+    internal_static_automation_DeviceRoleList_descriptor =
+      getDescriptor().getMessageTypes().get(3);
     internal_static_automation_DeviceRoleList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_automation_DeviceRoleList_descriptor,
         new java.lang.String[] { "DevRole", });
     internal_static_automation_DeviceRoleState_descriptor =
-      getDescriptor().getMessageTypes().get(3);
+      getDescriptor().getMessageTypes().get(4);
     internal_static_automation_DeviceRoleState_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_automation_DeviceRoleState_descriptor,
         new java.lang.String[] { "DevRoleId", "DevRoleState", });
     internal_static_automation_DeviceDeletionResult_descriptor =
-      getDescriptor().getMessageTypes().get(4);
+      getDescriptor().getMessageTypes().get(5);
     internal_static_automation_DeviceDeletionResult_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_automation_DeviceDeletionResult_descriptor,
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationService.java b/src/automation/target/generated-sources/grpc/automation/AutomationService.java
index 4df9e1098d2028bba58da0959512310ed3d2c4ba..8ef5784815a7b8bb6d51b05f89f6ca3a4b23f2e5 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationService.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationService.java
@@ -14,7 +14,7 @@ public interface AutomationService extends MutinyService {
     
     io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpAdd(automation.Automation.DeviceRole request);
     
-    io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRole request);
+    io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRoleConfig request);
     
     io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDelete(automation.Automation.DeviceRole request);
     
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java b/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java
index 74d420a1ee8c3c11f824c30fb96f694ddddc64fe..3c7923a0ce8a1501689d1bb567c915590376cf5f 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java
@@ -40,7 +40,7 @@ public class AutomationServiceBean extends MutinyAutomationServiceGrpc.Automatio
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRole request) {
+    public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRoleConfig request) {
        try {
          return delegate.ztpUpdate(request);
        } catch (UnsupportedOperationException e) {
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java b/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java
index 9dcad532a0238f6f14d8e6ca2aa64b445747e9e6..13d13c431b63baebd22ed7fd566b6b25395977e3 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java
@@ -33,7 +33,7 @@ public class AutomationServiceClient implements AutomationService, MutinyClient<
        return stub.ztpAdd(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRole request) {
+    public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRoleConfig request) {
        return stub.ztpUpdate(request);
     }
     @Override
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java b/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java
index 25f5feaf327702102d1ec6cd9ca6cc8ab74cf14f..841994ea713bb9d1c0223689386d6cae35c6d014 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java
@@ -107,27 +107,27 @@ public final class AutomationServiceGrpc {
     return getZtpAddMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<automation.Automation.DeviceRole,
+  private static volatile io.grpc.MethodDescriptor<automation.Automation.DeviceRoleConfig,
       automation.Automation.DeviceRoleState> getZtpUpdateMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
       fullMethodName = SERVICE_NAME + '/' + "ZtpUpdate",
-      requestType = automation.Automation.DeviceRole.class,
+      requestType = automation.Automation.DeviceRoleConfig.class,
       responseType = automation.Automation.DeviceRoleState.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<automation.Automation.DeviceRole,
+  public static io.grpc.MethodDescriptor<automation.Automation.DeviceRoleConfig,
       automation.Automation.DeviceRoleState> getZtpUpdateMethod() {
-    io.grpc.MethodDescriptor<automation.Automation.DeviceRole, automation.Automation.DeviceRoleState> getZtpUpdateMethod;
+    io.grpc.MethodDescriptor<automation.Automation.DeviceRoleConfig, automation.Automation.DeviceRoleState> getZtpUpdateMethod;
     if ((getZtpUpdateMethod = AutomationServiceGrpc.getZtpUpdateMethod) == null) {
       synchronized (AutomationServiceGrpc.class) {
         if ((getZtpUpdateMethod = AutomationServiceGrpc.getZtpUpdateMethod) == null) {
           AutomationServiceGrpc.getZtpUpdateMethod = getZtpUpdateMethod =
-              io.grpc.MethodDescriptor.<automation.Automation.DeviceRole, automation.Automation.DeviceRoleState>newBuilder()
+              io.grpc.MethodDescriptor.<automation.Automation.DeviceRoleConfig, automation.Automation.DeviceRoleState>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
               .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ZtpUpdate"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  automation.Automation.DeviceRole.getDefaultInstance()))
+                  automation.Automation.DeviceRoleConfig.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   automation.Automation.DeviceRoleState.getDefaultInstance()))
               .setSchemaDescriptor(new AutomationServiceMethodDescriptorSupplier("ZtpUpdate"))
@@ -271,7 +271,7 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public void ztpUpdate(automation.Automation.DeviceRole request,
+    public void ztpUpdate(automation.Automation.DeviceRoleConfig request,
         io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState> responseObserver) {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getZtpUpdateMethod(), responseObserver);
     }
@@ -317,7 +317,7 @@ public final class AutomationServiceGrpc {
             getZtpUpdateMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                automation.Automation.DeviceRole,
+                automation.Automation.DeviceRoleConfig,
                 automation.Automation.DeviceRoleState>(
                   this, METHODID_ZTP_UPDATE)))
           .addMethod(
@@ -378,7 +378,7 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public void ztpUpdate(automation.Automation.DeviceRole request,
+    public void ztpUpdate(automation.Automation.DeviceRoleConfig request,
         io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
           getChannel().newCall(getZtpUpdateMethod(), getCallOptions()), request, responseObserver);
@@ -438,7 +438,7 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public automation.Automation.DeviceRoleState ztpUpdate(automation.Automation.DeviceRole request) {
+    public automation.Automation.DeviceRoleState ztpUpdate(automation.Automation.DeviceRoleConfig request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
           getChannel(), getZtpUpdateMethod(), getCallOptions(), request);
     }
@@ -499,7 +499,7 @@ public final class AutomationServiceGrpc {
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<automation.Automation.DeviceRoleState> ztpUpdate(
-        automation.Automation.DeviceRole request) {
+        automation.Automation.DeviceRoleConfig request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
           getChannel().newCall(getZtpUpdateMethod(), getCallOptions()), request);
     }
@@ -558,7 +558,7 @@ public final class AutomationServiceGrpc {
               (io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState>) responseObserver);
           break;
         case METHODID_ZTP_UPDATE:
-          serviceImpl.ztpUpdate((automation.Automation.DeviceRole) request,
+          serviceImpl.ztpUpdate((automation.Automation.DeviceRoleConfig) request,
               (io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState>) responseObserver);
           break;
         case METHODID_ZTP_DELETE:
diff --git a/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java b/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java
index 9b641fcdd7733828c58ce563651ac3d46e697287..64565286ca36fd0b820c000e466954144207ab0b 100644
--- a/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java
@@ -51,7 +51,7 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRole request) {
+        public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRoleConfig request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::ztpUpdate);
         }
 
@@ -98,7 +98,7 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRole request) {
+        public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpUpdate(automation.Automation.DeviceRoleConfig request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
@@ -139,7 +139,7 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
                             automation.AutomationServiceGrpc.getZtpUpdateMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            automation.Automation.DeviceRole,
+                                            automation.Automation.DeviceRoleConfig,
                                             automation.Automation.DeviceRoleState>(
                                             this, METHODID_ZTP_UPDATE, compression)))
                     .addMethod(
@@ -205,7 +205,7 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
                             serviceImpl::ztpAdd);
                     break;
                 case METHODID_ZTP_UPDATE:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((automation.Automation.DeviceRole) request,
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((automation.Automation.DeviceRoleConfig) request,
                             (io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState>) responseObserver,
                             compression,
                             serviceImpl::ztpUpdate);
diff --git a/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java b/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java
index 1e953741471dbe872e491ad8ab836e1d7653a05e..fbbba62a2baa1c2fe2b3c3fe090883d6542996e4 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java
@@ -17340,6 +17340,21 @@ public final class ContextOuterClass {
      * <code>.context.DeviceId device_id = 2;</code>
      */
     context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
+
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return Whether the deviceConfig field is set.
+     */
+    boolean hasDeviceConfig();
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return The deviceConfig.
+     */
+    context.ContextOuterClass.DeviceConfig getDeviceConfig();
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     */
+    context.ContextOuterClass.DeviceConfigOrBuilder getDeviceConfigOrBuilder();
   }
   /**
    * Protobuf type {@code context.DeviceEvent}
@@ -17412,6 +17427,19 @@ public final class ContextOuterClass {
 
               break;
             }
+            case 26: {
+              context.ContextOuterClass.DeviceConfig.Builder subBuilder = null;
+              if (deviceConfig_ != null) {
+                subBuilder = deviceConfig_.toBuilder();
+              }
+              deviceConfig_ = input.readMessage(context.ContextOuterClass.DeviceConfig.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(deviceConfig_);
+                deviceConfig_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -17496,6 +17524,32 @@ public final class ContextOuterClass {
       return getDeviceId();
     }
 
+    public static final int DEVICE_CONFIG_FIELD_NUMBER = 3;
+    private context.ContextOuterClass.DeviceConfig deviceConfig_;
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return Whether the deviceConfig field is set.
+     */
+    @java.lang.Override
+    public boolean hasDeviceConfig() {
+      return deviceConfig_ != null;
+    }
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return The deviceConfig.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceConfig getDeviceConfig() {
+      return deviceConfig_ == null ? context.ContextOuterClass.DeviceConfig.getDefaultInstance() : deviceConfig_;
+    }
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceConfigOrBuilder getDeviceConfigOrBuilder() {
+      return getDeviceConfig();
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -17516,6 +17570,9 @@ public final class ContextOuterClass {
       if (deviceId_ != null) {
         output.writeMessage(2, getDeviceId());
       }
+      if (deviceConfig_ != null) {
+        output.writeMessage(3, getDeviceConfig());
+      }
       unknownFields.writeTo(output);
     }
 
@@ -17533,6 +17590,10 @@ public final class ContextOuterClass {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getDeviceId());
       }
+      if (deviceConfig_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getDeviceConfig());
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -17558,6 +17619,11 @@ public final class ContextOuterClass {
         if (!getDeviceId()
             .equals(other.getDeviceId())) return false;
       }
+      if (hasDeviceConfig() != other.hasDeviceConfig()) return false;
+      if (hasDeviceConfig()) {
+        if (!getDeviceConfig()
+            .equals(other.getDeviceConfig())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -17577,6 +17643,10 @@ public final class ContextOuterClass {
         hash = (37 * hash) + DEVICE_ID_FIELD_NUMBER;
         hash = (53 * hash) + getDeviceId().hashCode();
       }
+      if (hasDeviceConfig()) {
+        hash = (37 * hash) + DEVICE_CONFIG_FIELD_NUMBER;
+        hash = (53 * hash) + getDeviceConfig().hashCode();
+      }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -17722,6 +17792,12 @@ public final class ContextOuterClass {
           deviceId_ = null;
           deviceIdBuilder_ = null;
         }
+        if (deviceConfigBuilder_ == null) {
+          deviceConfig_ = null;
+        } else {
+          deviceConfig_ = null;
+          deviceConfigBuilder_ = null;
+        }
         return this;
       }
 
@@ -17758,6 +17834,11 @@ public final class ContextOuterClass {
         } else {
           result.deviceId_ = deviceIdBuilder_.build();
         }
+        if (deviceConfigBuilder_ == null) {
+          result.deviceConfig_ = deviceConfig_;
+        } else {
+          result.deviceConfig_ = deviceConfigBuilder_.build();
+        }
         onBuilt();
         return result;
       }
@@ -17812,6 +17893,9 @@ public final class ContextOuterClass {
         if (other.hasDeviceId()) {
           mergeDeviceId(other.getDeviceId());
         }
+        if (other.hasDeviceConfig()) {
+          mergeDeviceConfig(other.getDeviceConfig());
+        }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
@@ -18078,6 +18162,125 @@ public final class ContextOuterClass {
         }
         return deviceIdBuilder_;
       }
+
+      private context.ContextOuterClass.DeviceConfig deviceConfig_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder> deviceConfigBuilder_;
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       * @return Whether the deviceConfig field is set.
+       */
+      public boolean hasDeviceConfig() {
+        return deviceConfigBuilder_ != null || deviceConfig_ != null;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       * @return The deviceConfig.
+       */
+      public context.ContextOuterClass.DeviceConfig getDeviceConfig() {
+        if (deviceConfigBuilder_ == null) {
+          return deviceConfig_ == null ? context.ContextOuterClass.DeviceConfig.getDefaultInstance() : deviceConfig_;
+        } else {
+          return deviceConfigBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder setDeviceConfig(context.ContextOuterClass.DeviceConfig value) {
+        if (deviceConfigBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          deviceConfig_ = value;
+          onChanged();
+        } else {
+          deviceConfigBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder setDeviceConfig(
+          context.ContextOuterClass.DeviceConfig.Builder builderForValue) {
+        if (deviceConfigBuilder_ == null) {
+          deviceConfig_ = builderForValue.build();
+          onChanged();
+        } else {
+          deviceConfigBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder mergeDeviceConfig(context.ContextOuterClass.DeviceConfig value) {
+        if (deviceConfigBuilder_ == null) {
+          if (deviceConfig_ != null) {
+            deviceConfig_ =
+              context.ContextOuterClass.DeviceConfig.newBuilder(deviceConfig_).mergeFrom(value).buildPartial();
+          } else {
+            deviceConfig_ = value;
+          }
+          onChanged();
+        } else {
+          deviceConfigBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder clearDeviceConfig() {
+        if (deviceConfigBuilder_ == null) {
+          deviceConfig_ = null;
+          onChanged();
+        } else {
+          deviceConfig_ = null;
+          deviceConfigBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceConfig.Builder getDeviceConfigBuilder() {
+        
+        onChanged();
+        return getDeviceConfigFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceConfigOrBuilder getDeviceConfigOrBuilder() {
+        if (deviceConfigBuilder_ != null) {
+          return deviceConfigBuilder_.getMessageOrBuilder();
+        } else {
+          return deviceConfig_ == null ?
+              context.ContextOuterClass.DeviceConfig.getDefaultInstance() : deviceConfig_;
+        }
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder> 
+          getDeviceConfigFieldBuilder() {
+        if (deviceConfigBuilder_ == null) {
+          deviceConfigBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder>(
+                  getDeviceConfig(),
+                  getParentForChildren(),
+                  isClean());
+          deviceConfig_ = null;
+        }
+        return deviceConfigBuilder_;
+      }
       @java.lang.Override
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
@@ -61990,231 +62193,234 @@ public final class ContextOuterClass {
       "(\0132\023.context.ConfigRule\"5\n\014DeviceIdList\022" +
       "%\n\ndevice_ids\030\001 \003(\0132\021.context.DeviceId\"." +
       "\n\nDeviceList\022 \n\007devices\030\001 \003(\0132\017.context." +
-      "Device\"R\n\013DeviceEvent\022\035\n\005event\030\001 \001(\0132\016.c" +
-      "ontext.Event\022$\n\tdevice_id\030\002 \001(\0132\021.contex" +
-      "t.DeviceId\"*\n\006LinkId\022 \n\tlink_uuid\030\001 \001(\0132" +
-      "\r.context.Uuid\"X\n\004Link\022 \n\007link_id\030\001 \001(\0132" +
-      "\017.context.LinkId\022.\n\021link_endpoint_ids\030\002 " +
-      "\003(\0132\023.context.EndPointId\"/\n\nLinkIdList\022!" +
-      "\n\010link_ids\030\001 \003(\0132\017.context.LinkId\"(\n\010Lin" +
-      "kList\022\034\n\005links\030\001 \003(\0132\r.context.Link\"L\n\tL" +
-      "inkEvent\022\035\n\005event\030\001 \001(\0132\016.context.Event\022" +
-      " \n\007link_id\030\002 \001(\0132\017.context.LinkId\"X\n\tSer" +
-      "viceId\022&\n\ncontext_id\030\001 \001(\0132\022.context.Con" +
-      "textId\022#\n\014service_uuid\030\002 \001(\0132\r.context.U" +
-      "uid\"\315\002\n\007Service\022&\n\nservice_id\030\001 \001(\0132\022.co" +
-      "ntext.ServiceId\022.\n\014service_type\030\002 \001(\0162\030." +
-      "context.ServiceTypeEnum\0221\n\024service_endpo" +
-      "int_ids\030\003 \003(\0132\023.context.EndPointId\0220\n\023se" +
-      "rvice_constraints\030\004 \003(\0132\023.context.Constr" +
-      "aint\022.\n\016service_status\030\005 \001(\0132\026.context.S" +
-      "erviceStatus\022.\n\016service_config\030\006 \001(\0132\026.c" +
-      "ontext.ServiceConfig\022%\n\ttimestamp\030\007 \001(\0132" +
-      "\022.context.Timestamp\"C\n\rServiceStatus\0222\n\016" +
-      "service_status\030\001 \001(\0162\032.context.ServiceSt" +
-      "atusEnum\":\n\rServiceConfig\022)\n\014config_rule" +
-      "s\030\001 \003(\0132\023.context.ConfigRule\"8\n\rServiceI" +
-      "dList\022\'\n\013service_ids\030\001 \003(\0132\022.context.Ser" +
-      "viceId\"1\n\013ServiceList\022\"\n\010services\030\001 \003(\0132" +
-      "\020.context.Service\"U\n\014ServiceEvent\022\035\n\005eve" +
-      "nt\030\001 \001(\0132\016.context.Event\022&\n\nservice_id\030\002" +
-      " \001(\0132\022.context.ServiceId\"T\n\007SliceId\022&\n\nc" +
-      "ontext_id\030\001 \001(\0132\022.context.ContextId\022!\n\ns" +
-      "lice_uuid\030\002 \001(\0132\r.context.Uuid\"\222\003\n\005Slice" +
-      "\022\"\n\010slice_id\030\001 \001(\0132\020.context.SliceId\022/\n\022" +
-      "slice_endpoint_ids\030\002 \003(\0132\023.context.EndPo" +
-      "intId\022.\n\021slice_constraints\030\003 \003(\0132\023.conte" +
-      "xt.Constraint\022-\n\021slice_service_ids\030\004 \003(\013" +
-      "2\022.context.ServiceId\022,\n\022slice_subslice_i" +
-      "ds\030\005 \003(\0132\020.context.SliceId\022*\n\014slice_stat" +
-      "us\030\006 \001(\0132\024.context.SliceStatus\022*\n\014slice_" +
-      "config\030\007 \001(\0132\024.context.SliceConfig\022(\n\013sl" +
-      "ice_owner\030\010 \001(\0132\023.context.SliceOwner\022%\n\t" +
-      "timestamp\030\t \001(\0132\022.context.Timestamp\"E\n\nS" +
-      "liceOwner\022!\n\nowner_uuid\030\001 \001(\0132\r.context." +
-      "Uuid\022\024\n\014owner_string\030\002 \001(\t\"=\n\013SliceStatu" +
-      "s\022.\n\014slice_status\030\001 \001(\0162\030.context.SliceS" +
-      "tatusEnum\"8\n\013SliceConfig\022)\n\014config_rules" +
-      "\030\001 \003(\0132\023.context.ConfigRule\"2\n\013SliceIdLi" +
-      "st\022#\n\tslice_ids\030\001 \003(\0132\020.context.SliceId\"" +
-      "+\n\tSliceList\022\036\n\006slices\030\001 \003(\0132\016.context.S" +
-      "lice\"O\n\nSliceEvent\022\035\n\005event\030\001 \001(\0132\016.cont" +
-      "ext.Event\022\"\n\010slice_id\030\002 \001(\0132\020.context.Sl" +
-      "iceId\"6\n\014ConnectionId\022&\n\017connection_uuid" +
-      "\030\001 \001(\0132\r.context.Uuid\"2\n\025ConnectionSetti" +
-      "ngs_L0\022\031\n\021lsp_symbolic_name\030\001 \001(\t\"\236\001\n\025Co" +
-      "nnectionSettings_L2\022\027\n\017src_mac_address\030\001" +
-      " \001(\t\022\027\n\017dst_mac_address\030\002 \001(\t\022\022\n\nether_t" +
-      "ype\030\003 \001(\r\022\017\n\007vlan_id\030\004 \001(\r\022\022\n\nmpls_label" +
-      "\030\005 \001(\r\022\032\n\022mpls_traffic_class\030\006 \001(\r\"t\n\025Co" +
-      "nnectionSettings_L3\022\026\n\016src_ip_address\030\001 " +
-      "\001(\t\022\026\n\016dst_ip_address\030\002 \001(\t\022\014\n\004dscp\030\003 \001(" +
-      "\r\022\020\n\010protocol\030\004 \001(\r\022\013\n\003ttl\030\005 \001(\r\"[\n\025Conn" +
-      "ectionSettings_L4\022\020\n\010src_port\030\001 \001(\r\022\020\n\010d" +
-      "st_port\030\002 \001(\r\022\021\n\ttcp_flags\030\003 \001(\r\022\013\n\003ttl\030" +
-      "\004 \001(\r\"\304\001\n\022ConnectionSettings\022*\n\002l0\030\001 \001(\013" +
-      "2\036.context.ConnectionSettings_L0\022*\n\002l2\030\002" +
-      " \001(\0132\036.context.ConnectionSettings_L2\022*\n\002" +
-      "l3\030\003 \001(\0132\036.context.ConnectionSettings_L3" +
-      "\022*\n\002l4\030\004 \001(\0132\036.context.ConnectionSetting" +
-      "s_L4\"\363\001\n\nConnection\022,\n\rconnection_id\030\001 \001" +
-      "(\0132\025.context.ConnectionId\022&\n\nservice_id\030" +
-      "\002 \001(\0132\022.context.ServiceId\0223\n\026path_hops_e" +
-      "ndpoint_ids\030\003 \003(\0132\023.context.EndPointId\022+" +
-      "\n\017sub_service_ids\030\004 \003(\0132\022.context.Servic" +
-      "eId\022-\n\010settings\030\005 \001(\0132\033.context.Connecti" +
-      "onSettings\"A\n\020ConnectionIdList\022-\n\016connec" +
-      "tion_ids\030\001 \003(\0132\025.context.ConnectionId\":\n" +
-      "\016ConnectionList\022(\n\013connections\030\001 \003(\0132\023.c" +
-      "ontext.Connection\"^\n\017ConnectionEvent\022\035\n\005" +
-      "event\030\001 \001(\0132\016.context.Event\022,\n\rconnectio" +
-      "n_id\030\002 \001(\0132\025.context.ConnectionId\"\202\001\n\nEn" +
-      "dPointId\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.contex" +
-      "t.Uuid\"\264\001\n\010EndPoint\022(\n\013endpoint_id\030\001 \001(\013" +
-      "2\023.context.EndPointId\022\025\n\rendpoint_type\030\002" +
-      " \001(\t\0229\n\020kpi_sample_types\030\003 \003(\0162\037.kpi_sam" +
-      "ple_types.KpiSampleType\022,\n\021endpoint_loca" +
-      "tion\030\004 \001(\0132\021.context.Location\"A\n\021ConfigR" +
-      "ule_Custom\022\024\n\014resource_key\030\001 \001(\t\022\026\n\016reso" +
-      "urce_value\030\002 \001(\t\"]\n\016ConfigRule_ACL\022(\n\013en" +
-      "dpoint_id\030\001 \001(\0132\023.context.EndPointId\022!\n\010" +
-      "rule_set\030\002 \001(\0132\017.acl.AclRuleSet\"\234\001\n\nConf" +
-      "igRule\022)\n\006action\030\001 \001(\0162\031.context.ConfigA" +
-      "ctionEnum\022,\n\006custom\030\002 \001(\0132\032.context.Conf" +
-      "igRule_CustomH\000\022&\n\003acl\030\003 \001(\0132\027.context.C" +
-      "onfigRule_ACLH\000B\r\n\013config_rule\"F\n\021Constr" +
-      "aint_Custom\022\027\n\017constraint_type\030\001 \001(\t\022\030\n\020" +
-      "constraint_value\030\002 \001(\t\"E\n\023Constraint_Sch" +
-      "edule\022\027\n\017start_timestamp\030\001 \001(\002\022\025\n\rdurati" +
-      "on_days\030\002 \001(\002\"3\n\014GPS_Position\022\020\n\010latitud" +
-      "e\030\001 \001(\002\022\021\n\tlongitude\030\002 \001(\002\"W\n\010Location\022\020" +
-      "\n\006region\030\001 \001(\tH\000\022-\n\014gps_position\030\002 \001(\0132\025" +
-      ".context.GPS_PositionH\000B\n\n\010location\"l\n\033C" +
-      "onstraint_EndPointLocation\022(\n\013endpoint_i" +
-      "d\030\001 \001(\0132\023.context.EndPointId\022#\n\010location" +
-      "\030\002 \001(\0132\021.context.Location\"Y\n\033Constraint_" +
-      "EndPointPriority\022(\n\013endpoint_id\030\001 \001(\0132\023." +
-      "context.EndPointId\022\020\n\010priority\030\002 \001(\r\"0\n\026" +
-      "Constraint_SLA_Latency\022\026\n\016e2e_latency_ms" +
-      "\030\001 \001(\002\"0\n\027Constraint_SLA_Capacity\022\025\n\rcap" +
-      "acity_gbps\030\001 \001(\002\"M\n\033Constraint_SLA_Avail" +
-      "ability\022\032\n\022num_disjoint_paths\030\001 \001(\r\022\022\n\na" +
-      "ll_active\030\002 \001(\010\"V\n\036Constraint_SLA_Isolat" +
-      "ion_level\0224\n\017isolation_level\030\001 \003(\0162\033.con" +
-      "text.IsolationLevelEnum\"\366\003\n\nConstraint\022," +
-      "\n\006custom\030\001 \001(\0132\032.context.Constraint_Cust" +
-      "omH\000\0220\n\010schedule\030\002 \001(\0132\034.context.Constra" +
-      "int_ScheduleH\000\022A\n\021endpoint_location\030\003 \001(" +
-      "\0132$.context.Constraint_EndPointLocationH" +
-      "\000\022A\n\021endpoint_priority\030\004 \001(\0132$.context.C" +
-      "onstraint_EndPointPriorityH\000\0228\n\014sla_capa" +
-      "city\030\005 \001(\0132 .context.Constraint_SLA_Capa" +
-      "cityH\000\0226\n\013sla_latency\030\006 \001(\0132\037.context.Co" +
-      "nstraint_SLA_LatencyH\000\022@\n\020sla_availabili" +
-      "ty\030\007 \001(\0132$.context.Constraint_SLA_Availa" +
-      "bilityH\000\022@\n\rsla_isolation\030\010 \001(\0132\'.contex" +
-      "t.Constraint_SLA_Isolation_levelH\000B\014\n\nco" +
-      "nstraint\"^\n\022TeraFlowController\022&\n\ncontex" +
-      "t_id\030\001 \001(\0132\022.context.ContextId\022\022\n\nip_add" +
-      "ress\030\002 \001(\t\022\014\n\004port\030\003 \001(\r\"U\n\024Authenticati" +
-      "onResult\022&\n\ncontext_id\030\001 \001(\0132\022.context.C" +
-      "ontextId\022\025\n\rauthenticated\030\002 \001(\010*j\n\rEvent" +
-      "TypeEnum\022\027\n\023EVENTTYPE_UNDEFINED\020\000\022\024\n\020EVE" +
-      "NTTYPE_CREATE\020\001\022\024\n\020EVENTTYPE_UPDATE\020\002\022\024\n" +
-      "\020EVENTTYPE_REMOVE\020\003*\332\001\n\020DeviceDriverEnum" +
-      "\022\032\n\026DEVICEDRIVER_UNDEFINED\020\000\022\033\n\027DEVICEDR" +
-      "IVER_OPENCONFIG\020\001\022\036\n\032DEVICEDRIVER_TRANSP" +
-      "ORT_API\020\002\022\023\n\017DEVICEDRIVER_P4\020\003\022&\n\"DEVICE" +
-      "DRIVER_IETF_NETWORK_TOPOLOGY\020\004\022\033\n\027DEVICE" +
-      "DRIVER_ONF_TR_352\020\005\022\023\n\017DEVICEDRIVER_XR\020\006" +
-      "*\217\001\n\033DeviceOperationalStatusEnum\022%\n!DEVI" +
-      "CEOPERATIONALSTATUS_UNDEFINED\020\000\022$\n DEVIC" +
-      "EOPERATIONALSTATUS_DISABLED\020\001\022#\n\037DEVICEO" +
-      "PERATIONALSTATUS_ENABLED\020\002*\201\001\n\017ServiceTy" +
-      "peEnum\022\027\n\023SERVICETYPE_UNKNOWN\020\000\022\024\n\020SERVI" +
-      "CETYPE_L3NM\020\001\022\024\n\020SERVICETYPE_L2NM\020\002\022)\n%S" +
-      "ERVICETYPE_TAPI_CONNECTIVITY_SERVICE\020\003*\250" +
-      "\001\n\021ServiceStatusEnum\022\033\n\027SERVICESTATUS_UN" +
-      "DEFINED\020\000\022\031\n\025SERVICESTATUS_PLANNED\020\001\022\030\n\024" +
-      "SERVICESTATUS_ACTIVE\020\002\022!\n\035SERVICESTATUS_" +
-      "PENDING_REMOVAL\020\003\022\036\n\032SERVICESTATUS_SLA_V" +
-      "IOLATED\020\004*\251\001\n\017SliceStatusEnum\022\031\n\025SLICEST" +
-      "ATUS_UNDEFINED\020\000\022\027\n\023SLICESTATUS_PLANNED\020" +
-      "\001\022\024\n\020SLICESTATUS_INIT\020\002\022\026\n\022SLICESTATUS_A" +
-      "CTIVE\020\003\022\026\n\022SLICESTATUS_DEINIT\020\004\022\034\n\030SLICE" +
-      "STATUS_SLA_VIOLATED\020\005*]\n\020ConfigActionEnu" +
-      "m\022\032\n\026CONFIGACTION_UNDEFINED\020\000\022\024\n\020CONFIGA" +
-      "CTION_SET\020\001\022\027\n\023CONFIGACTION_DELETE\020\002*\203\002\n" +
-      "\022IsolationLevelEnum\022\020\n\014NO_ISOLATION\020\000\022\026\n" +
-      "\022PHYSICAL_ISOLATION\020\001\022\025\n\021LOGICAL_ISOLATI" +
-      "ON\020\002\022\025\n\021PROCESS_ISOLATION\020\003\022\035\n\031PHYSICAL_" +
-      "MEMORY_ISOLATION\020\004\022\036\n\032PHYSICAL_NETWORK_I" +
-      "SOLATION\020\005\022\036\n\032VIRTUAL_RESOURCE_ISOLATION" +
-      "\020\006\022\037\n\033NETWORK_FUNCTIONS_ISOLATION\020\007\022\025\n\021S" +
-      "ERVICE_ISOLATION\020\0102\357\022\n\016ContextService\022:\n" +
-      "\016ListContextIds\022\016.context.Empty\032\026.contex" +
-      "t.ContextIdList\"\000\0226\n\014ListContexts\022\016.cont" +
-      "ext.Empty\032\024.context.ContextList\"\000\0224\n\nGet" +
-      "Context\022\022.context.ContextId\032\020.context.Co" +
-      "ntext\"\000\0224\n\nSetContext\022\020.context.Context\032" +
-      "\022.context.ContextId\"\000\0225\n\rRemoveContext\022\022" +
-      ".context.ContextId\032\016.context.Empty\"\000\022=\n\020" +
-      "GetContextEvents\022\016.context.Empty\032\025.conte" +
-      "xt.ContextEvent\"\0000\001\022@\n\017ListTopologyIds\022\022" +
-      ".context.ContextId\032\027.context.TopologyIdL" +
-      "ist\"\000\022=\n\016ListTopologies\022\022.context.Contex" +
-      "tId\032\025.context.TopologyList\"\000\0227\n\013GetTopol" +
-      "ogy\022\023.context.TopologyId\032\021.context.Topol" +
-      "ogy\"\000\0227\n\013SetTopology\022\021.context.Topology\032" +
-      "\023.context.TopologyId\"\000\0227\n\016RemoveTopology" +
-      "\022\023.context.TopologyId\032\016.context.Empty\"\000\022" +
-      "?\n\021GetTopologyEvents\022\016.context.Empty\032\026.c" +
-      "ontext.TopologyEvent\"\0000\001\0228\n\rListDeviceId" +
-      "s\022\016.context.Empty\032\025.context.DeviceIdList" +
-      "\"\000\0224\n\013ListDevices\022\016.context.Empty\032\023.cont" +
-      "ext.DeviceList\"\000\0221\n\tGetDevice\022\021.context." +
-      "DeviceId\032\017.context.Device\"\000\0221\n\tSetDevice" +
-      "\022\017.context.Device\032\021.context.DeviceId\"\000\0223" +
-      "\n\014RemoveDevice\022\021.context.DeviceId\032\016.cont" +
-      "ext.Empty\"\000\022;\n\017GetDeviceEvents\022\016.context" +
-      ".Empty\032\024.context.DeviceEvent\"\0000\001\0224\n\013List" +
-      "LinkIds\022\016.context.Empty\032\023.context.LinkId" +
-      "List\"\000\0220\n\tListLinks\022\016.context.Empty\032\021.co" +
-      "ntext.LinkList\"\000\022+\n\007GetLink\022\017.context.Li" +
-      "nkId\032\r.context.Link\"\000\022+\n\007SetLink\022\r.conte" +
-      "xt.Link\032\017.context.LinkId\"\000\022/\n\nRemoveLink" +
-      "\022\017.context.LinkId\032\016.context.Empty\"\000\0227\n\rG" +
-      "etLinkEvents\022\016.context.Empty\032\022.context.L" +
-      "inkEvent\"\0000\001\022>\n\016ListServiceIds\022\022.context" +
-      ".ContextId\032\026.context.ServiceIdList\"\000\022:\n\014" +
-      "ListServices\022\022.context.ContextId\032\024.conte" +
-      "xt.ServiceList\"\000\0224\n\nGetService\022\022.context" +
-      ".ServiceId\032\020.context.Service\"\000\0224\n\nSetSer" +
-      "vice\022\020.context.Service\032\022.context.Service" +
-      "Id\"\000\0225\n\rRemoveService\022\022.context.ServiceI" +
-      "d\032\016.context.Empty\"\000\022=\n\020GetServiceEvents\022" +
-      "\016.context.Empty\032\025.context.ServiceEvent\"\000" +
-      "0\001\022:\n\014ListSliceIds\022\022.context.ContextId\032\024" +
-      ".context.SliceIdList\"\000\0226\n\nListSlices\022\022.c" +
-      "ontext.ContextId\032\022.context.SliceList\"\000\022." +
-      "\n\010GetSlice\022\020.context.SliceId\032\016.context.S" +
-      "lice\"\000\022.\n\010SetSlice\022\016.context.Slice\032\020.con" +
-      "text.SliceId\"\000\0221\n\013RemoveSlice\022\020.context." +
-      "SliceId\032\016.context.Empty\"\000\0229\n\016GetSliceEve" +
-      "nts\022\016.context.Empty\032\023.context.SliceEvent" +
-      "\"\0000\001\022D\n\021ListConnectionIds\022\022.context.Serv" +
-      "iceId\032\031.context.ConnectionIdList\"\000\022@\n\017Li" +
-      "stConnections\022\022.context.ServiceId\032\027.cont" +
-      "ext.ConnectionList\"\000\022=\n\rGetConnection\022\025." +
-      "context.ConnectionId\032\023.context.Connectio" +
-      "n\"\000\022=\n\rSetConnection\022\023.context.Connectio" +
-      "n\032\025.context.ConnectionId\"\000\022;\n\020RemoveConn" +
-      "ection\022\025.context.ConnectionId\032\016.context." +
-      "Empty\"\000\022C\n\023GetConnectionEvents\022\016.context" +
-      ".Empty\032\030.context.ConnectionEvent\"\0000\001b\006pr" +
-      "oto3"
+      "Device\"\200\001\n\013DeviceEvent\022\035\n\005event\030\001 \001(\0132\016." +
+      "context.Event\022$\n\tdevice_id\030\002 \001(\0132\021.conte" +
+      "xt.DeviceId\022,\n\rdevice_config\030\003 \001(\0132\025.con" +
+      "text.DeviceConfig\"*\n\006LinkId\022 \n\tlink_uuid" +
+      "\030\001 \001(\0132\r.context.Uuid\"X\n\004Link\022 \n\007link_id" +
+      "\030\001 \001(\0132\017.context.LinkId\022.\n\021link_endpoint" +
+      "_ids\030\002 \003(\0132\023.context.EndPointId\"/\n\nLinkI" +
+      "dList\022!\n\010link_ids\030\001 \003(\0132\017.context.LinkId" +
+      "\"(\n\010LinkList\022\034\n\005links\030\001 \003(\0132\r.context.Li" +
+      "nk\"L\n\tLinkEvent\022\035\n\005event\030\001 \001(\0132\016.context" +
+      ".Event\022 \n\007link_id\030\002 \001(\0132\017.context.LinkId" +
+      "\"X\n\tServiceId\022&\n\ncontext_id\030\001 \001(\0132\022.cont" +
+      "ext.ContextId\022#\n\014service_uuid\030\002 \001(\0132\r.co" +
+      "ntext.Uuid\"\315\002\n\007Service\022&\n\nservice_id\030\001 \001" +
+      "(\0132\022.context.ServiceId\022.\n\014service_type\030\002" +
+      " \001(\0162\030.context.ServiceTypeEnum\0221\n\024servic" +
+      "e_endpoint_ids\030\003 \003(\0132\023.context.EndPointI" +
+      "d\0220\n\023service_constraints\030\004 \003(\0132\023.context" +
+      ".Constraint\022.\n\016service_status\030\005 \001(\0132\026.co" +
+      "ntext.ServiceStatus\022.\n\016service_config\030\006 " +
+      "\001(\0132\026.context.ServiceConfig\022%\n\ttimestamp" +
+      "\030\007 \001(\0132\022.context.Timestamp\"C\n\rServiceSta" +
+      "tus\0222\n\016service_status\030\001 \001(\0162\032.context.Se" +
+      "rviceStatusEnum\":\n\rServiceConfig\022)\n\014conf" +
+      "ig_rules\030\001 \003(\0132\023.context.ConfigRule\"8\n\rS" +
+      "erviceIdList\022\'\n\013service_ids\030\001 \003(\0132\022.cont" +
+      "ext.ServiceId\"1\n\013ServiceList\022\"\n\010services" +
+      "\030\001 \003(\0132\020.context.Service\"U\n\014ServiceEvent" +
+      "\022\035\n\005event\030\001 \001(\0132\016.context.Event\022&\n\nservi" +
+      "ce_id\030\002 \001(\0132\022.context.ServiceId\"T\n\007Slice" +
+      "Id\022&\n\ncontext_id\030\001 \001(\0132\022.context.Context" +
+      "Id\022!\n\nslice_uuid\030\002 \001(\0132\r.context.Uuid\"\222\003" +
+      "\n\005Slice\022\"\n\010slice_id\030\001 \001(\0132\020.context.Slic" +
+      "eId\022/\n\022slice_endpoint_ids\030\002 \003(\0132\023.contex" +
+      "t.EndPointId\022.\n\021slice_constraints\030\003 \003(\0132" +
+      "\023.context.Constraint\022-\n\021slice_service_id" +
+      "s\030\004 \003(\0132\022.context.ServiceId\022,\n\022slice_sub" +
+      "slice_ids\030\005 \003(\0132\020.context.SliceId\022*\n\014sli" +
+      "ce_status\030\006 \001(\0132\024.context.SliceStatus\022*\n" +
+      "\014slice_config\030\007 \001(\0132\024.context.SliceConfi" +
+      "g\022(\n\013slice_owner\030\010 \001(\0132\023.context.SliceOw" +
+      "ner\022%\n\ttimestamp\030\t \001(\0132\022.context.Timesta" +
+      "mp\"E\n\nSliceOwner\022!\n\nowner_uuid\030\001 \001(\0132\r.c" +
+      "ontext.Uuid\022\024\n\014owner_string\030\002 \001(\t\"=\n\013Sli" +
+      "ceStatus\022.\n\014slice_status\030\001 \001(\0162\030.context" +
+      ".SliceStatusEnum\"8\n\013SliceConfig\022)\n\014confi" +
+      "g_rules\030\001 \003(\0132\023.context.ConfigRule\"2\n\013Sl" +
+      "iceIdList\022#\n\tslice_ids\030\001 \003(\0132\020.context.S" +
+      "liceId\"+\n\tSliceList\022\036\n\006slices\030\001 \003(\0132\016.co" +
+      "ntext.Slice\"O\n\nSliceEvent\022\035\n\005event\030\001 \001(\013" +
+      "2\016.context.Event\022\"\n\010slice_id\030\002 \001(\0132\020.con" +
+      "text.SliceId\"6\n\014ConnectionId\022&\n\017connecti" +
+      "on_uuid\030\001 \001(\0132\r.context.Uuid\"2\n\025Connecti" +
+      "onSettings_L0\022\031\n\021lsp_symbolic_name\030\001 \001(\t" +
+      "\"\236\001\n\025ConnectionSettings_L2\022\027\n\017src_mac_ad" +
+      "dress\030\001 \001(\t\022\027\n\017dst_mac_address\030\002 \001(\t\022\022\n\n" +
+      "ether_type\030\003 \001(\r\022\017\n\007vlan_id\030\004 \001(\r\022\022\n\nmpl" +
+      "s_label\030\005 \001(\r\022\032\n\022mpls_traffic_class\030\006 \001(" +
+      "\r\"t\n\025ConnectionSettings_L3\022\026\n\016src_ip_add" +
+      "ress\030\001 \001(\t\022\026\n\016dst_ip_address\030\002 \001(\t\022\014\n\004ds" +
+      "cp\030\003 \001(\r\022\020\n\010protocol\030\004 \001(\r\022\013\n\003ttl\030\005 \001(\r\"" +
+      "[\n\025ConnectionSettings_L4\022\020\n\010src_port\030\001 \001" +
+      "(\r\022\020\n\010dst_port\030\002 \001(\r\022\021\n\ttcp_flags\030\003 \001(\r\022" +
+      "\013\n\003ttl\030\004 \001(\r\"\304\001\n\022ConnectionSettings\022*\n\002l" +
+      "0\030\001 \001(\0132\036.context.ConnectionSettings_L0\022" +
+      "*\n\002l2\030\002 \001(\0132\036.context.ConnectionSettings" +
+      "_L2\022*\n\002l3\030\003 \001(\0132\036.context.ConnectionSett" +
+      "ings_L3\022*\n\002l4\030\004 \001(\0132\036.context.Connection" +
+      "Settings_L4\"\363\001\n\nConnection\022,\n\rconnection" +
+      "_id\030\001 \001(\0132\025.context.ConnectionId\022&\n\nserv" +
+      "ice_id\030\002 \001(\0132\022.context.ServiceId\0223\n\026path" +
+      "_hops_endpoint_ids\030\003 \003(\0132\023.context.EndPo" +
+      "intId\022+\n\017sub_service_ids\030\004 \003(\0132\022.context" +
+      ".ServiceId\022-\n\010settings\030\005 \001(\0132\033.context.C" +
+      "onnectionSettings\"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\"\264\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\022,\n\021endpoi" +
+      "nt_location\030\004 \001(\0132\021.context.Location\"A\n\021" +
+      "ConfigRule_Custom\022\024\n\014resource_key\030\001 \001(\t\022" +
+      "\026\n\016resource_value\030\002 \001(\t\"]\n\016ConfigRule_AC" +
+      "L\022(\n\013endpoint_id\030\001 \001(\0132\023.context.EndPoin" +
+      "tId\022!\n\010rule_set\030\002 \001(\0132\017.acl.AclRuleSet\"\234" +
+      "\001\n\nConfigRule\022)\n\006action\030\001 \001(\0162\031.context." +
+      "ConfigActionEnum\022,\n\006custom\030\002 \001(\0132\032.conte" +
+      "xt.ConfigRule_CustomH\000\022&\n\003acl\030\003 \001(\0132\027.co" +
+      "ntext.ConfigRule_ACLH\000B\r\n\013config_rule\"F\n" +
+      "\021Constraint_Custom\022\027\n\017constraint_type\030\001 " +
+      "\001(\t\022\030\n\020constraint_value\030\002 \001(\t\"E\n\023Constra" +
+      "int_Schedule\022\027\n\017start_timestamp\030\001 \001(\002\022\025\n" +
+      "\rduration_days\030\002 \001(\002\"3\n\014GPS_Position\022\020\n\010" +
+      "latitude\030\001 \001(\002\022\021\n\tlongitude\030\002 \001(\002\"W\n\010Loc" +
+      "ation\022\020\n\006region\030\001 \001(\tH\000\022-\n\014gps_position\030" +
+      "\002 \001(\0132\025.context.GPS_PositionH\000B\n\n\010locati" +
+      "on\"l\n\033Constraint_EndPointLocation\022(\n\013end" +
+      "point_id\030\001 \001(\0132\023.context.EndPointId\022#\n\010l" +
+      "ocation\030\002 \001(\0132\021.context.Location\"Y\n\033Cons" +
+      "traint_EndPointPriority\022(\n\013endpoint_id\030\001" +
+      " \001(\0132\023.context.EndPointId\022\020\n\010priority\030\002 " +
+      "\001(\r\"0\n\026Constraint_SLA_Latency\022\026\n\016e2e_lat" +
+      "ency_ms\030\001 \001(\002\"0\n\027Constraint_SLA_Capacity" +
+      "\022\025\n\rcapacity_gbps\030\001 \001(\002\"M\n\033Constraint_SL" +
+      "A_Availability\022\032\n\022num_disjoint_paths\030\001 \001" +
+      "(\r\022\022\n\nall_active\030\002 \001(\010\"V\n\036Constraint_SLA" +
+      "_Isolation_level\0224\n\017isolation_level\030\001 \003(" +
+      "\0162\033.context.IsolationLevelEnum\"\366\003\n\nConst" +
+      "raint\022,\n\006custom\030\001 \001(\0132\032.context.Constrai" +
+      "nt_CustomH\000\0220\n\010schedule\030\002 \001(\0132\034.context." +
+      "Constraint_ScheduleH\000\022A\n\021endpoint_locati" +
+      "on\030\003 \001(\0132$.context.Constraint_EndPointLo" +
+      "cationH\000\022A\n\021endpoint_priority\030\004 \001(\0132$.co" +
+      "ntext.Constraint_EndPointPriorityH\000\0228\n\014s" +
+      "la_capacity\030\005 \001(\0132 .context.Constraint_S" +
+      "LA_CapacityH\000\0226\n\013sla_latency\030\006 \001(\0132\037.con" +
+      "text.Constraint_SLA_LatencyH\000\022@\n\020sla_ava" +
+      "ilability\030\007 \001(\0132$.context.Constraint_SLA" +
+      "_AvailabilityH\000\022@\n\rsla_isolation\030\010 \001(\0132\'" +
+      ".context.Constraint_SLA_Isolation_levelH" +
+      "\000B\014\n\nconstraint\"^\n\022TeraFlowController\022&\n" +
+      "\ncontext_id\030\001 \001(\0132\022.context.ContextId\022\022\n" +
+      "\nip_address\030\002 \001(\t\022\014\n\004port\030\003 \001(\r\"U\n\024Authe" +
+      "nticationResult\022&\n\ncontext_id\030\001 \001(\0132\022.co" +
+      "ntext.ContextId\022\025\n\rauthenticated\030\002 \001(\010*j" +
+      "\n\rEventTypeEnum\022\027\n\023EVENTTYPE_UNDEFINED\020\000" +
+      "\022\024\n\020EVENTTYPE_CREATE\020\001\022\024\n\020EVENTTYPE_UPDA" +
+      "TE\020\002\022\024\n\020EVENTTYPE_REMOVE\020\003*\332\001\n\020DeviceDri" +
+      "verEnum\022\032\n\026DEVICEDRIVER_UNDEFINED\020\000\022\033\n\027D" +
+      "EVICEDRIVER_OPENCONFIG\020\001\022\036\n\032DEVICEDRIVER" +
+      "_TRANSPORT_API\020\002\022\023\n\017DEVICEDRIVER_P4\020\003\022&\n" +
+      "\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\020\004\022\033\n" +
+      "\027DEVICEDRIVER_ONF_TR_352\020\005\022\023\n\017DEVICEDRIV" +
+      "ER_XR\020\006*\217\001\n\033DeviceOperationalStatusEnum\022" +
+      "%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\020\000\022$" +
+      "\n DEVICEOPERATIONALSTATUS_DISABLED\020\001\022#\n\037" +
+      "DEVICEOPERATIONALSTATUS_ENABLED\020\002*\201\001\n\017Se" +
+      "rviceTypeEnum\022\027\n\023SERVICETYPE_UNKNOWN\020\000\022\024" +
+      "\n\020SERVICETYPE_L3NM\020\001\022\024\n\020SERVICETYPE_L2NM" +
+      "\020\002\022)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERV" +
+      "ICE\020\003*\250\001\n\021ServiceStatusEnum\022\033\n\027SERVICEST" +
+      "ATUS_UNDEFINED\020\000\022\031\n\025SERVICESTATUS_PLANNE" +
+      "D\020\001\022\030\n\024SERVICESTATUS_ACTIVE\020\002\022!\n\035SERVICE" +
+      "STATUS_PENDING_REMOVAL\020\003\022\036\n\032SERVICESTATU" +
+      "S_SLA_VIOLATED\020\004*\251\001\n\017SliceStatusEnum\022\031\n\025" +
+      "SLICESTATUS_UNDEFINED\020\000\022\027\n\023SLICESTATUS_P" +
+      "LANNED\020\001\022\024\n\020SLICESTATUS_INIT\020\002\022\026\n\022SLICES" +
+      "TATUS_ACTIVE\020\003\022\026\n\022SLICESTATUS_DEINIT\020\004\022\034" +
+      "\n\030SLICESTATUS_SLA_VIOLATED\020\005*]\n\020ConfigAc" +
+      "tionEnum\022\032\n\026CONFIGACTION_UNDEFINED\020\000\022\024\n\020" +
+      "CONFIGACTION_SET\020\001\022\027\n\023CONFIGACTION_DELET" +
+      "E\020\002*\203\002\n\022IsolationLevelEnum\022\020\n\014NO_ISOLATI" +
+      "ON\020\000\022\026\n\022PHYSICAL_ISOLATION\020\001\022\025\n\021LOGICAL_" +
+      "ISOLATION\020\002\022\025\n\021PROCESS_ISOLATION\020\003\022\035\n\031PH" +
+      "YSICAL_MEMORY_ISOLATION\020\004\022\036\n\032PHYSICAL_NE" +
+      "TWORK_ISOLATION\020\005\022\036\n\032VIRTUAL_RESOURCE_IS" +
+      "OLATION\020\006\022\037\n\033NETWORK_FUNCTIONS_ISOLATION" +
+      "\020\007\022\025\n\021SERVICE_ISOLATION\020\0102\331\023\n\016ContextSer" +
+      "vice\022:\n\016ListContextIds\022\016.context.Empty\032\026" +
+      ".context.ContextIdList\"\000\0226\n\014ListContexts" +
+      "\022\016.context.Empty\032\024.context.ContextList\"\000" +
+      "\0224\n\nGetContext\022\022.context.ContextId\032\020.con" +
+      "text.Context\"\000\0224\n\nSetContext\022\020.context.C" +
+      "ontext\032\022.context.ContextId\"\000\0225\n\rRemoveCo" +
+      "ntext\022\022.context.ContextId\032\016.context.Empt" +
+      "y\"\000\022=\n\020GetContextEvents\022\016.context.Empty\032" +
+      "\025.context.ContextEvent\"\0000\001\022@\n\017ListTopolo" +
+      "gyIds\022\022.context.ContextId\032\027.context.Topo" +
+      "logyIdList\"\000\022=\n\016ListTopologies\022\022.context" +
+      ".ContextId\032\025.context.TopologyList\"\000\0227\n\013G" +
+      "etTopology\022\023.context.TopologyId\032\021.contex" +
+      "t.Topology\"\000\0227\n\013SetTopology\022\021.context.To" +
+      "pology\032\023.context.TopologyId\"\000\0227\n\016RemoveT" +
+      "opology\022\023.context.TopologyId\032\016.context.E" +
+      "mpty\"\000\022?\n\021GetTopologyEvents\022\016.context.Em" +
+      "pty\032\026.context.TopologyEvent\"\0000\001\0228\n\rListD" +
+      "eviceIds\022\016.context.Empty\032\025.context.Devic" +
+      "eIdList\"\000\0224\n\013ListDevices\022\016.context.Empty" +
+      "\032\023.context.DeviceList\"\000\0221\n\tGetDevice\022\021.c" +
+      "ontext.DeviceId\032\017.context.Device\"\000\0221\n\tSe" +
+      "tDevice\022\017.context.Device\032\021.context.Devic" +
+      "eId\"\000\0223\n\014RemoveDevice\022\021.context.DeviceId" +
+      "\032\016.context.Empty\"\000\022;\n\017GetDeviceEvents\022\016." +
+      "context.Empty\032\024.context.DeviceEvent\"\0000\001\022" +
+      "4\n\013ListLinkIds\022\016.context.Empty\032\023.context" +
+      ".LinkIdList\"\000\0220\n\tListLinks\022\016.context.Emp" +
+      "ty\032\021.context.LinkList\"\000\022+\n\007GetLink\022\017.con" +
+      "text.LinkId\032\r.context.Link\"\000\022+\n\007SetLink\022" +
+      "\r.context.Link\032\017.context.LinkId\"\000\022/\n\nRem" +
+      "oveLink\022\017.context.LinkId\032\016.context.Empty" +
+      "\"\000\0227\n\rGetLinkEvents\022\016.context.Empty\032\022.co" +
+      "ntext.LinkEvent\"\0000\001\022>\n\016ListServiceIds\022\022." +
+      "context.ContextId\032\026.context.ServiceIdLis" +
+      "t\"\000\022:\n\014ListServices\022\022.context.ContextId\032" +
+      "\024.context.ServiceList\"\000\0224\n\nGetService\022\022." +
+      "context.ServiceId\032\020.context.Service\"\000\0224\n" +
+      "\nSetService\022\020.context.Service\032\022.context." +
+      "ServiceId\"\000\0226\n\014UnsetService\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\022:\n\014ListSliceId" +
+      "s\022\022.context.ContextId\032\024.context.SliceIdL" +
+      "ist\"\000\0226\n\nListSlices\022\022.context.ContextId\032" +
+      "\022.context.SliceList\"\000\022.\n\010GetSlice\022\020.cont" +
+      "ext.SliceId\032\016.context.Slice\"\000\022.\n\010SetSlic" +
+      "e\022\016.context.Slice\032\020.context.SliceId\"\000\0220\n" +
+      "\nUnsetSlice\022\016.context.Slice\032\020.context.Sl" +
+      "iceId\"\000\0221\n\013RemoveSlice\022\020.context.SliceId" +
+      "\032\016.context.Empty\"\000\0229\n\016GetSliceEvents\022\016.c" +
+      "ontext.Empty\032\023.context.SliceEvent\"\0000\001\022D\n" +
+      "\021ListConnectionIds\022\022.context.ServiceId\032\031" +
+      ".context.ConnectionIdList\"\000\022@\n\017ListConne" +
+      "ctions\022\022.context.ServiceId\032\027.context.Con" +
+      "nectionList\"\000\022=\n\rGetConnection\022\025.context" +
+      ".ConnectionId\032\023.context.Connection\"\000\022=\n\r" +
+      "SetConnection\022\023.context.Connection\032\025.con" +
+      "text.ConnectionId\"\000\022;\n\020RemoveConnection\022" +
+      "\025.context.ConnectionId\032\016.context.Empty\"\000" +
+      "\022C\n\023GetConnectionEvents\022\016.context.Empty\032" +
+      "\030.context.ConnectionEvent\"\0000\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -62341,7 +62547,7 @@ public final class ContextOuterClass {
     internal_static_context_DeviceEvent_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_DeviceEvent_descriptor,
-        new java.lang.String[] { "Event", "DeviceId", });
+        new java.lang.String[] { "Event", "DeviceId", "DeviceConfig", });
     internal_static_context_LinkId_descriptor =
       getDescriptor().getMessageTypes().get(20);
     internal_static_context_LinkId_fieldAccessorTable = new
diff --git a/src/automation/target/generated-sources/grpc/context/ContextService.java b/src/automation/target/generated-sources/grpc/context/ContextService.java
index d54c56057ca53e40071490d3b9aa313a13a77665..814ea98b65370f8fd3ffd752c77bec04997a5dd6 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextService.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextService.java
@@ -56,6 +56,8 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> setService(context.ContextOuterClass.Service request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request);
+    
     io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request);
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request);
@@ -66,6 +68,8 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(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);
diff --git a/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java b/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java
index f552294b8e6d645af41cc30632ae0432504bbc67..2b0099f106265e34d1f60bb3e0ecdc35f81895ee 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java
@@ -208,6 +208,14 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+       try {
+         return delegate.unsetService(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
        try {
          return delegate.removeService(request);
@@ -248,6 +256,14 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
+       try {
+         return delegate.unsetSlice(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);
diff --git a/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java b/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java
index c6493bd4d381967238e5eb87dd717f679d028526..c518a0b4622522728e0eb22fdbeb80442b10f7ef 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java
@@ -117,6 +117,10 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.setService(request);
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+       return stub.unsetService(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
        return stub.removeService(request);
     }
@@ -137,6 +141,10 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.setSlice(request);
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
+       return stub.unsetSlice(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
        return stub.removeSlice(request);
     }
diff --git a/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java b/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java
index be720c127439e50f68c2518332f85f750d6579ee..f59378086c84d0776cc25fb7aa9640403b072c0f 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java
@@ -882,6 +882,37 @@ public final class ContextServiceGrpc {
     return getSetServiceMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
+      context.ContextOuterClass.ServiceId> getUnsetServiceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "UnsetService",
+      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> getUnsetServiceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId> getUnsetServiceMethod;
+    if ((getUnsetServiceMethod = ContextServiceGrpc.getUnsetServiceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getUnsetServiceMethod = ContextServiceGrpc.getUnsetServiceMethod) == null) {
+          ContextServiceGrpc.getUnsetServiceMethod = getUnsetServiceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "UnsetService"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Service.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ServiceId.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("UnsetService"))
+              .build();
+        }
+      }
+    }
+    return getUnsetServiceMethod;
+  }
+
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
       context.ContextOuterClass.Empty> getRemoveServiceMethod;
 
@@ -1068,6 +1099,37 @@ public final class ContextServiceGrpc {
     return getSetSliceMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
+      context.ContextOuterClass.SliceId> getUnsetSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "UnsetSlice",
+      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> getUnsetSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId> getUnsetSliceMethod;
+    if ((getUnsetSliceMethod = ContextServiceGrpc.getUnsetSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getUnsetSliceMethod = ContextServiceGrpc.getUnsetSliceMethod) == null) {
+          ContextServiceGrpc.getUnsetSliceMethod = getUnsetSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "UnsetSlice"))
+              .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("UnsetSlice"))
+              .build();
+        }
+      }
+    }
+    return getUnsetSliceMethod;
+  }
+
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
       context.ContextOuterClass.Empty> getRemoveSliceMethod;
 
@@ -1560,6 +1622,13 @@ public final class ContextServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetServiceMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void unsetService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsetServiceMethod(), responseObserver);
+    }
+
     /**
      */
     public void removeService(context.ContextOuterClass.ServiceId request,
@@ -1602,6 +1671,13 @@ public final class ContextServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetSliceMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void unsetSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsetSliceMethod(), responseObserver);
+    }
+
     /**
      */
     public void removeSlice(context.ContextOuterClass.SliceId request,
@@ -1856,6 +1932,13 @@ public final class ContextServiceGrpc {
                 context.ContextOuterClass.Service,
                 context.ContextOuterClass.ServiceId>(
                   this, METHODID_SET_SERVICE)))
+          .addMethod(
+            getUnsetServiceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Service,
+                context.ContextOuterClass.ServiceId>(
+                  this, METHODID_UNSET_SERVICE)))
           .addMethod(
             getRemoveServiceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -1898,6 +1981,13 @@ public final class ContextServiceGrpc {
                 context.ContextOuterClass.Slice,
                 context.ContextOuterClass.SliceId>(
                   this, METHODID_SET_SLICE)))
+          .addMethod(
+            getUnsetSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Slice,
+                context.ContextOuterClass.SliceId>(
+                  this, METHODID_UNSET_SLICE)))
           .addMethod(
             getRemoveSliceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -2196,6 +2286,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetServiceMethod(), getCallOptions()), request, responseObserver);
     }
 
+    /**
+     */
+    public void unsetService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getUnsetServiceMethod(), getCallOptions()), request, responseObserver);
+    }
+
     /**
      */
     public void removeService(context.ContextOuterClass.ServiceId request,
@@ -2244,6 +2342,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetSliceMethod(), getCallOptions()), request, responseObserver);
     }
 
+    /**
+     */
+    public void unsetSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getUnsetSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
     /**
      */
     public void removeSlice(context.ContextOuterClass.SliceId request,
@@ -2523,6 +2629,13 @@ public final class ContextServiceGrpc {
           getChannel(), getSetServiceMethod(), getCallOptions(), request);
     }
 
+    /**
+     */
+    public context.ContextOuterClass.ServiceId unsetService(context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getUnsetServiceMethod(), getCallOptions(), request);
+    }
+
     /**
      */
     public context.ContextOuterClass.Empty removeService(context.ContextOuterClass.ServiceId request) {
@@ -2566,6 +2679,13 @@ public final class ContextServiceGrpc {
           getChannel(), getSetSliceMethod(), getCallOptions(), request);
     }
 
+    /**
+     */
+    public context.ContextOuterClass.SliceId unsetSlice(context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getUnsetSliceMethod(), getCallOptions(), request);
+    }
+
     /**
      */
     public context.ContextOuterClass.Empty removeSlice(context.ContextOuterClass.SliceId request) {
@@ -2831,6 +2951,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetServiceMethod(), getCallOptions()), request);
     }
 
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ServiceId> unsetService(
+        context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getUnsetServiceMethod(), getCallOptions()), request);
+    }
+
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeService(
@@ -2871,6 +2999,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetSliceMethod(), getCallOptions()), request);
     }
 
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceId> unsetSlice(
+        context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getUnsetSliceMethod(), getCallOptions()), request);
+    }
+
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeSlice(
@@ -2948,20 +3084,22 @@ public final class ContextServiceGrpc {
   private static final int METHODID_LIST_SERVICES = 25;
   private static final int METHODID_GET_SERVICE = 26;
   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_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 int METHODID_UNSET_SERVICE = 28;
+  private static final int METHODID_REMOVE_SERVICE = 29;
+  private static final int METHODID_GET_SERVICE_EVENTS = 30;
+  private static final int METHODID_LIST_SLICE_IDS = 31;
+  private static final int METHODID_LIST_SLICES = 32;
+  private static final int METHODID_GET_SLICE = 33;
+  private static final int METHODID_SET_SLICE = 34;
+  private static final int METHODID_UNSET_SLICE = 35;
+  private static final int METHODID_REMOVE_SLICE = 36;
+  private static final int METHODID_GET_SLICE_EVENTS = 37;
+  private static final int METHODID_LIST_CONNECTION_IDS = 38;
+  private static final int METHODID_LIST_CONNECTIONS = 39;
+  private static final int METHODID_GET_CONNECTION = 40;
+  private static final int METHODID_SET_CONNECTION = 41;
+  private static final int METHODID_REMOVE_CONNECTION = 42;
+  private static final int METHODID_GET_CONNECTION_EVENTS = 43;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -3092,6 +3230,10 @@ public final class ContextServiceGrpc {
           serviceImpl.setService((context.ContextOuterClass.Service) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
           break;
+        case METHODID_UNSET_SERVICE:
+          serviceImpl.unsetService((context.ContextOuterClass.Service) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
+          break;
         case METHODID_REMOVE_SERVICE:
           serviceImpl.removeService((context.ContextOuterClass.ServiceId) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
@@ -3116,6 +3258,10 @@ public final class ContextServiceGrpc {
           serviceImpl.setSlice((context.ContextOuterClass.Slice) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver);
           break;
+        case METHODID_UNSET_SLICE:
+          serviceImpl.unsetSlice((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);
@@ -3237,12 +3383,14 @@ public final class ContextServiceGrpc {
               .addMethod(getListServicesMethod())
               .addMethod(getGetServiceMethod())
               .addMethod(getSetServiceMethod())
+              .addMethod(getUnsetServiceMethod())
               .addMethod(getRemoveServiceMethod())
               .addMethod(getGetServiceEventsMethod())
               .addMethod(getListSliceIdsMethod())
               .addMethod(getListSlicesMethod())
               .addMethod(getGetSliceMethod())
               .addMethod(getSetSliceMethod())
+              .addMethod(getUnsetSliceMethod())
               .addMethod(getRemoveSliceMethod())
               .addMethod(getGetSliceEventsMethod())
               .addMethod(getListConnectionIdsMethod())
diff --git a/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java b/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
index 9f71b53786e40922546dc59cfd4328040a40bd7c..f7d2cb94e339366b54355c7e11b3ee72fa1e415c 100644
--- a/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
@@ -156,6 +156,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::unsetService);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeService);
         }
@@ -181,6 +186,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::unsetSlice);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeSlice);
         }
@@ -383,6 +393,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
@@ -408,6 +423,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(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);
         }
@@ -670,6 +690,13 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                                             context.ContextOuterClass.Service,
                                             context.ContextOuterClass.ServiceId>(
                                             this, METHODID_SET_SERVICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getUnsetServiceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Service,
+                                            context.ContextOuterClass.ServiceId>(
+                                            this, METHODID_UNSET_SERVICE, compression)))
                     .addMethod(
                             context.ContextServiceGrpc.getRemoveServiceMethod(),
                             asyncUnaryCall(
@@ -712,6 +739,13 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                                             context.ContextOuterClass.Slice,
                                             context.ContextOuterClass.SliceId>(
                                             this, METHODID_SET_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getUnsetSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Slice,
+                                            context.ContextOuterClass.SliceId>(
+                                            this, METHODID_UNSET_SLICE, compression)))
                     .addMethod(
                             context.ContextServiceGrpc.getRemoveSliceMethod(),
                             asyncUnaryCall(
@@ -800,20 +834,22 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
     private static final int METHODID_LIST_SERVICES = 25;
     private static final int METHODID_GET_SERVICE = 26;
     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_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 int METHODID_UNSET_SERVICE = 28;
+    private static final int METHODID_REMOVE_SERVICE = 29;
+    private static final int METHODID_GET_SERVICE_EVENTS = 30;
+    private static final int METHODID_LIST_SLICE_IDS = 31;
+    private static final int METHODID_LIST_SLICES = 32;
+    private static final int METHODID_GET_SLICE = 33;
+    private static final int METHODID_SET_SLICE = 34;
+    private static final int METHODID_UNSET_SLICE = 35;
+    private static final int METHODID_REMOVE_SLICE = 36;
+    private static final int METHODID_GET_SLICE_EVENTS = 37;
+    private static final int METHODID_LIST_CONNECTION_IDS = 38;
+    private static final int METHODID_LIST_CONNECTIONS = 39;
+    private static final int METHODID_GET_CONNECTION = 40;
+    private static final int METHODID_SET_CONNECTION = 41;
+    private static final int METHODID_REMOVE_CONNECTION = 42;
+    private static final int METHODID_GET_CONNECTION_EVENTS = 43;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -1002,6 +1038,12 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                             compression,
                             serviceImpl::setService);
                     break;
+                case METHODID_UNSET_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Service) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver,
+                            compression,
+                            serviceImpl::unsetService);
+                    break;
                 case METHODID_REMOVE_SERVICE:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
@@ -1038,6 +1080,12 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                             compression,
                             serviceImpl::setSlice);
                     break;
+                case METHODID_UNSET_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Slice) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver,
+                            compression,
+                            serviceImpl::unsetSlice);
+                    break;
                 case METHODID_REMOVE_SLICE:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
diff --git a/src/automation/target/generated-sources/grpc/monitoring/Monitoring.java b/src/automation/target/generated-sources/grpc/monitoring/Monitoring.java
index 5d63d4aa45e578957a7a3414c33491cebe98acbe..9d05f3da8a831e74922e65473206539680c8d78b 100644
--- a/src/automation/target/generated-sources/grpc/monitoring/Monitoring.java
+++ b/src/automation/target/generated-sources/grpc/monitoring/Monitoring.java
@@ -19,85 +19,124 @@ public final class Monitoring {
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>string kpi_description = 1;</code>
+     * <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 kpi_description = 2;</code>
      * @return The kpiDescription.
      */
     java.lang.String getKpiDescription();
     /**
-     * <code>string kpi_description = 1;</code>
+     * <code>string kpi_description = 2;</code>
      * @return The bytes for kpiDescription.
      */
     com.google.protobuf.ByteString
         getKpiDescriptionBytes();
 
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiId> 
+        getKpiIdListList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    monitoring.Monitoring.KpiId getKpiIdList(int index);
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    int getKpiIdListCount();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdListOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+        int index);
+
+    /**
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
      * @return The enum numeric value on the wire for kpiSampleType.
      */
     int getKpiSampleTypeValue();
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
      * @return The kpiSampleType.
      */
     kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
 
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return Whether the deviceId field is set.
      */
     boolean hasDeviceId();
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return The deviceId.
      */
     context.ContextOuterClass.DeviceId getDeviceId();
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      */
     context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
 
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return Whether the endpointId field is set.
      */
     boolean hasEndpointId();
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return The endpointId.
      */
     context.ContextOuterClass.EndPointId getEndpointId();
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      */
     context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
 
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return Whether the serviceId field is set.
      */
     boolean hasServiceId();
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return The serviceId.
      */
     context.ContextOuterClass.ServiceId getServiceId();
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      */
     context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
 
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return Whether the sliceId field is set.
      */
     boolean hasSliceId();
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return The sliceId.
      */
     context.ContextOuterClass.SliceId getSliceId();
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      */
     context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
   }
@@ -115,6 +154,7 @@ public final class Monitoring {
     }
     private KpiDescriptor() {
       kpiDescription_ = "";
+      kpiIdList_ = java.util.Collections.emptyList();
       kpiSampleType_ = 0;
     }
 
@@ -138,6 +178,7 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -149,18 +190,40 @@ public final class Monitoring {
               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();
 
               kpiDescription_ = s;
               break;
             }
-            case 16: {
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              kpiIdList_.add(
+                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
+              break;
+            }
+            case 32: {
               int rawValue = input.readEnum();
 
               kpiSampleType_ = rawValue;
               break;
             }
-            case 26: {
+            case 42: {
               context.ContextOuterClass.DeviceId.Builder subBuilder = null;
               if (deviceId_ != null) {
                 subBuilder = deviceId_.toBuilder();
@@ -173,7 +236,7 @@ public final class Monitoring {
 
               break;
             }
-            case 34: {
+            case 50: {
               context.ContextOuterClass.EndPointId.Builder subBuilder = null;
               if (endpointId_ != null) {
                 subBuilder = endpointId_.toBuilder();
@@ -186,7 +249,7 @@ public final class Monitoring {
 
               break;
             }
-            case 42: {
+            case 58: {
               context.ContextOuterClass.ServiceId.Builder subBuilder = null;
               if (serviceId_ != null) {
                 subBuilder = serviceId_.toBuilder();
@@ -199,7 +262,7 @@ public final class Monitoring {
 
               break;
             }
-            case 50: {
+            case 66: {
               context.ContextOuterClass.SliceId.Builder subBuilder = null;
               if (sliceId_ != null) {
                 subBuilder = sliceId_.toBuilder();
@@ -227,6 +290,9 @@ public final class Monitoring {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
@@ -244,10 +310,36 @@ public final class Monitoring {
               monitoring.Monitoring.KpiDescriptor.class, monitoring.Monitoring.KpiDescriptor.Builder.class);
     }
 
-    public static final int KPI_DESCRIPTION_FIELD_NUMBER = 1;
+    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 KPI_DESCRIPTION_FIELD_NUMBER = 2;
     private volatile java.lang.Object kpiDescription_;
     /**
-     * <code>string kpi_description = 1;</code>
+     * <code>string kpi_description = 2;</code>
      * @return The kpiDescription.
      */
     @java.lang.Override
@@ -264,7 +356,7 @@ public final class Monitoring {
       }
     }
     /**
-     * <code>string kpi_description = 1;</code>
+     * <code>string kpi_description = 2;</code>
      * @return The bytes for kpiDescription.
      */
     @java.lang.Override
@@ -282,17 +374,57 @@ public final class Monitoring {
       }
     }
 
-    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 2;
+    public static final int KPI_ID_LIST_FIELD_NUMBER = 3;
+    private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_;
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
+      return kpiIdList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdListOrBuilderList() {
+      return kpiIdList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public int getKpiIdListCount() {
+      return kpiIdList_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiIdList(int index) {
+      return kpiIdList_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+        int index) {
+      return kpiIdList_.get(index);
+    }
+
+    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 4;
     private int kpiSampleType_;
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</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>
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
      * @return The kpiSampleType.
      */
     @java.lang.Override public kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType() {
@@ -301,10 +433,10 @@ public final class Monitoring {
       return result == null ? kpi_sample_types.KpiSampleTypes.KpiSampleType.UNRECOGNIZED : result;
     }
 
-    public static final int DEVICE_ID_FIELD_NUMBER = 3;
+    public static final int DEVICE_ID_FIELD_NUMBER = 5;
     private context.ContextOuterClass.DeviceId deviceId_;
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return Whether the deviceId field is set.
      */
     @java.lang.Override
@@ -312,7 +444,7 @@ public final class Monitoring {
       return deviceId_ != null;
     }
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return The deviceId.
      */
     @java.lang.Override
@@ -320,17 +452,17 @@ public final class Monitoring {
       return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
     }
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
       return getDeviceId();
     }
 
-    public static final int ENDPOINT_ID_FIELD_NUMBER = 4;
+    public static final int ENDPOINT_ID_FIELD_NUMBER = 6;
     private context.ContextOuterClass.EndPointId endpointId_;
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return Whether the endpointId field is set.
      */
     @java.lang.Override
@@ -338,7 +470,7 @@ public final class Monitoring {
       return endpointId_ != null;
     }
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return The endpointId.
      */
     @java.lang.Override
@@ -346,17 +478,17 @@ public final class Monitoring {
       return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
     }
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
       return getEndpointId();
     }
 
-    public static final int SERVICE_ID_FIELD_NUMBER = 5;
+    public static final int SERVICE_ID_FIELD_NUMBER = 7;
     private context.ContextOuterClass.ServiceId serviceId_;
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return Whether the serviceId field is set.
      */
     @java.lang.Override
@@ -364,7 +496,7 @@ public final class Monitoring {
       return serviceId_ != null;
     }
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return The serviceId.
      */
     @java.lang.Override
@@ -372,17 +504,17 @@ public final class Monitoring {
       return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
     }
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
       return getServiceId();
     }
 
-    public static final int SLICE_ID_FIELD_NUMBER = 6;
+    public static final int SLICE_ID_FIELD_NUMBER = 8;
     private context.ContextOuterClass.SliceId sliceId_;
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return Whether the sliceId field is set.
      */
     @java.lang.Override
@@ -390,7 +522,7 @@ public final class Monitoring {
       return sliceId_ != null;
     }
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return The sliceId.
      */
     @java.lang.Override
@@ -398,7 +530,7 @@ public final class Monitoring {
       return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
     }
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
@@ -419,23 +551,29 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
+      }
       if (!getKpiDescriptionBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, kpiDescription_);
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, kpiDescription_);
+      }
+      for (int i = 0; i < kpiIdList_.size(); i++) {
+        output.writeMessage(3, kpiIdList_.get(i));
       }
       if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        output.writeEnum(2, kpiSampleType_);
+        output.writeEnum(4, kpiSampleType_);
       }
       if (deviceId_ != null) {
-        output.writeMessage(3, getDeviceId());
+        output.writeMessage(5, getDeviceId());
       }
       if (endpointId_ != null) {
-        output.writeMessage(4, getEndpointId());
+        output.writeMessage(6, getEndpointId());
       }
       if (serviceId_ != null) {
-        output.writeMessage(5, getServiceId());
+        output.writeMessage(7, getServiceId());
       }
       if (sliceId_ != null) {
-        output.writeMessage(6, getSliceId());
+        output.writeMessage(8, getSliceId());
       }
       unknownFields.writeTo(output);
     }
@@ -446,28 +584,36 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
+      }
       if (!getKpiDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, kpiDescription_);
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, kpiDescription_);
+      }
+      for (int i = 0; i < kpiIdList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, kpiIdList_.get(i));
       }
       if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(2, kpiSampleType_);
+          .computeEnumSize(4, kpiSampleType_);
       }
       if (deviceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getDeviceId());
+          .computeMessageSize(5, getDeviceId());
       }
       if (endpointId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getEndpointId());
+          .computeMessageSize(6, getEndpointId());
       }
       if (serviceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getServiceId());
+          .computeMessageSize(7, getServiceId());
       }
       if (sliceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, getSliceId());
+          .computeMessageSize(8, getSliceId());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -484,8 +630,15 @@ public final class Monitoring {
       }
       monitoring.Monitoring.KpiDescriptor other = (monitoring.Monitoring.KpiDescriptor) obj;
 
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
+      }
       if (!getKpiDescription()
           .equals(other.getKpiDescription())) return false;
+      if (!getKpiIdListList()
+          .equals(other.getKpiIdListList())) return false;
       if (kpiSampleType_ != other.kpiSampleType_) return false;
       if (hasDeviceId() != other.hasDeviceId()) return false;
       if (hasDeviceId()) {
@@ -518,8 +671,16 @@ public final class Monitoring {
       }
       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) + KPI_DESCRIPTION_FIELD_NUMBER;
       hash = (53 * hash) + getKpiDescription().hashCode();
+      if (getKpiIdListCount() > 0) {
+        hash = (37 * hash) + KPI_ID_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiIdListList().hashCode();
+      }
       hash = (37 * hash) + KPI_SAMPLE_TYPE_FIELD_NUMBER;
       hash = (53 * hash) + kpiSampleType_;
       if (hasDeviceId()) {
@@ -666,13 +827,26 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getKpiIdListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
         kpiDescription_ = "";
 
+        if (kpiIdListBuilder_ == null) {
+          kpiIdList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          kpiIdListBuilder_.clear();
+        }
         kpiSampleType_ = 0;
 
         if (deviceIdBuilder_ == null) {
@@ -725,7 +899,22 @@ public final class Monitoring {
       @java.lang.Override
       public monitoring.Monitoring.KpiDescriptor buildPartial() {
         monitoring.Monitoring.KpiDescriptor result = new monitoring.Monitoring.KpiDescriptor(this);
+        int from_bitField0_ = bitField0_;
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
         result.kpiDescription_ = kpiDescription_;
+        if (kpiIdListBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.kpiIdList_ = kpiIdList_;
+        } else {
+          result.kpiIdList_ = kpiIdListBuilder_.build();
+        }
         result.kpiSampleType_ = kpiSampleType_;
         if (deviceIdBuilder_ == null) {
           result.deviceId_ = deviceId_;
@@ -795,14 +984,43 @@ public final class Monitoring {
 
       public Builder mergeFrom(monitoring.Monitoring.KpiDescriptor other) {
         if (other == monitoring.Monitoring.KpiDescriptor.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
         if (!other.getKpiDescription().isEmpty()) {
           kpiDescription_ = other.kpiDescription_;
           onChanged();
         }
-        if (other.kpiSampleType_ != 0) {
-          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
-        }
-        if (other.hasDeviceId()) {
+        if (kpiIdListBuilder_ == null) {
+          if (!other.kpiIdList_.isEmpty()) {
+            if (kpiIdList_.isEmpty()) {
+              kpiIdList_ = other.kpiIdList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiIdListIsMutable();
+              kpiIdList_.addAll(other.kpiIdList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.kpiIdList_.isEmpty()) {
+            if (kpiIdListBuilder_.isEmpty()) {
+              kpiIdListBuilder_.dispose();
+              kpiIdListBuilder_ = null;
+              kpiIdList_ = other.kpiIdList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiIdListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiIdListFieldBuilder() : null;
+            } else {
+              kpiIdListBuilder_.addAllMessages(other.kpiIdList_);
+            }
+          }
+        }
+        if (other.kpiSampleType_ != 0) {
+          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
+        }
+        if (other.hasDeviceId()) {
           mergeDeviceId(other.getDeviceId());
         }
         if (other.hasEndpointId()) {
@@ -842,10 +1060,130 @@ public final class Monitoring {
         }
         return this;
       }
+      private int bitField0_;
+
+      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 kpiDescription_ = "";
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @return The kpiDescription.
        */
       public java.lang.String getKpiDescription() {
@@ -861,7 +1199,7 @@ public final class Monitoring {
         }
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @return The bytes for kpiDescription.
        */
       public com.google.protobuf.ByteString
@@ -878,7 +1216,7 @@ public final class Monitoring {
         }
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @param value The kpiDescription to set.
        * @return This builder for chaining.
        */
@@ -893,7 +1231,7 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @return This builder for chaining.
        */
       public Builder clearKpiDescription() {
@@ -903,7 +1241,7 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @param value The bytes for kpiDescription to set.
        * @return This builder for chaining.
        */
@@ -919,548 +1257,788 @@ public final class Monitoring {
         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;
+      private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiIdListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiIdList_);
+          bitField0_ |= 0x00000001;
+         }
       }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdListBuilder_;
+
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
-       * @param value The kpiSampleType to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setKpiSampleType(kpi_sample_types.KpiSampleTypes.KpiSampleType value) {
-        if (value == null) {
-          throw new NullPointerException();
+      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
+        if (kpiIdListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiIdList_);
+        } else {
+          return kpiIdListBuilder_.getMessageList();
         }
-        
-        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.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public boolean hasDeviceId() {
-        return deviceIdBuilder_ != null || deviceId_ != null;
+      public int getKpiIdListCount() {
+        if (kpiIdListBuilder_ == null) {
+          return kpiIdList_.size();
+        } else {
+          return kpiIdListBuilder_.getCount();
+        }
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
-       * @return The deviceId.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.DeviceId getDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+      public monitoring.Monitoring.KpiId getKpiIdList(int index) {
+        if (kpiIdListBuilder_ == null) {
+          return kpiIdList_.get(index);
         } else {
-          return deviceIdBuilder_.getMessage();
+          return kpiIdListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setDeviceId(context.ContextOuterClass.DeviceId value) {
-        if (deviceIdBuilder_ == null) {
+      public Builder setKpiIdList(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          deviceId_ = value;
+          ensureKpiIdListIsMutable();
+          kpiIdList_.set(index, value);
           onChanged();
         } else {
-          deviceIdBuilder_.setMessage(value);
+          kpiIdListBuilder_.setMessage(index, value);
         }
-
         return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setDeviceId(
-          context.ContextOuterClass.DeviceId.Builder builderForValue) {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = builderForValue.build();
+      public Builder setKpiIdList(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          deviceIdBuilder_.setMessage(builderForValue.build());
+          kpiIdListBuilder_.setMessage(index, builderForValue.build());
         }
-
         return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 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;
+      public Builder addKpiIdList(monitoring.Monitoring.KpiId value) {
+        if (kpiIdListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(value);
           onChanged();
         } else {
-          deviceIdBuilder_.mergeFrom(value);
+          kpiIdListBuilder_.addMessage(value);
         }
-
         return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder clearDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = null;
+      public Builder addKpiIdList(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(index, value);
           onChanged();
         } else {
-          deviceId_ = null;
-          deviceIdBuilder_ = null;
+          kpiIdListBuilder_.addMessage(index, value);
         }
-
         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>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
-        if (deviceIdBuilder_ != null) {
-          return deviceIdBuilder_.getMessageOrBuilder();
+      public Builder addKpiIdList(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(builderForValue.build());
+          onChanged();
         } else {
-          return deviceId_ == null ?
-              context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+          kpiIdListBuilder_.addMessage(builderForValue.build());
         }
+        return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 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;
+      public Builder addKpiIdList(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdListBuilder_.addMessage(index, builderForValue.build());
         }
-        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;
+        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
-       * @return The endpointId.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.EndPointId getEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+      public Builder addAllKpiIdList(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiIdList_);
+          onChanged();
         } else {
-          return endpointIdBuilder_.getMessage();
+          kpiIdListBuilder_.addAllMessages(values);
         }
+        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
-        if (endpointIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          endpointId_ = value;
+      public Builder clearKpiIdList() {
+        if (kpiIdListBuilder_ == null) {
+          kpiIdList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          endpointIdBuilder_.setMessage(value);
+          kpiIdListBuilder_.clear();
         }
-
         return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setEndpointId(
-          context.ContextOuterClass.EndPointId.Builder builderForValue) {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = builderForValue.build();
+      public Builder removeKpiIdList(int index) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.remove(index);
           onChanged();
         } else {
-          endpointIdBuilder_.setMessage(builderForValue.build());
+          kpiIdListBuilder_.remove(index);
         }
-
         return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</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);
+      public monitoring.Monitoring.KpiId.Builder getKpiIdListBuilder(
+          int index) {
+        return getKpiIdListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+          int index) {
+        if (kpiIdListBuilder_ == null) {
+          return kpiIdList_.get(index);  } else {
+          return kpiIdListBuilder_.getMessageOrBuilder(index);
         }
-
-        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder clearEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = null;
-          onChanged();
+      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+           getKpiIdListOrBuilderList() {
+        if (kpiIdListBuilder_ != null) {
+          return kpiIdListBuilder_.getMessageOrBuilderList();
         } else {
-          endpointId_ = null;
-          endpointIdBuilder_ = null;
+          return java.util.Collections.unmodifiableList(kpiIdList_);
         }
-
-        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
-        
-        onChanged();
-        return getEndpointIdFieldBuilder().getBuilder();
+      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder() {
+        return getKpiIdListFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiId.getDefaultInstance());
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
-        if (endpointIdBuilder_ != null) {
-          return endpointIdBuilder_.getMessageOrBuilder();
-        } else {
-          return endpointId_ == null ?
-              context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
-        }
+      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder(
+          int index) {
+        return getKpiIdListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiId.getDefaultInstance());
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</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(),
+      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
+           getKpiIdListBuilderList() {
+        return getKpiIdListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdListFieldBuilder() {
+        if (kpiIdListBuilder_ == null) {
+          kpiIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  kpiIdList_,
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          endpointId_ = null;
+          kpiIdList_ = null;
         }
-        return endpointIdBuilder_;
+        return kpiIdListBuilder_;
       }
 
-      private context.ContextOuterClass.ServiceId serviceId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
+      private int kpiSampleType_ = 0;
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
-       * @return Whether the serviceId field is set.
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
+       * @return The enum numeric value on the wire for kpiSampleType.
        */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
+      @java.lang.Override public int getKpiSampleTypeValue() {
+        return kpiSampleType_;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
-       * @return The serviceId.
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
+       * @param value The enum numeric value on the wire for kpiSampleType to set.
+       * @return This builder for chaining.
        */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
-        }
+      public Builder setKpiSampleTypeValue(int value) {
+        
+        kpiSampleType_ = value;
+        onChanged();
+        return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
+       * @return The kpiSampleType.
        */
-      public Builder setServiceId(context.ContextOuterClass.ServiceId value) {
-        if (serviceIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          serviceId_ = value;
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(value);
-        }
+      @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 = 4;</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 = 4;</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 = 5;</code>
+       * @return Whether the deviceId field is set.
+       */
+      public boolean hasDeviceId() {
+        return deviceIdBuilder_ != null || deviceId_ != null;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 5;</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 = 5;</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.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
+      public Builder setDeviceId(
+          context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = builderForValue.build();
           onChanged();
         } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
+          deviceIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_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();
+      public Builder mergeDeviceId(context.ContextOuterClass.DeviceId value) {
+        if (deviceIdBuilder_ == null) {
+          if (deviceId_ != null) {
+            deviceId_ =
+              context.ContextOuterClass.DeviceId.newBuilder(deviceId_).mergeFrom(value).buildPartial();
           } else {
-            serviceId_ = value;
+            deviceId_ = value;
           }
           onChanged();
         } else {
-          serviceIdBuilder_.mergeFrom(value);
+          deviceIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
+      public Builder clearDeviceId() {
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = null;
           onChanged();
         } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
+          deviceId_ = null;
+          deviceIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
         
         onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
+        return getDeviceIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
+        if (deviceIdBuilder_ != null) {
+          return deviceIdBuilder_.getMessageOrBuilder();
         } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+          return deviceId_ == null ?
+              context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
         }
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_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(),
+          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());
-          serviceId_ = null;
+          deviceId_ = null;
         }
-        return serviceIdBuilder_;
+        return deviceIdBuilder_;
       }
 
-      private context.ContextOuterClass.SliceId sliceId_;
+      private context.ContextOuterClass.EndPointId endpointId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdBuilder_;
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> endpointIdBuilder_;
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
-       * @return Whether the sliceId field is set.
+       * <code>.context.EndPointId endpoint_id = 6;</code>
+       * @return Whether the endpointId field is set.
        */
-      public boolean hasSliceId() {
-        return sliceIdBuilder_ != null || sliceId_ != null;
+      public boolean hasEndpointId() {
+        return endpointIdBuilder_ != null || endpointId_ != null;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
-       * @return The sliceId.
+       * <code>.context.EndPointId endpoint_id = 6;</code>
+       * @return The endpointId.
        */
-      public context.ContextOuterClass.SliceId getSliceId() {
-        if (sliceIdBuilder_ == null) {
-          return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+      public context.ContextOuterClass.EndPointId getEndpointId() {
+        if (endpointIdBuilder_ == null) {
+          return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
         } else {
-          return sliceIdBuilder_.getMessage();
+          return endpointIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder setSliceId(context.ContextOuterClass.SliceId value) {
-        if (sliceIdBuilder_ == null) {
+      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
+        if (endpointIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          sliceId_ = value;
+          endpointId_ = value;
           onChanged();
         } else {
-          sliceIdBuilder_.setMessage(value);
+          endpointIdBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder setSliceId(
-          context.ContextOuterClass.SliceId.Builder builderForValue) {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = builderForValue.build();
+      public Builder setEndpointId(
+          context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = builderForValue.build();
           onChanged();
         } else {
-          sliceIdBuilder_.setMessage(builderForValue.build());
+          endpointIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder mergeSliceId(context.ContextOuterClass.SliceId value) {
-        if (sliceIdBuilder_ == null) {
-          if (sliceId_ != null) {
-            sliceId_ =
-              context.ContextOuterClass.SliceId.newBuilder(sliceId_).mergeFrom(value).buildPartial();
+      public Builder mergeEndpointId(context.ContextOuterClass.EndPointId value) {
+        if (endpointIdBuilder_ == null) {
+          if (endpointId_ != null) {
+            endpointId_ =
+              context.ContextOuterClass.EndPointId.newBuilder(endpointId_).mergeFrom(value).buildPartial();
           } else {
-            sliceId_ = value;
+            endpointId_ = value;
           }
           onChanged();
         } else {
-          sliceIdBuilder_.mergeFrom(value);
+          endpointIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder clearSliceId() {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
+      public Builder clearEndpointId() {
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = null;
           onChanged();
         } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
+          endpointId_ = null;
+          endpointIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
         
         onChanged();
-        return getSliceIdFieldBuilder().getBuilder();
+        return getEndpointIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
-        if (sliceIdBuilder_ != null) {
-          return sliceIdBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
+        if (endpointIdBuilder_ != null) {
+          return endpointIdBuilder_.getMessageOrBuilder();
         } else {
-          return sliceId_ == null ?
-              context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+          return endpointId_ == null ?
+              context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
         }
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</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(),
+          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());
-          sliceId_ = null;
+          endpointId_ = null;
         }
-        return sliceIdBuilder_;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+        return endpointIdBuilder_;
       }
 
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      private context.ContextOuterClass.ServiceId serviceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       * @return Whether the serviceId field is set.
+       */
+      public boolean hasServiceId() {
+        return serviceIdBuilder_ != null || serviceId_ != null;
       }
-
-
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       * @return The serviceId.
+       */
+      public context.ContextOuterClass.ServiceId getServiceId() {
+        if (serviceIdBuilder_ == null) {
+          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        } else {
+          return serviceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</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;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public Builder setServiceId(
+          context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          serviceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</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;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public Builder clearServiceId() {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
+          onChanged();
+        } else {
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+        
+        onChanged();
+        return getServiceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+        if (serviceIdBuilder_ != null) {
+          return serviceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return serviceId_ == null ?
+              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        }
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</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_;
+      }
+
+      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 = 8;</code>
+       * @return Whether the sliceId field is set.
+       */
+      public boolean hasSliceId() {
+        return sliceIdBuilder_ != null || sliceId_ != null;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 8;</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 = 8;</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 = 8;</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 = 8;</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 = 8;</code>
+       */
+      public Builder clearSliceId() {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+          onChanged();
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 8;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+        
+        onChanged();
+        return getSliceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceId slice_id = 8;</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 = 8;</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:monitoring.KpiDescriptor)
     }
 
@@ -1501,140 +2079,61 @@ public final class Monitoring {
 
   }
 
-  public interface BundleKpiDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.BundleKpiDescriptor)
+  public interface MonitorKpiRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.MonitorKpiRequest)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>string kpi_description = 1;</code>
-     * @return The kpiDescription.
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
      */
-    java.lang.String getKpiDescription();
+    boolean hasKpiId();
     /**
-     * <code>string kpi_description = 1;</code>
-     * @return The bytes for kpiDescription.
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
      */
-    com.google.protobuf.ByteString
-        getKpiDescriptionBytes();
-
+    monitoring.Monitoring.KpiId getKpiId();
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
-    java.util.List<monitoring.Monitoring.KpiId> 
-        getKpiIdListList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    monitoring.Monitoring.KpiId getKpiIdList(int index);
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    int getKpiIdListCount();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-        int index);
-
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-     * @return The enum numeric value on the wire for kpiSampleType.
-     */
-    int getKpiSampleTypeValue();
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-     * @return The kpiSampleType.
-     */
-    kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
-
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     * @return Whether the deviceId field is set.
-     */
-    boolean hasDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     * @return The deviceId.
-     */
-    context.ContextOuterClass.DeviceId getDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     */
-    context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
-
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     * @return Whether the endpointId field is set.
-     */
-    boolean hasEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     * @return The endpointId.
-     */
-    context.ContextOuterClass.EndPointId getEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     */
-    context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
 
     /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return Whether the serviceId field is set.
-     */
-    boolean hasServiceId();
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return The serviceId.
-     */
-    context.ContextOuterClass.ServiceId getServiceId();
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
-    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+    float getMonitoringWindowS();
 
     /**
-     * <code>.context.SliceId slice_id = 7;</code>
-     * @return Whether the sliceId field is set.
-     */
-    boolean hasSliceId();
-    /**
-     * <code>.context.SliceId slice_id = 7;</code>
-     * @return The sliceId.
-     */
-    context.ContextOuterClass.SliceId getSliceId();
-    /**
-     * <code>.context.SliceId slice_id = 7;</code>
+     * <pre>
+     * Pending add field to reflect Available Device Protocols
+     * </pre>
+     *
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
-    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+    float getSamplingRateS();
   }
   /**
-   * Protobuf type {@code monitoring.BundleKpiDescriptor}
+   * Protobuf type {@code monitoring.MonitorKpiRequest}
    */
-  public static final class BundleKpiDescriptor extends
+  public static final class MonitorKpiRequest extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.BundleKpiDescriptor)
-      BundleKpiDescriptorOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.MonitorKpiRequest)
+      MonitorKpiRequestOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use BundleKpiDescriptor.newBuilder() to construct.
-    private BundleKpiDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use MonitorKpiRequest.newBuilder() to construct.
+    private MonitorKpiRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private BundleKpiDescriptor() {
-      kpiDescription_ = "";
-      kpiIdList_ = java.util.Collections.emptyList();
-      kpiSampleType_ = 0;
+    private MonitorKpiRequest() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new BundleKpiDescriptor();
+      return new MonitorKpiRequest();
     }
 
     @java.lang.Override
@@ -1642,7 +2141,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private BundleKpiDescriptor(
+    private MonitorKpiRequest(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -1650,7 +2149,6 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
-      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -1662,76 +2160,26 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              kpiDescription_ = s;
-              break;
-            }
-            case 18: {
-              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              kpiIdList_.add(
-                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
-              break;
-            }
-            case 24: {
-              int rawValue = input.readEnum();
-
-              kpiSampleType_ = rawValue;
-              break;
-            }
-            case 34: {
-              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 42: {
-              context.ContextOuterClass.EndPointId.Builder subBuilder = null;
-              if (endpointId_ != null) {
-                subBuilder = endpointId_.toBuilder();
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
+              if (kpiId_ != null) {
+                subBuilder = kpiId_.toBuilder();
               }
-              endpointId_ = input.readMessage(context.ContextOuterClass.EndPointId.parser(), extensionRegistry);
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(endpointId_);
-                endpointId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(kpiId_);
+                kpiId_ = subBuilder.buildPartial();
               }
 
               break;
             }
-            case 50: {
-              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();
-              }
+            case 21: {
 
+              monitoringWindowS_ = input.readFloat();
               break;
             }
-            case 58: {
-              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();
-              }
+            case 29: {
 
+              samplingRateS_ = input.readFloat();
               break;
             }
             default: {
@@ -1749,261 +2197,97 @@ public final class Monitoring {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
-        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.BundleKpiDescriptor.class, monitoring.Monitoring.BundleKpiDescriptor.Builder.class);
+              monitoring.Monitoring.MonitorKpiRequest.class, monitoring.Monitoring.MonitorKpiRequest.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;
-      }
-    }
+    public static final int KPI_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiId kpiId_;
     /**
-     * <code>string kpi_description = 1;</code>
-     * @return The bytes for kpiDescription.
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
      */
     @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 boolean hasKpiId() {
+      return kpiId_ != null;
     }
-
-    public static final int KPI_ID_LIST_FIELD_NUMBER = 2;
-    private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_;
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-      return kpiIdList_;
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
     }
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList() {
-      return kpiIdList_;
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
     }
+
+    public static final int MONITORING_WINDOW_S_FIELD_NUMBER = 2;
+    private float monitoringWindowS_;
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
     @java.lang.Override
-    public int getKpiIdListCount() {
-      return kpiIdList_.size();
+    public float getMonitoringWindowS() {
+      return monitoringWindowS_;
     }
+
+    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
+    private float samplingRateS_;
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <pre>
+     * Pending add field to reflect Available Device Protocols
+     * </pre>
+     *
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-      return kpiIdList_.get(index);
+    public float getSamplingRateS() {
+      return samplingRateS_;
     }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
+
+    private byte memoizedIsInitialized = -1;
     @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-        int index) {
-      return kpiIdList_.get(index);
-    }
-
-    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 3;
-    private int kpiSampleType_;
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</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 = 3;</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 = 4;
-    private context.ContextOuterClass.DeviceId deviceId_;
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     * @return Whether the deviceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasDeviceId() {
-      return deviceId_ != null;
-    }
-    /**
-     * <code>.context.DeviceId device_id = 4;</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 = 4;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
-      return getDeviceId();
-    }
-
-    public static final int ENDPOINT_ID_FIELD_NUMBER = 5;
-    private context.ContextOuterClass.EndPointId endpointId_;
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     * @return Whether the endpointId field is set.
-     */
-    @java.lang.Override
-    public boolean hasEndpointId() {
-      return endpointId_ != null;
-    }
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
-      return getEndpointId();
-    }
-
-    public static final int SERVICE_ID_FIELD_NUMBER = 6;
-    private context.ContextOuterClass.ServiceId serviceId_;
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return Whether the serviceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasServiceId() {
-      return serviceId_ != null;
-    }
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return The serviceId.
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.ServiceId getServiceId() {
-      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-    }
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-      return getServiceId();
-    }
-
-    public static final int SLICE_ID_FIELD_NUMBER = 7;
-    private context.ContextOuterClass.SliceId sliceId_;
-    /**
-     * <code>.context.SliceId slice_id = 7;</code>
-     * @return Whether the sliceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasSliceId() {
-      return sliceId_ != null;
-    }
-    /**
-     * <code>.context.SliceId slice_id = 7;</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 = 7;</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;
+    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_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        output.writeMessage(2, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        output.writeEnum(3, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        output.writeMessage(4, getDeviceId());
-      }
-      if (endpointId_ != null) {
-        output.writeMessage(5, getEndpointId());
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
       }
-      if (serviceId_ != null) {
-        output.writeMessage(6, getServiceId());
+      if (monitoringWindowS_ != 0F) {
+        output.writeFloat(2, monitoringWindowS_);
       }
-      if (sliceId_ != null) {
-        output.writeMessage(7, getSliceId());
+      if (samplingRateS_ != 0F) {
+        output.writeFloat(3, samplingRateS_);
       }
       unknownFields.writeTo(output);
     }
@@ -2014,32 +2298,17 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (!getKpiDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, kpiDescription_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(3, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getDeviceId());
-      }
-      if (endpointId_ != null) {
+      if (kpiId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getEndpointId());
+          .computeMessageSize(1, getKpiId());
       }
-      if (serviceId_ != null) {
+      if (monitoringWindowS_ != 0F) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, getServiceId());
+          .computeFloatSize(2, monitoringWindowS_);
       }
-      if (sliceId_ != null) {
+      if (samplingRateS_ != 0F) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, getSliceId());
+          .computeFloatSize(3, samplingRateS_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -2051,36 +2320,22 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.BundleKpiDescriptor)) {
+      if (!(obj instanceof monitoring.Monitoring.MonitorKpiRequest)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.BundleKpiDescriptor other = (monitoring.Monitoring.BundleKpiDescriptor) obj;
+      monitoring.Monitoring.MonitorKpiRequest other = (monitoring.Monitoring.MonitorKpiRequest) obj;
 
-      if (!getKpiDescription()
-          .equals(other.getKpiDescription())) return false;
-      if (!getKpiIdListList()
-          .equals(other.getKpiIdListList())) 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 (hasSliceId() != other.hasSliceId()) return false;
-      if (hasSliceId()) {
-        if (!getSliceId()
-            .equals(other.getSliceId())) return false;
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
       }
+      if (java.lang.Float.floatToIntBits(getMonitoringWindowS())
+          != java.lang.Float.floatToIntBits(
+              other.getMonitoringWindowS())) return false;
+      if (java.lang.Float.floatToIntBits(getSamplingRateS())
+          != java.lang.Float.floatToIntBits(
+              other.getSamplingRateS())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -2092,98 +2347,84 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + KPI_DESCRIPTION_FIELD_NUMBER;
-      hash = (53 * hash) + getKpiDescription().hashCode();
-      if (getKpiIdListCount() > 0) {
-        hash = (37 * hash) + KPI_ID_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiIdListList().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();
-      }
-      if (hasSliceId()) {
-        hash = (37 * hash) + SLICE_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getSliceId().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
       }
+      hash = (37 * hash) + MONITORING_WINDOW_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getMonitoringWindowS());
+      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSamplingRateS());
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(byte[] data)
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(java.io.InputStream input)
+    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.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseDelimitedFrom(java.io.InputStream input)
+    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.BundleKpiDescriptor parseDelimitedFrom(
+    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.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -2196,7 +2437,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.BundleKpiDescriptor prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.MonitorKpiRequest prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -2212,26 +2453,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.BundleKpiDescriptor}
+     * Protobuf type {@code monitoring.MonitorKpiRequest}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.BundleKpiDescriptor)
-        monitoring.Monitoring.BundleKpiDescriptorOrBuilder {
+        // @@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_BundleKpiDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.BundleKpiDescriptor.class, monitoring.Monitoring.BundleKpiDescriptor.Builder.class);
+                monitoring.Monitoring.MonitorKpiRequest.class, monitoring.Monitoring.MonitorKpiRequest.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.BundleKpiDescriptor.newBuilder()
+      // Construct using monitoring.Monitoring.MonitorKpiRequest.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -2244,63 +2485,38 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiIdListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        kpiDescription_ = "";
-
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
         } else {
-          kpiIdListBuilder_.clear();
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
-        kpiSampleType_ = 0;
+        monitoringWindowS_ = 0F;
+
+        samplingRateS_ = 0F;
 
-        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;
-        }
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.BundleKpiDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.BundleKpiDescriptor.getDefaultInstance();
+      public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
+        return monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.BundleKpiDescriptor build() {
-        monitoring.Monitoring.BundleKpiDescriptor result = buildPartial();
+      public monitoring.Monitoring.MonitorKpiRequest build() {
+        monitoring.Monitoring.MonitorKpiRequest result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -2308,40 +2524,15 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.BundleKpiDescriptor buildPartial() {
-        monitoring.Monitoring.BundleKpiDescriptor result = new monitoring.Monitoring.BundleKpiDescriptor(this);
-        int from_bitField0_ = bitField0_;
-        result.kpiDescription_ = kpiDescription_;
-        if (kpiIdListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.kpiIdList_ = kpiIdList_;
-        } else {
-          result.kpiIdList_ = kpiIdListBuilder_.build();
-        }
-        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();
-        }
-        if (sliceIdBuilder_ == null) {
-          result.sliceId_ = sliceId_;
+      public monitoring.Monitoring.MonitorKpiRequest buildPartial() {
+        monitoring.Monitoring.MonitorKpiRequest result = new monitoring.Monitoring.MonitorKpiRequest(this);
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
         } else {
-          result.sliceId_ = sliceIdBuilder_.build();
+          result.kpiId_ = kpiIdBuilder_.build();
         }
+        result.monitoringWindowS_ = monitoringWindowS_;
+        result.samplingRateS_ = samplingRateS_;
         onBuilt();
         return result;
       }
@@ -2380,60 +2571,24 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.BundleKpiDescriptor) {
-          return mergeFrom((monitoring.Monitoring.BundleKpiDescriptor)other);
+        if (other instanceof monitoring.Monitoring.MonitorKpiRequest) {
+          return mergeFrom((monitoring.Monitoring.MonitorKpiRequest)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.BundleKpiDescriptor other) {
-        if (other == monitoring.Monitoring.BundleKpiDescriptor.getDefaultInstance()) return this;
-        if (!other.getKpiDescription().isEmpty()) {
-          kpiDescription_ = other.kpiDescription_;
-          onChanged();
-        }
-        if (kpiIdListBuilder_ == null) {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdList_.isEmpty()) {
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiIdListIsMutable();
-              kpiIdList_.addAll(other.kpiIdList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdListBuilder_.isEmpty()) {
-              kpiIdListBuilder_.dispose();
-              kpiIdListBuilder_ = null;
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiIdListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiIdListFieldBuilder() : null;
-            } else {
-              kpiIdListBuilder_.addAllMessages(other.kpiIdList_);
-            }
-          }
-        }
-        if (other.kpiSampleType_ != 0) {
-          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
-        }
-        if (other.hasDeviceId()) {
-          mergeDeviceId(other.getDeviceId());
-        }
-        if (other.hasEndpointId()) {
-          mergeEndpointId(other.getEndpointId());
+      public Builder mergeFrom(monitoring.Monitoring.MonitorKpiRequest other) {
+        if (other == monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
         }
-        if (other.hasServiceId()) {
-          mergeServiceId(other.getServiceId());
+        if (other.getMonitoringWindowS() != 0F) {
+          setMonitoringWindowS(other.getMonitoringWindowS());
         }
-        if (other.hasSliceId()) {
-          mergeSliceId(other.getSliceId());
+        if (other.getSamplingRateS() != 0F) {
+          setSamplingRateS(other.getSamplingRateS());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -2450,11 +2605,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.BundleKpiDescriptor parsedMessage = null;
+        monitoring.Monitoring.MonitorKpiRequest parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.BundleKpiDescriptor) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.MonitorKpiRequest) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -2463,1055 +2618,377 @@ public final class Monitoring {
         }
         return this;
       }
-      private int bitField0_;
 
-      private java.lang.Object kpiDescription_ = "";
+      private monitoring.Monitoring.KpiId kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
       /**
-       * <code>string kpi_description = 1;</code>
-       * @return The kpiDescription.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
        */
-      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;
-        }
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
       }
       /**
-       * <code>string kpi_description = 1;</code>
-       * @return The bytes for kpiDescription.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return The kpiId.
        */
-      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;
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          return kpiIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>string kpi_description = 1;</code>
-       * @param value The kpiDescription to set.
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder setKpiDescription(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        kpiDescription_ = value;
-        onChanged();
+      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>string kpi_description = 1;</code>
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder clearKpiDescription() {
-        
-        kpiDescription_ = getDefaultInstance().getKpiDescription();
-        onChanged();
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
         return this;
       }
       /**
-       * <code>string kpi_description = 1;</code>
-       * @param value The bytes for kpiDescription to set.
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder setKpiDescriptionBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        kpiDescription_ = value;
-        onChanged();
-        return this;
-      }
+      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);
+        }
 
-      private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiIdListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiIdList_);
-          bitField0_ |= 0x00000001;
-         }
+        return this;
       }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdListBuilder_;
-
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-        if (kpiIdListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
         } else {
-          return kpiIdListBuilder_.getMessageList();
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public int getKpiIdListCount() {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.size();
-        } else {
-          return kpiIdListBuilder_.getCount();
-        }
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);
-        } else {
-          return kpiIdListBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addAllKpiIdList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiIdList_);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addAllMessages(values);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder clearKpiIdList() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.clear();
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder removeKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.remove(index);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.remove(index);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-          int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);  } else {
-          return kpiIdListBuilder_.getMessageOrBuilder(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-           getKpiIdListOrBuilderList() {
-        if (kpiIdListBuilder_ != null) {
-          return kpiIdListBuilder_.getMessageOrBuilderList();
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
         } else {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         }
       }
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder() {
-        return getKpiIdListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
-           getKpiIdListBuilderList() {
-        return getKpiIdListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
+      private com.google.protobuf.SingleFieldBuilderV3<
           monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
-          getKpiIdListFieldBuilder() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
-                  kpiIdList_,
-                  ((bitField0_ & 0x00000001) != 0),
+                  getKpiId(),
                   getParentForChildren(),
                   isClean());
-          kpiIdList_ = null;
+          kpiId_ = null;
         }
-        return kpiIdListBuilder_;
+        return kpiIdBuilder_;
       }
 
-      private int kpiSampleType_ = 0;
+      private float monitoringWindowS_ ;
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @return The enum numeric value on the wire for kpiSampleType.
+       * <code>float monitoring_window_s = 2;</code>
+       * @return The monitoringWindowS.
        */
-      @java.lang.Override public int getKpiSampleTypeValue() {
-        return kpiSampleType_;
+      @java.lang.Override
+      public float getMonitoringWindowS() {
+        return monitoringWindowS_;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @param value The enum numeric value on the wire for kpiSampleType to set.
+       * <code>float monitoring_window_s = 2;</code>
+       * @param value The monitoringWindowS to set.
        * @return This builder for chaining.
        */
-      public Builder setKpiSampleTypeValue(int value) {
+      public Builder setMonitoringWindowS(float value) {
         
-        kpiSampleType_ = value;
+        monitoringWindowS_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @return The kpiSampleType.
+       * <code>float monitoring_window_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearMonitoringWindowS() {
+        
+        monitoringWindowS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float samplingRateS_ ;
+      /**
+       * <pre>
+       * Pending add field to reflect Available Device Protocols
+       * </pre>
+       *
+       * <code>float sampling_rate_s = 3;</code>
+       * @return The samplingRateS.
        */
       @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 float getSamplingRateS() {
+        return samplingRateS_;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @param value The kpiSampleType to set.
+       * <pre>
+       * Pending add field to reflect Available Device Protocols
+       * </pre>
+       *
+       * <code>float sampling_rate_s = 3;</code>
+       * @param value The samplingRateS to set.
        * @return This builder for chaining.
        */
-      public Builder setKpiSampleType(kpi_sample_types.KpiSampleTypes.KpiSampleType value) {
-        if (value == null) {
-          throw new NullPointerException();
-        }
+      public Builder setSamplingRateS(float value) {
         
-        kpiSampleType_ = value.getNumber();
+        samplingRateS_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
+       * <pre>
+       * Pending add field to reflect Available Device Protocols
+       * </pre>
+       *
+       * <code>float sampling_rate_s = 3;</code>
        * @return This builder for chaining.
        */
-      public Builder clearKpiSampleType() {
+      public Builder clearSamplingRateS() {
         
-        kpiSampleType_ = 0;
+        samplingRateS_ = 0F;
         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 = 4;</code>
-       * @return Whether the deviceId field is set.
-       */
-      public boolean hasDeviceId() {
-        return deviceIdBuilder_ != null || deviceId_ != null;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 4;</code>
-       * @return The deviceId.
-       */
-      public context.ContextOuterClass.DeviceId getDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
-        } else {
-          return deviceIdBuilder_.getMessage();
-        }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
       }
-      /**
-       * <code>.context.DeviceId device_id = 4;</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;
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
-      /**
-       * <code>.context.DeviceId device_id = 4;</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 = 4;</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 = 4;</code>
-       */
-      public Builder clearDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = null;
-          onChanged();
-        } else {
-          deviceId_ = null;
-          deviceIdBuilder_ = null;
-        }
+      // @@protoc_insertion_point(builder_scope:monitoring.MonitorKpiRequest)
+    }
 
-        return this;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 4;</code>
-       */
-      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
-        
-        onChanged();
-        return getDeviceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.DeviceId device_id = 4;</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 = 4;</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_;
-      }
+    // @@protoc_insertion_point(class_scope:monitoring.MonitorKpiRequest)
+    private static final monitoring.Monitoring.MonitorKpiRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.MonitorKpiRequest();
+    }
 
-      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 = 5;</code>
-       * @return Whether the endpointId field is set.
-       */
-      public boolean hasEndpointId() {
-        return endpointIdBuilder_ != null || endpointId_ != null;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</code>
-       */
-      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
-        if (endpointIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          endpointId_ = value;
-          onChanged();
-        } else {
-          endpointIdBuilder_.setMessage(value);
-        }
+    public static monitoring.Monitoring.MonitorKpiRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
 
-        return this;
+    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);
       }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</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);
-        }
+    public static com.google.protobuf.Parser<MonitorKpiRequest> parser() {
+      return PARSER;
+    }
 
-        return this;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</code>
-       */
-      public Builder clearEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = null;
-          onChanged();
-        } else {
-          endpointId_ = null;
-          endpointIdBuilder_ = null;
-        }
+    @java.lang.Override
+    public com.google.protobuf.Parser<MonitorKpiRequest> getParserForType() {
+      return PARSER;
+    }
 
-        return this;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</code>
-       */
-      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
-        
-        onChanged();
-        return getEndpointIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</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_;
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       * @return Whether the serviceId field is set.
-       */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       * @return The serviceId.
-       */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
-          onChanged();
-        } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
-        
-        onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
-        } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</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_;
-      }
-
-      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 = 7;</code>
-       * @return Whether the sliceId field is set.
-       */
-      public boolean hasSliceId() {
-        return sliceIdBuilder_ != null || sliceId_ != null;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 7;</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 = 7;</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 = 7;</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 = 7;</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 = 7;</code>
-       */
-      public Builder clearSliceId() {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-          onChanged();
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 7;</code>
-       */
-      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
-        
-        onChanged();
-        return getSliceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.SliceId slice_id = 7;</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 = 7;</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:monitoring.BundleKpiDescriptor)
-    }
-
-    // @@protoc_insertion_point(class_scope:monitoring.BundleKpiDescriptor)
-    private static final monitoring.Monitoring.BundleKpiDescriptor DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.BundleKpiDescriptor();
-    }
-
-    public static monitoring.Monitoring.BundleKpiDescriptor getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<BundleKpiDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<BundleKpiDescriptor>() {
-      @java.lang.Override
-      public BundleKpiDescriptor parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new BundleKpiDescriptor(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<BundleKpiDescriptor> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<BundleKpiDescriptor> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.BundleKpiDescriptor getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
+    @java.lang.Override
+    public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
 
   }
 
-  public interface EditedKpiDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.EditedKpiDescriptor)
+  public interface KpiQueryOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiQuery)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    boolean hasKpiId();
+    java.util.List<monitoring.Monitoring.KpiId> 
+        getKpiIdList();
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    monitoring.Monitoring.KpiId getKpiId();
-    /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
-
-    /**
-     * <code>string kpi_description = 2;</code>
-     * @return The kpiDescription.
-     */
-    java.lang.String getKpiDescription();
-    /**
-     * <code>string kpi_description = 2;</code>
-     * @return The bytes for kpiDescription.
-     */
-    com.google.protobuf.ByteString
-        getKpiDescriptionBytes();
-
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    java.util.List<monitoring.Monitoring.KpiId> 
-        getKpiIdListList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    monitoring.Monitoring.KpiId getKpiIdList(int index);
+    monitoring.Monitoring.KpiId getKpiId(int index);
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    int getKpiIdListCount();
+    int getKpiIdCount();
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList();
+        getKpiIdOrBuilderList();
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
         int index);
 
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
-     * @return The enum numeric value on the wire for kpiSampleType.
-     */
-    int getKpiSampleTypeValue();
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
-     * @return The kpiSampleType.
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
-    kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
+    float getMonitoringWindowS();
 
     /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return Whether the deviceId field is set.
-     */
-    boolean hasDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return The deviceId.
-     */
-    context.ContextOuterClass.DeviceId getDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
-    context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
+    float getSamplingRateS();
 
     /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return Whether the endpointId field is set.
-     */
-    boolean hasEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return The endpointId.
-     */
-    context.ContextOuterClass.EndPointId getEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
+     * <pre>
+     * used when you want something like "get the last N many samples
+     * </pre>
+     *
+     * <code>uint32 last_n_samples = 4;</code>
+     * @return The lastNSamples.
      */
-    context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
+    int getLastNSamples();
 
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return Whether the serviceId field is set.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
      */
-    boolean hasServiceId();
+    boolean hasStartTimestamp();
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return The serviceId.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
      */
-    context.ContextOuterClass.ServiceId getServiceId();
+    context.ContextOuterClass.Timestamp getStartTimestamp();
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
      */
-    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+    context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder();
 
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return Whether the sliceId field is set.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
      */
-    boolean hasSliceId();
+    boolean hasEndTimestamp();
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return The sliceId.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
      */
-    context.ContextOuterClass.SliceId getSliceId();
+    context.ContextOuterClass.Timestamp getEndTimestamp();
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
      */
-    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+    context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.EditedKpiDescriptor}
+   * Protobuf type {@code monitoring.KpiQuery}
    */
-  public static final class EditedKpiDescriptor extends
+  public static final class KpiQuery extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.EditedKpiDescriptor)
-      EditedKpiDescriptorOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiQuery)
+      KpiQueryOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use EditedKpiDescriptor.newBuilder() to construct.
-    private EditedKpiDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiQuery.newBuilder() to construct.
+    private KpiQuery(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private EditedKpiDescriptor() {
-      kpiDescription_ = "";
-      kpiIdList_ = java.util.Collections.emptyList();
-      kpiSampleType_ = 0;
+    private KpiQuery() {
+      kpiId_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new EditedKpiDescriptor();
+      return new KpiQuery();
     }
 
     @java.lang.Override
@@ -3519,7 +2996,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private EditedKpiDescriptor(
+    private KpiQuery(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -3539,87 +3016,51 @@ public final class Monitoring {
               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();
-
-              kpiDescription_ = s;
-              break;
-            }
-            case 26: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
+                kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              kpiIdList_.add(
+              kpiId_.add(
                   input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
               break;
             }
-            case 32: {
-              int rawValue = input.readEnum();
+            case 21: {
 
-              kpiSampleType_ = rawValue;
+              monitoringWindowS_ = input.readFloat();
               break;
             }
-            case 42: {
-              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();
-              }
+            case 29: {
 
+              samplingRateS_ = input.readFloat();
               break;
             }
-            case 50: {
-              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();
-              }
+            case 32: {
 
+              lastNSamples_ = input.readUInt32();
               break;
             }
-            case 58: {
-              context.ContextOuterClass.ServiceId.Builder subBuilder = null;
-              if (serviceId_ != null) {
-                subBuilder = serviceId_.toBuilder();
+            case 42: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (startTimestamp_ != null) {
+                subBuilder = startTimestamp_.toBuilder();
               }
-              serviceId_ = input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry);
+              startTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(serviceId_);
-                serviceId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(startTimestamp_);
+                startTimestamp_ = subBuilder.buildPartial();
               }
 
               break;
             }
-            case 66: {
-              context.ContextOuterClass.SliceId.Builder subBuilder = null;
-              if (sliceId_ != null) {
-                subBuilder = sliceId_.toBuilder();
+            case 50: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (endTimestamp_ != null) {
+                subBuilder = endTimestamp_.toBuilder();
               }
-              sliceId_ = input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry);
+              endTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(sliceId_);
-                sliceId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(endTimestamp_);
+                endTimestamp_ = subBuilder.buildPartial();
               }
 
               break;
@@ -3640,7 +3081,7 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
+          kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -3648,242 +3089,168 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.EditedKpiDescriptor.class, monitoring.Monitoring.EditedKpiDescriptor.Builder.class);
+              monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
     }
 
     public static final int KPI_ID_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.KpiId kpiId_;
+    private java.util.List<monitoring.Monitoring.KpiId> kpiId_;
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public boolean hasKpiId() {
-      return kpiId_ != null;
+    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+      return kpiId_;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiId() {
-      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdOrBuilderList() {
+      return kpiId_;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-      return getKpiId();
+    public int getKpiIdCount() {
+      return kpiId_.size();
     }
-
-    public static final int KPI_DESCRIPTION_FIELD_NUMBER = 2;
-    private volatile java.lang.Object kpiDescription_;
     /**
-     * <code>string kpi_description = 2;</code>
-     * @return The kpiDescription.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @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;
-      }
+    public monitoring.Monitoring.KpiId getKpiId(int index) {
+      return kpiId_.get(index);
     }
     /**
-     * <code>string kpi_description = 2;</code>
-     * @return The bytes for kpiDescription.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @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_ID_LIST_FIELD_NUMBER = 3;
-    private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_;
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-      return kpiIdList_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList() {
-      return kpiIdList_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public int getKpiIdListCount() {
-      return kpiIdList_.size();
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-      return kpiIdList_.get(index);
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
         int index) {
-      return kpiIdList_.get(index);
-    }
-
-    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 4;
-    private int kpiSampleType_;
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</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 = 4;</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;
+      return kpiId_.get(index);
     }
 
-    public static final int DEVICE_ID_FIELD_NUMBER = 5;
-    private context.ContextOuterClass.DeviceId deviceId_;
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return Whether the deviceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasDeviceId() {
-      return deviceId_ != null;
-    }
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return The deviceId.
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.DeviceId getDeviceId() {
-      return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
-    }
+    public static final int MONITORING_WINDOW_S_FIELD_NUMBER = 2;
+    private float monitoringWindowS_;
     /**
-     * <code>.context.DeviceId device_id = 5;</code>
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
     @java.lang.Override
-    public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
-      return getDeviceId();
+    public float getMonitoringWindowS() {
+      return monitoringWindowS_;
     }
 
-    public static final int ENDPOINT_ID_FIELD_NUMBER = 6;
-    private context.ContextOuterClass.EndPointId endpointId_;
-    /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return Whether the endpointId field is set.
-     */
-    @java.lang.Override
-    public boolean hasEndpointId() {
-      return endpointId_ != null;
-    }
+    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
+    private float samplingRateS_;
     /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return The endpointId.
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
     @java.lang.Override
-    public context.ContextOuterClass.EndPointId getEndpointId() {
-      return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+    public float getSamplingRateS() {
+      return samplingRateS_;
     }
+
+    public static final int LAST_N_SAMPLES_FIELD_NUMBER = 4;
+    private int lastNSamples_;
     /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
+     * <pre>
+     * used when you want something like "get the last N many samples
+     * </pre>
+     *
+     * <code>uint32 last_n_samples = 4;</code>
+     * @return The lastNSamples.
      */
     @java.lang.Override
-    public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
-      return getEndpointId();
+    public int getLastNSamples() {
+      return lastNSamples_;
     }
 
-    public static final int SERVICE_ID_FIELD_NUMBER = 7;
-    private context.ContextOuterClass.ServiceId serviceId_;
+    public static final int START_TIMESTAMP_FIELD_NUMBER = 5;
+    private context.ContextOuterClass.Timestamp startTimestamp_;
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return Whether the serviceId field is set.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
      */
     @java.lang.Override
-    public boolean hasServiceId() {
-      return serviceId_ != null;
+    public boolean hasStartTimestamp() {
+      return startTimestamp_ != null;
     }
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return The serviceId.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceId getServiceId() {
-      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+    public context.ContextOuterClass.Timestamp getStartTimestamp() {
+      return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
     }
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-      return getServiceId();
+    public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+      return getStartTimestamp();
     }
 
-    public static final int SLICE_ID_FIELD_NUMBER = 8;
-    private context.ContextOuterClass.SliceId sliceId_;
+    public static final int END_TIMESTAMP_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.Timestamp endTimestamp_;
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return Whether the sliceId field is set.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
      */
     @java.lang.Override
-    public boolean hasSliceId() {
-      return sliceId_ != null;
+    public boolean hasEndTimestamp() {
+      return endTimestamp_ != null;
     }
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return The sliceId.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
      */
     @java.lang.Override
-    public context.ContextOuterClass.SliceId getSliceId() {
-      return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+    public context.ContextOuterClass.Timestamp getEndTimestamp() {
+      return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
     }
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
-      return getSliceId();
+    public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+      return getEndTimestamp();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -3894,3670 +3261,1729 @@ public final class Monitoring {
       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 (!getKpiDescriptionBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, kpiDescription_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        output.writeMessage(3, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        output.writeEnum(4, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        output.writeMessage(5, getDeviceId());
-      }
-      if (endpointId_ != null) {
-        output.writeMessage(6, getEndpointId());
-      }
-      if (serviceId_ != null) {
-        output.writeMessage(7, getServiceId());
-      }
-      if (sliceId_ != null) {
-        output.writeMessage(8, getSliceId());
-      }
-      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 (!getKpiDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, kpiDescription_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(4, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getDeviceId());
-      }
-      if (endpointId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, getEndpointId());
-      }
-      if (serviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, getServiceId());
-      }
-      if (sliceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(8, 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 monitoring.Monitoring.EditedKpiDescriptor)) {
-        return super.equals(obj);
-      }
-      monitoring.Monitoring.EditedKpiDescriptor other = (monitoring.Monitoring.EditedKpiDescriptor) obj;
-
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
-      }
-      if (!getKpiDescription()
-          .equals(other.getKpiDescription())) return false;
-      if (!getKpiIdListList()
-          .equals(other.getKpiIdListList())) 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 (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 (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
-      }
-      hash = (37 * hash) + KPI_DESCRIPTION_FIELD_NUMBER;
-      hash = (53 * hash) + getKpiDescription().hashCode();
-      if (getKpiIdListCount() > 0) {
-        hash = (37 * hash) + KPI_ID_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiIdListList().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();
-      }
-      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 monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor 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.EditedKpiDescriptor}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.EditedKpiDescriptor)
-        monitoring.Monitoring.EditedKpiDescriptorOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_descriptor;
-      }
-
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.EditedKpiDescriptor.class, monitoring.Monitoring.EditedKpiDescriptor.Builder.class);
-      }
-
-      // Construct using monitoring.Monitoring.EditedKpiDescriptor.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-          getKpiIdListFieldBuilder();
-        }
-      }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
-        } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
-        }
-        kpiDescription_ = "";
-
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-        } else {
-          kpiIdListBuilder_.clear();
-        }
-        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;
-        }
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.EditedKpiDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.EditedKpiDescriptor.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.EditedKpiDescriptor build() {
-        monitoring.Monitoring.EditedKpiDescriptor result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.EditedKpiDescriptor buildPartial() {
-        monitoring.Monitoring.EditedKpiDescriptor result = new monitoring.Monitoring.EditedKpiDescriptor(this);
-        int from_bitField0_ = bitField0_;
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
-        } else {
-          result.kpiId_ = kpiIdBuilder_.build();
-        }
-        result.kpiDescription_ = kpiDescription_;
-        if (kpiIdListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.kpiIdList_ = kpiIdList_;
-        } else {
-          result.kpiIdList_ = kpiIdListBuilder_.build();
-        }
-        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();
-        }
-        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 monitoring.Monitoring.EditedKpiDescriptor) {
-          return mergeFrom((monitoring.Monitoring.EditedKpiDescriptor)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(monitoring.Monitoring.EditedKpiDescriptor other) {
-        if (other == monitoring.Monitoring.EditedKpiDescriptor.getDefaultInstance()) return this;
-        if (other.hasKpiId()) {
-          mergeKpiId(other.getKpiId());
-        }
-        if (!other.getKpiDescription().isEmpty()) {
-          kpiDescription_ = other.kpiDescription_;
-          onChanged();
-        }
-        if (kpiIdListBuilder_ == null) {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdList_.isEmpty()) {
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiIdListIsMutable();
-              kpiIdList_.addAll(other.kpiIdList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdListBuilder_.isEmpty()) {
-              kpiIdListBuilder_.dispose();
-              kpiIdListBuilder_ = null;
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiIdListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiIdListFieldBuilder() : null;
-            } else {
-              kpiIdListBuilder_.addAllMessages(other.kpiIdList_);
-            }
-          }
-        }
-        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());
-        }
-        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 {
-        monitoring.Monitoring.EditedKpiDescriptor parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.EditedKpiDescriptor) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      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 kpiDescription_ = "";
-      /**
-       * <code>string kpi_description = 2;</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 = 2;</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 = 2;</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 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearKpiDescription() {
-        
-        kpiDescription_ = getDefaultInstance().getKpiDescription();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string kpi_description = 2;</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 java.util.List<monitoring.Monitoring.KpiId> kpiIdList_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiIdListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiIdList_);
-          bitField0_ |= 0x00000001;
-         }
-      }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdListBuilder_;
-
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-        if (kpiIdListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
-        } else {
-          return kpiIdListBuilder_.getMessageList();
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public int getKpiIdListCount() {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.size();
-        } else {
-          return kpiIdListBuilder_.getCount();
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);
-        } else {
-          return kpiIdListBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addAllKpiIdList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiIdList_);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addAllMessages(values);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder clearKpiIdList() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.clear();
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder removeKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.remove(index);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.remove(index);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-          int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);  } else {
-          return kpiIdListBuilder_.getMessageOrBuilder(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-           getKpiIdListOrBuilderList() {
-        if (kpiIdListBuilder_ != null) {
-          return kpiIdListBuilder_.getMessageOrBuilderList();
-        } else {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder() {
-        return getKpiIdListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
-           getKpiIdListBuilderList() {
-        return getKpiIdListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
-          getKpiIdListFieldBuilder() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
-                  kpiIdList_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          kpiIdList_ = null;
-        }
-        return kpiIdListBuilder_;
-      }
-
-      private int kpiSampleType_ = 0;
-      /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</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 = 4;</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 = 4;</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 = 4;</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 = 4;</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 = 5;</code>
-       * @return Whether the deviceId field is set.
-       */
-      public boolean hasDeviceId() {
-        return deviceIdBuilder_ != null || deviceId_ != null;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 5;</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 = 5;</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 = 5;</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 = 5;</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 = 5;</code>
-       */
-      public Builder clearDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = null;
-          onChanged();
-        } else {
-          deviceId_ = null;
-          deviceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 5;</code>
-       */
-      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
-        
-        onChanged();
-        return getDeviceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.DeviceId device_id = 5;</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 = 5;</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 = 6;</code>
-       * @return Whether the endpointId field is set.
-       */
-      public boolean hasEndpointId() {
-        return endpointIdBuilder_ != null || endpointId_ != null;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 6;</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 = 6;</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 = 6;</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 = 6;</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 = 6;</code>
-       */
-      public Builder clearEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = null;
-          onChanged();
-        } else {
-          endpointId_ = null;
-          endpointIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 6;</code>
-       */
-      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
-        
-        onChanged();
-        return getEndpointIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 6;</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 = 6;</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_;
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       * @return Whether the serviceId field is set.
-       */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       * @return The serviceId.
-       */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
-          onChanged();
-        } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
-        
-        onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
-        } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</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_;
-      }
-
-      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 = 8;</code>
-       * @return Whether the sliceId field is set.
-       */
-      public boolean hasSliceId() {
-        return sliceIdBuilder_ != null || sliceId_ != null;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 8;</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 = 8;</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 = 8;</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 = 8;</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 = 8;</code>
-       */
-      public Builder clearSliceId() {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-          onChanged();
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 8;</code>
-       */
-      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
-        
-        onChanged();
-        return getSliceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.SliceId slice_id = 8;</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 = 8;</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:monitoring.EditedKpiDescriptor)
-    }
-
-    // @@protoc_insertion_point(class_scope:monitoring.EditedKpiDescriptor)
-    private static final monitoring.Monitoring.EditedKpiDescriptor DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.EditedKpiDescriptor();
-    }
-
-    public static monitoring.Monitoring.EditedKpiDescriptor getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<EditedKpiDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<EditedKpiDescriptor>() {
-      @java.lang.Override
-      public EditedKpiDescriptor parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new EditedKpiDescriptor(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<EditedKpiDescriptor> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<EditedKpiDescriptor> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.EditedKpiDescriptor 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 monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    float getMonitoringWindowS();
-
-    /**
-     * <pre>
-     * Pending add field to reflect Available Device Protocols
-     * </pre>
-     *
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    float getSamplingRateS();
-  }
-  /**
-   * 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: {
-
-              monitoringWindowS_ = input.readFloat();
-              break;
-            }
-            case 29: {
-
-              samplingRateS_ = 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 MONITORING_WINDOW_S_FIELD_NUMBER = 2;
-    private float monitoringWindowS_;
-    /**
-     * <code>float monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    @java.lang.Override
-    public float getMonitoringWindowS() {
-      return monitoringWindowS_;
-    }
-
-    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
-    private float samplingRateS_;
-    /**
-     * <pre>
-     * Pending add field to reflect Available Device Protocols
-     * </pre>
-     *
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    @java.lang.Override
-    public float getSamplingRateS() {
-      return samplingRateS_;
-    }
-
-    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 (monitoringWindowS_ != 0F) {
-        output.writeFloat(2, monitoringWindowS_);
-      }
-      if (samplingRateS_ != 0F) {
-        output.writeFloat(3, samplingRateS_);
-      }
-      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 (monitoringWindowS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(2, monitoringWindowS_);
-      }
-      if (samplingRateS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(3, samplingRateS_);
-      }
-      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(getMonitoringWindowS())
-          != java.lang.Float.floatToIntBits(
-              other.getMonitoringWindowS())) return false;
-      if (java.lang.Float.floatToIntBits(getSamplingRateS())
-          != java.lang.Float.floatToIntBits(
-              other.getSamplingRateS())) 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) + MONITORING_WINDOW_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getMonitoringWindowS());
-      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getSamplingRateS());
-      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;
-        }
-        monitoringWindowS_ = 0F;
-
-        samplingRateS_ = 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.monitoringWindowS_ = monitoringWindowS_;
-        result.samplingRateS_ = samplingRateS_;
-        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.getMonitoringWindowS() != 0F) {
-          setMonitoringWindowS(other.getMonitoringWindowS());
-        }
-        if (other.getSamplingRateS() != 0F) {
-          setSamplingRateS(other.getSamplingRateS());
-        }
-        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_;
-      }
+      return true;
+    }
 
-      private float monitoringWindowS_ ;
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return The monitoringWindowS.
-       */
-      @java.lang.Override
-      public float getMonitoringWindowS() {
-        return monitoringWindowS_;
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < kpiId_.size(); i++) {
+        output.writeMessage(1, kpiId_.get(i));
       }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @param value The monitoringWindowS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMonitoringWindowS(float value) {
-        
-        monitoringWindowS_ = value;
-        onChanged();
-        return this;
+      if (monitoringWindowS_ != 0F) {
+        output.writeFloat(2, monitoringWindowS_);
       }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMonitoringWindowS() {
-        
-        monitoringWindowS_ = 0F;
-        onChanged();
-        return this;
+      if (samplingRateS_ != 0F) {
+        output.writeFloat(3, samplingRateS_);
+      }
+      if (lastNSamples_ != 0) {
+        output.writeUInt32(4, lastNSamples_);
+      }
+      if (startTimestamp_ != null) {
+        output.writeMessage(5, getStartTimestamp());
       }
+      if (endTimestamp_ != null) {
+        output.writeMessage(6, getEndTimestamp());
+      }
+      unknownFields.writeTo(output);
+    }
 
-      private float samplingRateS_ ;
-      /**
-       * <pre>
-       * Pending add field to reflect Available Device Protocols
-       * </pre>
-       *
-       * <code>float sampling_rate_s = 3;</code>
-       * @return The samplingRateS.
-       */
-      @java.lang.Override
-      public float getSamplingRateS() {
-        return samplingRateS_;
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < kpiId_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, kpiId_.get(i));
       }
-      /**
-       * <pre>
-       * Pending add field to reflect Available Device Protocols
-       * </pre>
-       *
-       * <code>float sampling_rate_s = 3;</code>
-       * @param value The samplingRateS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSamplingRateS(float value) {
-        
-        samplingRateS_ = value;
-        onChanged();
-        return this;
+      if (monitoringWindowS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(2, monitoringWindowS_);
       }
-      /**
-       * <pre>
-       * Pending add field to reflect Available Device Protocols
-       * </pre>
-       *
-       * <code>float sampling_rate_s = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSamplingRateS() {
-        
-        samplingRateS_ = 0F;
-        onChanged();
-        return this;
+      if (samplingRateS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, samplingRateS_);
       }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+      if (lastNSamples_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(4, lastNSamples_);
       }
-
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      if (startTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, getStartTimestamp());
       }
+      if (endTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getEndTimestamp());
+      }
+      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.KpiQuery)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.KpiQuery other = (monitoring.Monitoring.KpiQuery) obj;
 
-      // @@protoc_insertion_point(builder_scope:monitoring.MonitorKpiRequest)
+      if (!getKpiIdList()
+          .equals(other.getKpiIdList())) return false;
+      if (java.lang.Float.floatToIntBits(getMonitoringWindowS())
+          != java.lang.Float.floatToIntBits(
+              other.getMonitoringWindowS())) return false;
+      if (java.lang.Float.floatToIntBits(getSamplingRateS())
+          != java.lang.Float.floatToIntBits(
+              other.getSamplingRateS())) return false;
+      if (getLastNSamples()
+          != other.getLastNSamples()) return false;
+      if (hasStartTimestamp() != other.hasStartTimestamp()) return false;
+      if (hasStartTimestamp()) {
+        if (!getStartTimestamp()
+            .equals(other.getStartTimestamp())) return false;
+      }
+      if (hasEndTimestamp() != other.hasEndTimestamp()) return false;
+      if (hasEndTimestamp()) {
+        if (!getEndTimestamp()
+            .equals(other.getEndTimestamp())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.MonitorKpiRequest)
-    private static final monitoring.Monitoring.MonitorKpiRequest DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.MonitorKpiRequest();
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getKpiIdCount() > 0) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiIdList().hashCode();
+      }
+      hash = (37 * hash) + MONITORING_WINDOW_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getMonitoringWindowS());
+      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSamplingRateS());
+      hash = (37 * hash) + LAST_N_SAMPLES_FIELD_NUMBER;
+      hash = (53 * hash) + getLastNSamples();
+      if (hasStartTimestamp()) {
+        hash = (37 * hash) + START_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getStartTimestamp().hashCode();
+      }
+      if (hasEndTimestamp()) {
+        hash = (37 * hash) + END_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getEndTimestamp().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
-    public static monitoring.Monitoring.MonitorKpiRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    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 Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.KpiQuery prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
-
     @java.lang.Override
-    public com.google.protobuf.Parser<MonitorKpiRequest> getParserForType() {
-      return PARSER;
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
     }
-
-  }
-
-  public interface KpiQueryOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiQuery)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    java.util.List<monitoring.Monitoring.KpiId> 
-        getKpiIdList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    monitoring.Monitoring.KpiId getKpiId(int index);
     /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    int getKpiIdCount();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdOrBuilderList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+     * Protobuf type {@code monitoring.KpiQuery}
      */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
-        int index);
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiQuery)
+        monitoring.Monitoring.KpiQueryOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
+      }
 
-    /**
-     * <code>float monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    float getMonitoringWindowS();
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
+      }
 
-    /**
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    float getSamplingRateS();
+      // Construct using monitoring.Monitoring.KpiQuery.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
 
-    /**
-     * <pre>
-     * used when you want something like "get the last N many samples
-     * </pre>
-     *
-     * <code>uint32 last_n_samples = 4;</code>
-     * @return The lastNSamples.
-     */
-    int getLastNSamples();
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getKpiIdFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          kpiIdBuilder_.clear();
+        }
+        monitoringWindowS_ = 0F;
 
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The startDate.
-     */
-    java.lang.String getStartDate();
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The bytes for startDate.
-     */
-    com.google.protobuf.ByteString
-        getStartDateBytes();
+        samplingRateS_ = 0F;
 
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The endDate.
-     */
-    java.lang.String getEndDate();
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The bytes for endDate.
-     */
-    com.google.protobuf.ByteString
-        getEndDateBytes();
-  }
-  /**
-   * Protobuf type {@code monitoring.KpiQuery}
-   */
-  public static final class KpiQuery extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiQuery)
-      KpiQueryOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use KpiQuery.newBuilder() to construct.
-    private KpiQuery(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private KpiQuery() {
-      kpiId_ = java.util.Collections.emptyList();
-      startDate_ = "";
-      endDate_ = "";
-    }
+        lastNSamples_ = 0;
 
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new KpiQuery();
-    }
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
+        } else {
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
+        }
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
+        } else {
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
+        }
+        return this;
+      }
 
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private KpiQuery(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
       }
-      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)) {
-                kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              kpiId_.add(
-                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
-              break;
-            }
-            case 21: {
 
-              monitoringWindowS_ = input.readFloat();
-              break;
-            }
-            case 29: {
+      @java.lang.Override
+      public monitoring.Monitoring.KpiQuery getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiQuery.getDefaultInstance();
+      }
 
-              samplingRateS_ = input.readFloat();
-              break;
-            }
-            case 32: {
+      @java.lang.Override
+      public monitoring.Monitoring.KpiQuery build() {
+        monitoring.Monitoring.KpiQuery result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
 
-              lastNSamples_ = input.readUInt32();
-              break;
-            }
-            case 42: {
-              java.lang.String s = input.readStringRequireUtf8();
+      @java.lang.Override
+      public monitoring.Monitoring.KpiQuery buildPartial() {
+        monitoring.Monitoring.KpiQuery result = new monitoring.Monitoring.KpiQuery(this);
+        int from_bitField0_ = bitField0_;
+        if (kpiIdBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.monitoringWindowS_ = monitoringWindowS_;
+        result.samplingRateS_ = samplingRateS_;
+        result.lastNSamples_ = lastNSamples_;
+        if (startTimestampBuilder_ == null) {
+          result.startTimestamp_ = startTimestamp_;
+        } else {
+          result.startTimestamp_ = startTimestampBuilder_.build();
+        }
+        if (endTimestampBuilder_ == null) {
+          result.endTimestamp_ = endTimestamp_;
+        } else {
+          result.endTimestamp_ = endTimestampBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
 
-              startDate_ = s;
-              break;
-            }
-            case 50: {
-              java.lang.String s = input.readStringRequireUtf8();
+      @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.KpiQuery) {
+          return mergeFrom((monitoring.Monitoring.KpiQuery)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
 
-              endDate_ = s;
-              break;
+      public Builder mergeFrom(monitoring.Monitoring.KpiQuery other) {
+        if (other == monitoring.Monitoring.KpiQuery.getDefaultInstance()) return this;
+        if (kpiIdBuilder_ == null) {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiId_.isEmpty()) {
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiIdIsMutable();
+              kpiId_.addAll(other.kpiId_);
             }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
+            onChanged();
+          }
+        } else {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiIdBuilder_.isEmpty()) {
+              kpiIdBuilder_.dispose();
+              kpiIdBuilder_ = null;
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiIdBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiIdFieldBuilder() : null;
+            } else {
+              kpiIdBuilder_.addAllMessages(other.kpiId_);
             }
           }
         }
-      } 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)) {
-          kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+        if (other.getMonitoringWindowS() != 0F) {
+          setMonitoringWindowS(other.getMonitoringWindowS());
         }
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
+        if (other.getSamplingRateS() != 0F) {
+          setSamplingRateS(other.getSamplingRateS());
+        }
+        if (other.getLastNSamples() != 0) {
+          setLastNSamples(other.getLastNSamples());
+        }
+        if (other.hasStartTimestamp()) {
+          mergeStartTimestamp(other.getStartTimestamp());
+        }
+        if (other.hasEndTimestamp()) {
+          mergeEndTimestamp(other.getEndTimestamp());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
       }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
-    }
-
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
-    }
-
-    public static final int KPI_ID_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.KpiId> kpiId_;
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
-      return kpiId_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdOrBuilderList() {
-      return kpiId_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public int getKpiIdCount() {
-      return kpiId_.size();
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiId(int index) {
-      return kpiId_.get(index);
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
-        int index) {
-      return kpiId_.get(index);
-    }
-
-    public static final int MONITORING_WINDOW_S_FIELD_NUMBER = 2;
-    private float monitoringWindowS_;
-    /**
-     * <code>float monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    @java.lang.Override
-    public float getMonitoringWindowS() {
-      return monitoringWindowS_;
-    }
-
-    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
-    private float samplingRateS_;
-    /**
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    @java.lang.Override
-    public float getSamplingRateS() {
-      return samplingRateS_;
-    }
-
-    public static final int LAST_N_SAMPLES_FIELD_NUMBER = 4;
-    private int lastNSamples_;
-    /**
-     * <pre>
-     * used when you want something like "get the last N many samples
-     * </pre>
-     *
-     * <code>uint32 last_n_samples = 4;</code>
-     * @return The lastNSamples.
-     */
-    @java.lang.Override
-    public int getLastNSamples() {
-      return lastNSamples_;
-    }
 
-    public static final int START_DATE_FIELD_NUMBER = 5;
-    private volatile java.lang.Object startDate_;
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The startDate.
-     */
-    @java.lang.Override
-    public java.lang.String getStartDate() {
-      java.lang.Object ref = startDate_;
-      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();
-        startDate_ = s;
-        return s;
-      }
-    }
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The bytes for startDate.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStartDateBytes() {
-      java.lang.Object ref = startDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        startDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
       }
-    }
 
-    public static final int END_DATE_FIELD_NUMBER = 6;
-    private volatile java.lang.Object endDate_;
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The endDate.
-     */
-    @java.lang.Override
-    public java.lang.String getEndDate() {
-      java.lang.Object ref = endDate_;
-      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();
-        endDate_ = s;
-        return s;
-      }
-    }
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The bytes for endDate.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getEndDateBytes() {
-      java.lang.Object ref = endDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        endDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.KpiQuery parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.KpiQuery) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
       }
-    }
+      private int bitField0_;
 
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
+      private java.util.List<monitoring.Monitoring.KpiId> kpiId_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiIdIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiId_);
+          bitField0_ |= 0x00000001;
+         }
+      }
 
-      memoizedIsInitialized = 1;
-      return true;
-    }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
 
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      for (int i = 0; i < kpiId_.size(); i++) {
-        output.writeMessage(1, kpiId_.get(i));
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+        if (kpiIdBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        } else {
+          return kpiIdBuilder_.getMessageList();
+        }
       }
-      if (monitoringWindowS_ != 0F) {
-        output.writeFloat(2, monitoringWindowS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public int getKpiIdCount() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.size();
+        } else {
+          return kpiIdBuilder_.getCount();
+        }
       }
-      if (samplingRateS_ != 0F) {
-        output.writeFloat(3, samplingRateS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId getKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);
+        } else {
+          return kpiIdBuilder_.getMessage(index);
+        }
       }
-      if (lastNSamples_ != 0) {
-        output.writeUInt32(4, lastNSamples_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, value);
+        }
+        return this;
       }
-      if (!getStartDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, startDate_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (!getEndDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, endDate_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(value);
+        }
+        return this;
       }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      for (int i = 0; i < kpiId_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, kpiId_.get(i));
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, value);
+        }
+        return this;
       }
-      if (monitoringWindowS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(2, monitoringWindowS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
       }
-      if (samplingRateS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(3, samplingRateS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (lastNSamples_ != 0) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(4, lastNSamples_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addAllKpiId(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiId_);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiIdBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder removeKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.remove(index);
+          onChanged();
+        } else {
+          kpiIdBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
+          int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);  } else {
+          return kpiIdBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+           getKpiIdOrBuilderList() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder() {
+        return getKpiIdFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiId.getDefaultInstance());
       }
-      if (!getStartDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, startDate_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
+           getKpiIdBuilderList() {
+        return getKpiIdFieldBuilder().getBuilderList();
       }
-      if (!getEndDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, endDate_);
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  kpiId_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
       }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
 
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
+      private float monitoringWindowS_ ;
+      /**
+       * <code>float monitoring_window_s = 2;</code>
+       * @return The monitoringWindowS.
+       */
+      @java.lang.Override
+      public float getMonitoringWindowS() {
+        return monitoringWindowS_;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiQuery)) {
-        return super.equals(obj);
+      /**
+       * <code>float monitoring_window_s = 2;</code>
+       * @param value The monitoringWindowS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setMonitoringWindowS(float value) {
+        
+        monitoringWindowS_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float monitoring_window_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearMonitoringWindowS() {
+        
+        monitoringWindowS_ = 0F;
+        onChanged();
+        return this;
       }
-      monitoring.Monitoring.KpiQuery other = (monitoring.Monitoring.KpiQuery) obj;
-
-      if (!getKpiIdList()
-          .equals(other.getKpiIdList())) return false;
-      if (java.lang.Float.floatToIntBits(getMonitoringWindowS())
-          != java.lang.Float.floatToIntBits(
-              other.getMonitoringWindowS())) return false;
-      if (java.lang.Float.floatToIntBits(getSamplingRateS())
-          != java.lang.Float.floatToIntBits(
-              other.getSamplingRateS())) return false;
-      if (getLastNSamples()
-          != other.getLastNSamples()) return false;
-      if (!getStartDate()
-          .equals(other.getStartDate())) return false;
-      if (!getEndDate()
-          .equals(other.getEndDate())) return false;
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
 
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
+      private float samplingRateS_ ;
+      /**
+       * <code>float sampling_rate_s = 3;</code>
+       * @return The samplingRateS.
+       */
+      @java.lang.Override
+      public float getSamplingRateS() {
+        return samplingRateS_;
       }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      if (getKpiIdCount() > 0) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiIdList().hashCode();
+      /**
+       * <code>float sampling_rate_s = 3;</code>
+       * @param value The samplingRateS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSamplingRateS(float value) {
+        
+        samplingRateS_ = value;
+        onChanged();
+        return this;
       }
-      hash = (37 * hash) + MONITORING_WINDOW_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getMonitoringWindowS());
-      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getSamplingRateS());
-      hash = (37 * hash) + LAST_N_SAMPLES_FIELD_NUMBER;
-      hash = (53 * hash) + getLastNSamples();
-      hash = (37 * hash) + START_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getStartDate().hashCode();
-      hash = (37 * hash) + END_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getEndDate().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery 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.KpiQuery}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiQuery)
-        monitoring.Monitoring.KpiQueryOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
+      /**
+       * <code>float sampling_rate_s = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingRateS() {
+        
+        samplingRateS_ = 0F;
+        onChanged();
+        return this;
       }
 
+      private int lastNSamples_ ;
+      /**
+       * <pre>
+       * used when you want something like "get the last N many samples
+       * </pre>
+       *
+       * <code>uint32 last_n_samples = 4;</code>
+       * @return The lastNSamples.
+       */
       @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
+      public int getLastNSamples() {
+        return lastNSamples_;
       }
-
-      // Construct using monitoring.Monitoring.KpiQuery.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
+      /**
+       * <pre>
+       * used when you want something like "get the last N many samples
+       * </pre>
+       *
+       * <code>uint32 last_n_samples = 4;</code>
+       * @param value The lastNSamples to set.
+       * @return This builder for chaining.
+       */
+      public Builder setLastNSamples(int value) {
+        
+        lastNSamples_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the last N many samples
+       * </pre>
+       *
+       * <code>uint32 last_n_samples = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearLastNSamples() {
+        
+        lastNSamples_ = 0;
+        onChanged();
+        return this;
       }
 
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
+      private context.ContextOuterClass.Timestamp startTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> startTimestampBuilder_;
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return Whether the startTimestamp field is set.
+       */
+      public boolean hasStartTimestamp() {
+        return startTimestampBuilder_ != null || startTimestamp_ != null;
       }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-          getKpiIdFieldBuilder();
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return The startTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
+        } else {
+          return startTimestampBuilder_.getMessage();
         }
       }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder setStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          startTimestamp_ = value;
+          onChanged();
         } else {
-          kpiIdBuilder_.clear();
+          startTimestampBuilder_.setMessage(value);
         }
-        monitoringWindowS_ = 0F;
-
-        samplingRateS_ = 0F;
-
-        lastNSamples_ = 0;
-
-        startDate_ = "";
-
-        endDate_ = "";
 
         return this;
       }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.KpiQuery getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiQuery.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.KpiQuery build() {
-        monitoring.Monitoring.KpiQuery result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder setStartTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          startTimestampBuilder_.setMessage(builderForValue.build());
         }
-        return result;
-      }
 
-      @java.lang.Override
-      public monitoring.Monitoring.KpiQuery buildPartial() {
-        monitoring.Monitoring.KpiQuery result = new monitoring.Monitoring.KpiQuery(this);
-        int from_bitField0_ = bitField0_;
-        if (kpiIdBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
-            bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder mergeStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (startTimestamp_ != null) {
+            startTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(startTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            startTimestamp_ = value;
           }
-          result.kpiId_ = kpiId_;
+          onChanged();
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          startTimestampBuilder_.mergeFrom(value);
         }
-        result.monitoringWindowS_ = monitoringWindowS_;
-        result.samplingRateS_ = samplingRateS_;
-        result.lastNSamples_ = lastNSamples_;
-        result.startDate_ = startDate_;
-        result.endDate_ = endDate_;
-        onBuilt();
-        return result;
-      }
 
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
+        return this;
       }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder clearStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
+          onChanged();
+        } else {
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
+        }
+
+        return this;
       }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getStartTimestampBuilder() {
+        
+        onChanged();
+        return getStartTimestampFieldBuilder().getBuilder();
       }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+        if (startTimestampBuilder_ != null) {
+          return startTimestampBuilder_.getMessageOrBuilder();
+        } else {
+          return startTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
+        }
       }
-      @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>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getStartTimestampFieldBuilder() {
+        if (startTimestampBuilder_ == null) {
+          startTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getStartTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          startTimestamp_ = null;
+        }
+        return startTimestampBuilder_;
       }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
+
+      private context.ContextOuterClass.Timestamp endTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> endTimestampBuilder_;
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return Whether the endTimestamp field is set.
+       */
+      public boolean hasEndTimestamp() {
+        return endTimestampBuilder_ != null || endTimestamp_ != null;
       }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiQuery) {
-          return mergeFrom((monitoring.Monitoring.KpiQuery)other);
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return The endTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
         } else {
-          super.mergeFrom(other);
-          return this;
+          return endTimestampBuilder_.getMessage();
         }
       }
-
-      public Builder mergeFrom(monitoring.Monitoring.KpiQuery other) {
-        if (other == monitoring.Monitoring.KpiQuery.getDefaultInstance()) return this;
-        if (kpiIdBuilder_ == null) {
-          if (!other.kpiId_.isEmpty()) {
-            if (kpiId_.isEmpty()) {
-              kpiId_ = other.kpiId_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiIdIsMutable();
-              kpiId_.addAll(other.kpiId_);
-            }
-            onChanged();
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder setEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          endTimestamp_ = value;
+          onChanged();
         } else {
-          if (!other.kpiId_.isEmpty()) {
-            if (kpiIdBuilder_.isEmpty()) {
-              kpiIdBuilder_.dispose();
-              kpiIdBuilder_ = null;
-              kpiId_ = other.kpiId_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiIdBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiIdFieldBuilder() : null;
-            } else {
-              kpiIdBuilder_.addAllMessages(other.kpiId_);
-            }
-          }
-        }
-        if (other.getMonitoringWindowS() != 0F) {
-          setMonitoringWindowS(other.getMonitoringWindowS());
+          endTimestampBuilder_.setMessage(value);
         }
-        if (other.getSamplingRateS() != 0F) {
-          setSamplingRateS(other.getSamplingRateS());
-        }
-        if (other.getLastNSamples() != 0) {
-          setLastNSamples(other.getLastNSamples());
+
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder setEndTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          endTimestampBuilder_.setMessage(builderForValue.build());
         }
-        if (!other.getStartDate().isEmpty()) {
-          startDate_ = other.startDate_;
+
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder mergeEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (endTimestamp_ != null) {
+            endTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(endTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            endTimestamp_ = value;
+          }
           onChanged();
+        } else {
+          endTimestampBuilder_.mergeFrom(value);
         }
-        if (!other.getEndDate().isEmpty()) {
-          endDate_ = other.endDate_;
+
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder clearEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
           onChanged();
+        } else {
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
         }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
+
         return this;
       }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getEndTimestampBuilder() {
+        
+        onChanged();
+        return getEndTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+        if (endTimestampBuilder_ != null) {
+          return endTimestampBuilder_.getMessageOrBuilder();
+        } else {
+          return endTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
+        }
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getEndTimestampFieldBuilder() {
+        if (endTimestampBuilder_ == null) {
+          endTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getEndTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          endTimestamp_ = null;
+        }
+        return endTimestampBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
 
       @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
 
+
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiQuery)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.KpiQuery)
+    private static final monitoring.Monitoring.KpiQuery DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiQuery();
+    }
+
+    public static monitoring.Monitoring.KpiQuery getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<KpiQuery>
+        PARSER = new com.google.protobuf.AbstractParser<KpiQuery>() {
       @java.lang.Override
-      public Builder mergeFrom(
+      public KpiQuery parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        monitoring.Monitoring.KpiQuery parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiQuery) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new KpiQuery(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<KpiQuery> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<KpiQuery> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.KpiQuery 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;
+            }
           }
         }
-        return this;
+      } 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();
       }
-      private int bitField0_;
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+    }
 
-      private java.util.List<monitoring.Monitoring.KpiId> kpiId_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiIdIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiId_);
-          bitField0_ |= 0x00000001;
-         }
+    @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);
+    }
 
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
 
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
-        if (kpiIdBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiId_);
-        } else {
-          return kpiIdBuilder_.getMessageList();
-        }
+      size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public int getKpiIdCount() {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_.size();
-        } else {
-          return kpiIdBuilder_.getCount();
-        }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId getKpiId(int index) {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_.get(index);
-        } else {
-          return kpiIdBuilder_.getMessage(index);
-        }
+      if (!(obj instanceof monitoring.Monitoring.KpiId)) {
+        return super.equals(obj);
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder setKpiId(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdIsMutable();
-          kpiId_.set(index, value);
-          onChanged();
-        } else {
-          kpiIdBuilder_.setMessage(index, value);
-        }
-        return this;
+      monitoring.Monitoring.KpiId other = (monitoring.Monitoring.KpiId) obj;
+
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder setKpiId(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdIsMutable();
-          kpiId_.add(value);
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(value);
-        }
-        return this;
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdIsMutable();
-          kpiId_.add(index, value);
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(index, value);
-        }
-        return this;
+      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;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.add(builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
+
+      @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);
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
+
+      // Construct using monitoring.Monitoring.KpiId.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addAllKpiId(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiId_);
-          onChanged();
-        } else {
-          kpiIdBuilder_.addAllMessages(values);
-        }
-        return this;
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder clearKpiId() {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          kpiIdBuilder_.clear();
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
-        return this;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder removeKpiId(int index) {
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
         if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.remove(index);
-          onChanged();
+          kpiId_ = null;
         } else {
-          kpiIdBuilder_.remove(index);
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
         return this;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder(
-          int index) {
-        return getKpiIdFieldBuilder().getBuilder(index);
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
-          int index) {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_.get(index);  } else {
-          return kpiIdBuilder_.getMessageOrBuilder(index);
-        }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiId.getDefaultInstance();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-           getKpiIdOrBuilderList() {
-        if (kpiIdBuilder_ != null) {
-          return kpiIdBuilder_.getMessageOrBuilderList();
-        } else {
-          return java.util.Collections.unmodifiableList(kpiId_);
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId build() {
+        monitoring.Monitoring.KpiId result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
+        return result;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder() {
-        return getKpiIdFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder(
-          int index) {
-        return getKpiIdFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
-           getKpiIdBuilderList() {
-        return getKpiIdFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
-          getKpiIdFieldBuilder() {
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId buildPartial() {
+        monitoring.Monitoring.KpiId result = new monitoring.Monitoring.KpiId(this);
         if (kpiIdBuilder_ == null) {
-          kpiIdBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
-                  kpiId_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          kpiId_ = null;
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
         }
-        return kpiIdBuilder_;
+        onBuilt();
+        return result;
       }
 
-      private float monitoringWindowS_ ;
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return The monitoringWindowS.
-       */
       @java.lang.Override
-      public float getMonitoringWindowS() {
-        return monitoringWindowS_;
-      }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @param value The monitoringWindowS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMonitoringWindowS(float value) {
-        
-        monitoringWindowS_ = value;
-        onChanged();
-        return this;
+      public Builder clone() {
+        return super.clone();
       }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMonitoringWindowS() {
-        
-        monitoringWindowS_ = 0F;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
       }
-
-      private float samplingRateS_ ;
-      /**
-       * <code>float sampling_rate_s = 3;</code>
-       * @return The samplingRateS.
-       */
       @java.lang.Override
-      public float getSamplingRateS() {
-        return samplingRateS_;
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
       }
-      /**
-       * <code>float sampling_rate_s = 3;</code>
-       * @param value The samplingRateS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSamplingRateS(float value) {
-        
-        samplingRateS_ = value;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
       }
-      /**
-       * <code>float sampling_rate_s = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSamplingRateS() {
-        
-        samplingRateS_ = 0F;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
       }
-
-      private int lastNSamples_ ;
-      /**
-       * <pre>
-       * used when you want something like "get the last N many samples
-       * </pre>
-       *
-       * <code>uint32 last_n_samples = 4;</code>
-       * @return The lastNSamples.
-       */
       @java.lang.Override
-      public int getLastNSamples() {
-        return lastNSamples_;
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
       }
-      /**
-       * <pre>
-       * used when you want something like "get the last N many samples
-       * </pre>
-       *
-       * <code>uint32 last_n_samples = 4;</code>
-       * @param value The lastNSamples to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLastNSamples(int value) {
-        
-        lastNSamples_ = 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;
       }
-      /**
-       * <pre>
-       * used when you want something like "get the last N many samples
-       * </pre>
-       *
-       * <code>uint32 last_n_samples = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLastNSamples() {
-        
-        lastNSamples_ = 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 {
+        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 java.lang.Object startDate_ = "";
+      private context.ContextOuterClass.Uuid kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> kpiIdBuilder_;
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @return The startDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
        */
-      public java.lang.String getStartDate() {
-        java.lang.Object ref = startDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          startDate_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @return The bytes for startDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
+       * @return The kpiId.
        */
-      public com.google.protobuf.ByteString
-          getStartDateBytes() {
-        java.lang.Object ref = startDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          startDate_ = b;
-          return b;
+      public context.ContextOuterClass.Uuid getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          return kpiIdBuilder_.getMessage();
         }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @param value The startDate to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStartDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        startDate_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder clearStartDate() {
-        
-        startDate_ = getDefaultInstance().getStartDate();
-        onChanged();
+      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;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @param value The bytes for startDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder setStartDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        startDate_ = value;
-        onChanged();
+      public Builder setKpiId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
         return this;
       }
-
-      private java.lang.Object endDate_ = "";
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @return The endDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public java.lang.String getEndDate() {
-        java.lang.Object ref = endDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          endDate_ = s;
-          return s;
+      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 {
-          return (java.lang.String) ref;
+          kpiIdBuilder_.mergeFrom(value);
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @return The bytes for endDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public com.google.protobuf.ByteString
-          getEndDateBytes() {
-        java.lang.Object ref = endDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          endDate_ = b;
-          return b;
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @param value The endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder setEndDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        endDate_ = value;
+      public context.ContextOuterClass.Uuid.Builder getKpiIdBuilder() {
+        
         onChanged();
-        return this;
+        return getKpiIdFieldBuilder().getBuilder();
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder clearEndDate() {
-        
-        endDate_ = getDefaultInstance().getEndDate();
-        onChanged();
-        return this;
+      public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+        }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @param value The bytes for endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder setEndDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        endDate_ = value;
-        onChanged();
-        return this;
+      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(
@@ -7572,85 +4998,115 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiQuery)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiId)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiQuery)
-    private static final monitoring.Monitoring.KpiQuery DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiId)
+    private static final monitoring.Monitoring.KpiId DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiQuery();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiId();
     }
 
-    public static monitoring.Monitoring.KpiQuery getDefaultInstance() {
+    public static monitoring.Monitoring.KpiId getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiQuery>
-        PARSER = new com.google.protobuf.AbstractParser<KpiQuery>() {
+    private static final com.google.protobuf.Parser<KpiId>
+        PARSER = new com.google.protobuf.AbstractParser<KpiId>() {
       @java.lang.Override
-      public KpiQuery parsePartialFrom(
+      public KpiId parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiQuery(input, extensionRegistry);
+        return new KpiId(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiQuery> parser() {
+    public static com.google.protobuf.Parser<KpiId> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiQuery> getParserForType() {
+    public com.google.protobuf.Parser<KpiId> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiQuery getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiIdOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiId)
+  public interface KpiOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.Kpi)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return Whether the kpiId field is set.
      */
     boolean hasKpiId();
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return The kpiId.
      */
-    context.ContextOuterClass.Uuid getKpiId();
+    monitoring.Monitoring.KpiId getKpiId();
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder();
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return Whether the timestamp field is set.
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return The timestamp.
+     */
+    context.ContextOuterClass.Timestamp getTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder();
+
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    boolean hasKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * @return The kpiValue.
+     */
+    monitoring.Monitoring.KpiValue getKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     */
+    monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.KpiId}
+   * Protobuf type {@code monitoring.Kpi}
    */
-  public static final class KpiId extends
+  public static final class Kpi extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiId)
-      KpiIdOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.Kpi)
+      KpiOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiId.newBuilder() to construct.
-    private KpiId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use Kpi.newBuilder() to construct.
+    private Kpi(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiId() {
+    private Kpi() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiId();
+      return new Kpi();
     }
 
     @java.lang.Override
@@ -7658,7 +5114,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiId(
+    private Kpi(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -7677,11 +5133,11 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
               if (kpiId_ != null) {
                 subBuilder = kpiId_.toBuilder();
               }
-              kpiId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(kpiId_);
                 kpiId_ = subBuilder.buildPartial();
@@ -7689,6 +5145,32 @@ public final class Monitoring {
 
               break;
             }
+            case 18: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (timestamp_ != null) {
+                subBuilder = timestamp_.toBuilder();
+              }
+              timestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(timestamp_);
+                timestamp_ = subBuilder.buildPartial();
+              }
+
+              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)) {
@@ -7710,21 +5192,21 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiId_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiId.class, monitoring.Monitoring.KpiId.Builder.class);
+              monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
     }
 
     public static final int KPI_ID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid kpiId_;
+    private monitoring.Monitoring.KpiId kpiId_;
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return Whether the kpiId field is set.
      */
     @java.lang.Override
@@ -7732,21 +5214,73 @@ public final class Monitoring {
       return kpiId_ != null;
     }
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return The kpiId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getKpiId() {
-      return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
     }
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
       return getKpiId();
     }
 
+    public static final int TIMESTAMP_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.Timestamp timestamp_;
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return Whether the timestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasTimestamp() {
+      return timestamp_ != null;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getTimestamp() {
+      return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+      return getTimestamp();
+    }
+
+    public static final int KPI_VALUE_FIELD_NUMBER = 3;
+    private monitoring.Monitoring.KpiValue kpiValue_;
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiValue() {
+      return kpiValue_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</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 = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
+      return getKpiValue();
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -7764,6 +5298,12 @@ public final class Monitoring {
       if (kpiId_ != null) {
         output.writeMessage(1, getKpiId());
       }
+      if (timestamp_ != null) {
+        output.writeMessage(2, getTimestamp());
+      }
+      if (kpiValue_ != null) {
+        output.writeMessage(3, getKpiValue());
+      }
       unknownFields.writeTo(output);
     }
 
@@ -7777,6 +5317,14 @@ public final class Monitoring {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getKpiId());
       }
+      if (timestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getTimestamp());
+      }
+      if (kpiValue_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getKpiValue());
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -7787,16 +5335,26 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiId)) {
+      if (!(obj instanceof monitoring.Monitoring.Kpi)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiId other = (monitoring.Monitoring.KpiId) 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 (hasTimestamp() != other.hasTimestamp()) return false;
+      if (hasTimestamp()) {
+        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;
     }
@@ -7812,74 +5370,82 @@ public final class Monitoring {
         hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
         hash = (53 * hash) + getKpiId().hashCode();
       }
+      if (hasTimestamp()) {
+        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.KpiId parseFrom(
+    public static monitoring.Monitoring.Kpi parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiId parseFrom(
+    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.KpiId parseFrom(
+    public static monitoring.Monitoring.Kpi parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiId parseFrom(
+    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.KpiId parseFrom(byte[] data)
+    public static monitoring.Monitoring.Kpi parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiId parseFrom(
+    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.KpiId parseFrom(java.io.InputStream input)
+    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.KpiId parseFrom(
+    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.KpiId parseDelimitedFrom(java.io.InputStream input)
+    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.KpiId parseDelimitedFrom(
+    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.KpiId parseFrom(
+    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.KpiId parseFrom(
+    public static monitoring.Monitoring.Kpi parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -7892,7 +5458,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiId prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.Kpi prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -7908,26 +5474,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiId}
+     * Protobuf type {@code monitoring.Kpi}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiId)
-        monitoring.Monitoring.KpiIdOrBuilder {
+        // @@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_KpiId_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiId_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiId.class, monitoring.Monitoring.KpiId.Builder.class);
+                monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiId.newBuilder()
+      // Construct using monitoring.Monitoring.Kpi.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -7951,23 +5517,35 @@ public final class Monitoring {
           kpiId_ = null;
           kpiIdBuilder_ = null;
         }
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
+        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_KpiId_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiId.getDefaultInstance();
+      public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
+        return monitoring.Monitoring.Kpi.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiId build() {
-        monitoring.Monitoring.KpiId result = buildPartial();
+      public monitoring.Monitoring.Kpi build() {
+        monitoring.Monitoring.Kpi result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -7975,13 +5553,23 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiId buildPartial() {
-        monitoring.Monitoring.KpiId result = new monitoring.Monitoring.KpiId(this);
+      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();
         }
+        if (timestampBuilder_ == null) {
+          result.timestamp_ = timestamp_;
+        } else {
+          result.timestamp_ = timestampBuilder_.build();
+        }
+        if (kpiValueBuilder_ == null) {
+          result.kpiValue_ = kpiValue_;
+        } else {
+          result.kpiValue_ = kpiValueBuilder_.build();
+        }
         onBuilt();
         return result;
       }
@@ -8020,19 +5608,25 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiId) {
-          return mergeFrom((monitoring.Monitoring.KpiId)other);
+        if (other instanceof monitoring.Monitoring.Kpi) {
+          return mergeFrom((monitoring.Monitoring.Kpi)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.KpiId other) {
-        if (other == monitoring.Monitoring.KpiId.getDefaultInstance()) 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.hasTimestamp()) {
+          mergeTimestamp(other.getTimestamp());
+        }
+        if (other.hasKpiValue()) {
+          mergeKpiValue(other.getKpiValue());
+        }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
@@ -8048,11 +5642,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiId parsedMessage = null;
+        monitoring.Monitoring.Kpi parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiId) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.Kpi) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -8062,31 +5656,31 @@ public final class Monitoring {
         return this;
       }
 
-      private context.ContextOuterClass.Uuid kpiId_;
+      private monitoring.Monitoring.KpiId kpiId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> kpiIdBuilder_;
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId 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>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        * @return The kpiId.
        */
-      public context.ContextOuterClass.Uuid getKpiId() {
+      public monitoring.Monitoring.KpiId getKpiId() {
         if (kpiIdBuilder_ == null) {
-          return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         } else {
           return kpiIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder setKpiId(context.ContextOuterClass.Uuid value) {
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
         if (kpiIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
@@ -8100,10 +5694,10 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
       public Builder setKpiId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
         if (kpiIdBuilder_ == null) {
           kpiId_ = builderForValue.build();
           onChanged();
@@ -8114,13 +5708,13 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder mergeKpiId(context.ContextOuterClass.Uuid value) {
+      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
         if (kpiIdBuilder_ == null) {
           if (kpiId_ != null) {
             kpiId_ =
-              context.ContextOuterClass.Uuid.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
           } else {
             kpiId_ = value;
           }
@@ -8132,7 +5726,7 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
       public Builder clearKpiId() {
         if (kpiIdBuilder_ == null) {
@@ -8146,33 +5740,33 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public context.ContextOuterClass.Uuid.Builder getKpiIdBuilder() {
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
         
         onChanged();
         return getKpiIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
         if (kpiIdBuilder_ != null) {
           return kpiIdBuilder_.getMessageOrBuilder();
         } else {
           return kpiId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         }
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
           getKpiIdFieldBuilder() {
         if (kpiIdBuilder_ == null) {
           kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
                   getKpiId(),
                   getParentForChildren(),
                   isClean());
@@ -8180,6 +5774,244 @@ public final class Monitoring {
         }
         return kpiIdBuilder_;
       }
+
+      private context.ContextOuterClass.Timestamp timestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> timestampBuilder_;
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       * @return Whether the timestamp field is set.
+       */
+      public boolean hasTimestamp() {
+        return timestampBuilder_ != null || timestamp_ != null;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       * @return The timestamp.
+       */
+      public context.ContextOuterClass.Timestamp getTimestamp() {
+        if (timestampBuilder_ == null) {
+          return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        } else {
+          return timestampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder setTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          timestamp_ = value;
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder setTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (timestampBuilder_ == null) {
+          timestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder mergeTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (timestamp_ != null) {
+            timestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(timestamp_).mergeFrom(value).buildPartial();
+          } else {
+            timestamp_ = value;
+          }
+          onChanged();
+        } else {
+          timestampBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder clearTimestamp() {
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+          onChanged();
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getTimestampBuilder() {
+        
+        onChanged();
+        return getTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+        if (timestampBuilder_ != null) {
+          return timestampBuilder_.getMessageOrBuilder();
+        } else {
+          return timestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getTimestampFieldBuilder() {
+        if (timestampBuilder_ == null) {
+          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          timestamp_ = null;
+        }
+        return timestampBuilder_;
+      }
+
+      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 = 3;</code>
+       * @return Whether the kpiValue field is set.
+       */
+      public boolean hasKpiValue() {
+        return kpiValueBuilder_ != null || kpiValue_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 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 kpi_value = 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 kpi_value = 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 kpi_value = 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 kpi_value = 3;</code>
+       */
+      public Builder clearKpiValue() {
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = null;
+          onChanged();
+        } else {
+          kpiValue_ = null;
+          kpiValueBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       */
+      public monitoring.Monitoring.KpiValue.Builder getKpiValueBuilder() {
+        
+        onChanged();
+        return getKpiValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 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 kpi_value = 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) {
@@ -8193,113 +6025,130 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiId)
+      // @@protoc_insertion_point(builder_scope:monitoring.Kpi)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiId)
-    private static final monitoring.Monitoring.KpiId DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.Kpi)
+    private static final monitoring.Monitoring.Kpi DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiId();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.Kpi();
     }
 
-    public static monitoring.Monitoring.KpiId getDefaultInstance() {
+    public static monitoring.Monitoring.Kpi getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiId>
-        PARSER = new com.google.protobuf.AbstractParser<KpiId>() {
+    private static final com.google.protobuf.Parser<Kpi>
+        PARSER = new com.google.protobuf.AbstractParser<Kpi>() {
       @java.lang.Override
-      public KpiId parsePartialFrom(
+      public Kpi parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiId(input, extensionRegistry);
+        return new Kpi(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiId> parser() {
+    public static com.google.protobuf.Parser<Kpi> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiId> getParserForType() {
+    public com.google.protobuf.Parser<Kpi> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
+    public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.Kpi)
+  public interface KpiValueRangeOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiValueRange)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return Whether the kpiMinValue field is set.
      */
-    boolean hasKpiId();
+    boolean hasKpiMinValue();
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return The kpiMinValue.
      */
-    monitoring.Monitoring.KpiId getKpiId();
+    monitoring.Monitoring.KpiValue getKpiMinValue();
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
      */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+    monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder();
 
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return Whether the kpiMaxValue field is set.
      */
-    java.lang.String getTimestamp();
+    boolean hasKpiMaxValue();
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The bytes for timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return The kpiMaxValue.
      */
-    com.google.protobuf.ByteString
-        getTimestampBytes();
+    monitoring.Monitoring.KpiValue getKpiMaxValue();
+    /**
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     */
+    monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder();
 
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return Whether the kpiValue field is set.
+     * <pre>
+     * by default True
+     * </pre>
+     *
+     * <code>bool inRange = 3;</code>
+     * @return The inRange.
      */
-    boolean hasKpiValue();
+    boolean getInRange();
+
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return The kpiValue.
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMinValue = 4;</code>
+     * @return The includeMinValue.
      */
-    monitoring.Monitoring.KpiValue getKpiValue();
+    boolean getIncludeMinValue();
+
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMaxValue = 5;</code>
+     * @return The includeMaxValue.
      */
-    monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
+    boolean getIncludeMaxValue();
   }
   /**
-   * Protobuf type {@code monitoring.Kpi}
+   * Protobuf type {@code monitoring.KpiValueRange}
    */
-  public static final class Kpi extends
+  public static final class KpiValueRange extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.Kpi)
-      KpiOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiValueRange)
+      KpiValueRangeOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use Kpi.newBuilder() to construct.
-    private Kpi(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiValueRange.newBuilder() to construct.
+    private KpiValueRange(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private Kpi() {
-      timestamp_ = "";
+    private KpiValueRange() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new Kpi();
+      return new KpiValueRange();
     }
 
     @java.lang.Override
@@ -8307,7 +6156,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private Kpi(
+    private KpiValueRange(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -8326,37 +6175,46 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              monitoring.Monitoring.KpiId.Builder subBuilder = null;
-              if (kpiId_ != null) {
-                subBuilder = kpiId_.toBuilder();
+              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
+              if (kpiMinValue_ != null) {
+                subBuilder = kpiMinValue_.toBuilder();
               }
-              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              kpiMinValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiId_);
-                kpiId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(kpiMinValue_);
+                kpiMinValue_ = subBuilder.buildPartial();
               }
 
               break;
             }
             case 18: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              timestamp_ = s;
-              break;
-            }
-            case 26: {
               monitoring.Monitoring.KpiValue.Builder subBuilder = null;
-              if (kpiValue_ != null) {
-                subBuilder = kpiValue_.toBuilder();
+              if (kpiMaxValue_ != null) {
+                subBuilder = kpiMaxValue_.toBuilder();
               }
-              kpiValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
+              kpiMaxValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiValue_);
-                kpiValue_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(kpiMaxValue_);
+                kpiMaxValue_ = subBuilder.buildPartial();
               }
 
               break;
             }
+            case 24: {
+
+              inRange_ = input.readBool();
+              break;
+            }
+            case 32: {
+
+              includeMinValue_ = input.readBool();
+              break;
+            }
+            case 40: {
+
+              includeMaxValue_ = input.readBool();
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -8378,105 +6236,112 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
+              monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
     }
 
-    public static final int KPI_ID_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.KpiId kpiId_;
+    public static final int KPIMINVALUE_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiValue kpiMinValue_;
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return Whether the kpiMinValue field is set.
      */
     @java.lang.Override
-    public boolean hasKpiId() {
-      return kpiId_ != null;
+    public boolean hasKpiMinValue() {
+      return kpiMinValue_ != null;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return The kpiMinValue.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiId() {
-      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    public monitoring.Monitoring.KpiValue getKpiMinValue() {
+      return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-      return getKpiId();
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
+      return getKpiMinValue();
     }
 
-    public static final int TIMESTAMP_FIELD_NUMBER = 2;
-    private volatile java.lang.Object timestamp_;
+    public static final int KPIMAXVALUE_FIELD_NUMBER = 2;
+    private monitoring.Monitoring.KpiValue kpiMaxValue_;
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return Whether the kpiMaxValue field is set.
      */
     @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;
-      }
+    public boolean hasKpiMaxValue() {
+      return kpiMaxValue_ != null;
     }
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The bytes for timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return The kpiMaxValue.
      */
     @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 monitoring.Monitoring.KpiValue getKpiMaxValue() {
+      return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
+      return getKpiMaxValue();
     }
 
-    public static final int KPI_VALUE_FIELD_NUMBER = 3;
-    private monitoring.Monitoring.KpiValue kpiValue_;
+    public static final int INRANGE_FIELD_NUMBER = 3;
+    private boolean inRange_;
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return Whether the kpiValue field is set.
+     * <pre>
+     * by default True
+     * </pre>
+     *
+     * <code>bool inRange = 3;</code>
+     * @return The inRange.
      */
     @java.lang.Override
-    public boolean hasKpiValue() {
-      return kpiValue_ != null;
+    public boolean getInRange() {
+      return inRange_;
     }
+
+    public static final int INCLUDEMINVALUE_FIELD_NUMBER = 4;
+    private boolean includeMinValue_;
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return The kpiValue.
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMinValue = 4;</code>
+     * @return The includeMinValue.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getKpiValue() {
-      return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+    public boolean getIncludeMinValue() {
+      return includeMinValue_;
     }
+
+    public static final int INCLUDEMAXVALUE_FIELD_NUMBER = 5;
+    private boolean includeMaxValue_;
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMaxValue = 5;</code>
+     * @return The includeMaxValue.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
-      return getKpiValue();
+    public boolean getIncludeMaxValue() {
+      return includeMaxValue_;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -8493,14 +6358,20 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (kpiId_ != null) {
-        output.writeMessage(1, getKpiId());
+      if (kpiMinValue_ != null) {
+        output.writeMessage(1, getKpiMinValue());
       }
-      if (!getTimestampBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, timestamp_);
+      if (kpiMaxValue_ != null) {
+        output.writeMessage(2, getKpiMaxValue());
       }
-      if (kpiValue_ != null) {
-        output.writeMessage(3, getKpiValue());
+      if (inRange_ != false) {
+        output.writeBool(3, inRange_);
+      }
+      if (includeMinValue_ != false) {
+        output.writeBool(4, includeMinValue_);
+      }
+      if (includeMaxValue_ != false) {
+        output.writeBool(5, includeMaxValue_);
       }
       unknownFields.writeTo(output);
     }
@@ -8511,16 +6382,25 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (kpiId_ != null) {
+      if (kpiMinValue_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getKpiId());
+          .computeMessageSize(1, getKpiMinValue());
       }
-      if (!getTimestampBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, timestamp_);
+      if (kpiMaxValue_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getKpiMaxValue());
       }
-      if (kpiValue_ != null) {
+      if (inRange_ != false) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getKpiValue());
+          .computeBoolSize(3, inRange_);
+      }
+      if (includeMinValue_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(4, includeMinValue_);
+      }
+      if (includeMaxValue_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(5, includeMaxValue_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -8532,23 +6412,27 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.Kpi)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiValueRange)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.Kpi other = (monitoring.Monitoring.Kpi) obj;
+      monitoring.Monitoring.KpiValueRange other = (monitoring.Monitoring.KpiValueRange) obj;
 
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
+      if (hasKpiMinValue() != other.hasKpiMinValue()) return false;
+      if (hasKpiMinValue()) {
+        if (!getKpiMinValue()
+            .equals(other.getKpiMinValue())) 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 (hasKpiMaxValue() != other.hasKpiMaxValue()) return false;
+      if (hasKpiMaxValue()) {
+        if (!getKpiMaxValue()
+            .equals(other.getKpiMaxValue())) return false;
       }
+      if (getInRange()
+          != other.getInRange()) return false;
+      if (getIncludeMinValue()
+          != other.getIncludeMinValue()) return false;
+      if (getIncludeMaxValue()
+          != other.getIncludeMaxValue()) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -8560,84 +6444,91 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
+      if (hasKpiMinValue()) {
+        hash = (37 * hash) + KPIMINVALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiMinValue().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();
+      if (hasKpiMaxValue()) {
+        hash = (37 * hash) + KPIMAXVALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiMaxValue().hashCode();
       }
+      hash = (37 * hash) + INRANGE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+          getInRange());
+      hash = (37 * hash) + INCLUDEMINVALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+          getIncludeMinValue());
+      hash = (37 * hash) + INCLUDEMAXVALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+          getIncludeMaxValue());
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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)
+    public static monitoring.Monitoring.KpiValueRange parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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)
+    public static monitoring.Monitoring.KpiValueRange parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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)
+    public static monitoring.Monitoring.KpiValueRange parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.Kpi parseDelimitedFrom(
+    public static monitoring.Monitoring.KpiValueRange 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(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -8650,7 +6541,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.Kpi prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiValueRange prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -8666,26 +6557,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.Kpi}
+     * Protobuf type {@code monitoring.KpiValueRange}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.Kpi)
-        monitoring.Monitoring.KpiOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiValueRange)
+        monitoring.Monitoring.KpiValueRangeOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
+                monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.Kpi.newBuilder()
+      // Construct using monitoring.Monitoring.KpiValueRange.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -8703,37 +6594,41 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValue_ = null;
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          kpiMinValue_ = null;
+          kpiMinValueBuilder_ = null;
         }
-        timestamp_ = "";
-
-        if (kpiValueBuilder_ == null) {
-          kpiValue_ = null;
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValue_ = null;
         } else {
-          kpiValue_ = null;
-          kpiValueBuilder_ = null;
+          kpiMaxValue_ = null;
+          kpiMaxValueBuilder_ = null;
         }
+        inRange_ = false;
+
+        includeMinValue_ = false;
+
+        includeMaxValue_ = false;
+
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
-        return monitoring.Monitoring.Kpi.getDefaultInstance();
+      public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiValueRange.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.Kpi build() {
-        monitoring.Monitoring.Kpi result = buildPartial();
+      public monitoring.Monitoring.KpiValueRange build() {
+        monitoring.Monitoring.KpiValueRange result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -8741,19 +6636,21 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.Kpi buildPartial() {
-        monitoring.Monitoring.Kpi result = new monitoring.Monitoring.Kpi(this);
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
+      public monitoring.Monitoring.KpiValueRange buildPartial() {
+        monitoring.Monitoring.KpiValueRange result = new monitoring.Monitoring.KpiValueRange(this);
+        if (kpiMinValueBuilder_ == null) {
+          result.kpiMinValue_ = kpiMinValue_;
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          result.kpiMinValue_ = kpiMinValueBuilder_.build();
         }
-        result.timestamp_ = timestamp_;
-        if (kpiValueBuilder_ == null) {
-          result.kpiValue_ = kpiValue_;
+        if (kpiMaxValueBuilder_ == null) {
+          result.kpiMaxValue_ = kpiMaxValue_;
         } else {
-          result.kpiValue_ = kpiValueBuilder_.build();
+          result.kpiMaxValue_ = kpiMaxValueBuilder_.build();
         }
+        result.inRange_ = inRange_;
+        result.includeMinValue_ = includeMinValue_;
+        result.includeMaxValue_ = includeMaxValue_;
         onBuilt();
         return result;
       }
@@ -8792,25 +6689,30 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.Kpi) {
-          return mergeFrom((monitoring.Monitoring.Kpi)other);
+        if (other instanceof monitoring.Monitoring.KpiValueRange) {
+          return mergeFrom((monitoring.Monitoring.KpiValueRange)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());
+      public Builder mergeFrom(monitoring.Monitoring.KpiValueRange other) {
+        if (other == monitoring.Monitoring.KpiValueRange.getDefaultInstance()) return this;
+        if (other.hasKpiMinValue()) {
+          mergeKpiMinValue(other.getKpiMinValue());
         }
-        if (!other.getTimestamp().isEmpty()) {
-          timestamp_ = other.timestamp_;
-          onChanged();
+        if (other.hasKpiMaxValue()) {
+          mergeKpiMaxValue(other.getKpiMaxValue());
         }
-        if (other.hasKpiValue()) {
-          mergeKpiValue(other.getKpiValue());
+        if (other.getInRange() != false) {
+          setInRange(other.getInRange());
+        }
+        if (other.getIncludeMinValue() != false) {
+          setIncludeMinValue(other.getIncludeMinValue());
+        }
+        if (other.getIncludeMaxValue() != false) {
+          setIncludeMaxValue(other.getIncludeMaxValue());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -8827,11 +6729,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.Kpi parsedMessage = null;
+        monitoring.Monitoring.KpiValueRange parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.Kpi) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiValueRange) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -8841,318 +6743,371 @@ public final class Monitoring {
         return this;
       }
 
-      private monitoring.Monitoring.KpiId kpiId_;
+      private monitoring.Monitoring.KpiValue kpiMinValue_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMinValueBuilder_;
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
-       * @return Whether the kpiId field is set.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * @return Whether the kpiMinValue field is set.
        */
-      public boolean hasKpiId() {
-        return kpiIdBuilder_ != null || kpiId_ != null;
+      public boolean hasKpiMinValue() {
+        return kpiMinValueBuilder_ != null || kpiMinValue_ != null;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
-       * @return The kpiId.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * @return The kpiMinValue.
        */
-      public monitoring.Monitoring.KpiId getKpiId() {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+      public monitoring.Monitoring.KpiValue getKpiMinValue() {
+        if (kpiMinValueBuilder_ == null) {
+          return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
         } else {
-          return kpiIdBuilder_.getMessage();
+          return kpiMinValueBuilder_.getMessage();
         }
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
+      public Builder setKpiMinValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMinValueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          kpiId_ = value;
+          kpiMinValue_ = value;
           onChanged();
         } else {
-          kpiIdBuilder_.setMessage(value);
+          kpiMinValueBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder setKpiId(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = builderForValue.build();
+      public Builder setKpiMinValue(
+          monitoring.Monitoring.KpiValue.Builder builderForValue) {
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValue_ = builderForValue.build();
           onChanged();
         } else {
-          kpiIdBuilder_.setMessage(builderForValue.build());
+          kpiMinValueBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (kpiId_ != null) {
-            kpiId_ =
-              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+      public Builder mergeKpiMinValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMinValueBuilder_ == null) {
+          if (kpiMinValue_ != null) {
+            kpiMinValue_ =
+              monitoring.Monitoring.KpiValue.newBuilder(kpiMinValue_).mergeFrom(value).buildPartial();
           } else {
-            kpiId_ = value;
+            kpiMinValue_ = value;
           }
           onChanged();
         } else {
-          kpiIdBuilder_.mergeFrom(value);
+          kpiMinValueBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder clearKpiId() {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+      public Builder clearKpiMinValue() {
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValue_ = null;
           onChanged();
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          kpiMinValue_ = null;
+          kpiMinValueBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+      public monitoring.Monitoring.KpiValue.Builder getKpiMinValueBuilder() {
         
         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;
-        }
+        return getKpiMinValueFieldBuilder().getBuilder();
       }
       /**
-       * <code>string timestamp = 2;</code>
-       * @return The bytes for timestamp.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      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;
+      public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
+        if (kpiMinValueBuilder_ != null) {
+          return kpiMinValueBuilder_.getMessageOrBuilder();
         } 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;
+          return kpiMinValue_ == null ?
+              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
+        }
       }
       /**
-       * <code>string timestamp = 2;</code>
-       * @param value The bytes for timestamp to set.
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder setTimestampBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        timestamp_ = value;
-        onChanged();
-        return this;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
+          getKpiMinValueFieldBuilder() {
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
+                  getKpiMinValue(),
+                  getParentForChildren(),
+                  isClean());
+          kpiMinValue_ = null;
+        }
+        return kpiMinValueBuilder_;
       }
 
-      private monitoring.Monitoring.KpiValue kpiValue_;
+      private monitoring.Monitoring.KpiValue kpiMaxValue_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiValueBuilder_;
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMaxValueBuilder_;
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
-       * @return Whether the kpiValue field is set.
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * @return Whether the kpiMaxValue field is set.
        */
-      public boolean hasKpiValue() {
-        return kpiValueBuilder_ != null || kpiValue_ != null;
+      public boolean hasKpiMaxValue() {
+        return kpiMaxValueBuilder_ != null || kpiMaxValue_ != null;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
-       * @return The kpiValue.
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * @return The kpiMaxValue.
        */
-      public monitoring.Monitoring.KpiValue getKpiValue() {
-        if (kpiValueBuilder_ == null) {
-          return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+      public monitoring.Monitoring.KpiValue getKpiMaxValue() {
+        if (kpiMaxValueBuilder_ == null) {
+          return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
         } else {
-          return kpiValueBuilder_.getMessage();
+          return kpiMaxValueBuilder_.getMessage();
         }
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder setKpiValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiValueBuilder_ == null) {
+      public Builder setKpiMaxValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMaxValueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          kpiValue_ = value;
+          kpiMaxValue_ = value;
           onChanged();
         } else {
-          kpiValueBuilder_.setMessage(value);
+          kpiMaxValueBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder setKpiValue(
+      public Builder setKpiMaxValue(
           monitoring.Monitoring.KpiValue.Builder builderForValue) {
-        if (kpiValueBuilder_ == null) {
-          kpiValue_ = builderForValue.build();
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValue_ = builderForValue.build();
           onChanged();
         } else {
-          kpiValueBuilder_.setMessage(builderForValue.build());
+          kpiMaxValueBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder mergeKpiValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiValueBuilder_ == null) {
-          if (kpiValue_ != null) {
-            kpiValue_ =
-              monitoring.Monitoring.KpiValue.newBuilder(kpiValue_).mergeFrom(value).buildPartial();
+      public Builder mergeKpiMaxValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMaxValueBuilder_ == null) {
+          if (kpiMaxValue_ != null) {
+            kpiMaxValue_ =
+              monitoring.Monitoring.KpiValue.newBuilder(kpiMaxValue_).mergeFrom(value).buildPartial();
           } else {
-            kpiValue_ = value;
+            kpiMaxValue_ = value;
           }
           onChanged();
         } else {
-          kpiValueBuilder_.mergeFrom(value);
+          kpiMaxValueBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder clearKpiValue() {
-        if (kpiValueBuilder_ == null) {
-          kpiValue_ = null;
+      public Builder clearKpiMaxValue() {
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValue_ = null;
           onChanged();
         } else {
-          kpiValue_ = null;
-          kpiValueBuilder_ = null;
+          kpiMaxValue_ = null;
+          kpiMaxValueBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public monitoring.Monitoring.KpiValue.Builder getKpiValueBuilder() {
+      public monitoring.Monitoring.KpiValue.Builder getKpiMaxValueBuilder() {
         
         onChanged();
-        return getKpiValueFieldBuilder().getBuilder();
+        return getKpiMaxValueFieldBuilder().getBuilder();
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
-        if (kpiValueBuilder_ != null) {
-          return kpiValueBuilder_.getMessageOrBuilder();
+      public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
+        if (kpiMaxValueBuilder_ != null) {
+          return kpiMaxValueBuilder_.getMessageOrBuilder();
         } else {
-          return kpiValue_ == null ?
-              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+          return kpiMaxValue_ == null ?
+              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
         }
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</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<
+          getKpiMaxValueFieldBuilder() {
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
-                  getKpiValue(),
+                  getKpiMaxValue(),
                   getParentForChildren(),
                   isClean());
-          kpiValue_ = null;
+          kpiMaxValue_ = null;
         }
-        return kpiValueBuilder_;
+        return kpiMaxValueBuilder_;
+      }
+
+      private boolean inRange_ ;
+      /**
+       * <pre>
+       * by default True
+       * </pre>
+       *
+       * <code>bool inRange = 3;</code>
+       * @return The inRange.
+       */
+      @java.lang.Override
+      public boolean getInRange() {
+        return inRange_;
+      }
+      /**
+       * <pre>
+       * by default True
+       * </pre>
+       *
+       * <code>bool inRange = 3;</code>
+       * @param value The inRange to set.
+       * @return This builder for chaining.
+       */
+      public Builder setInRange(boolean value) {
+        
+        inRange_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * by default True
+       * </pre>
+       *
+       * <code>bool inRange = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearInRange() {
+        
+        inRange_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean includeMinValue_ ;
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMinValue = 4;</code>
+       * @return The includeMinValue.
+       */
+      @java.lang.Override
+      public boolean getIncludeMinValue() {
+        return includeMinValue_;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMinValue = 4;</code>
+       * @param value The includeMinValue to set.
+       * @return This builder for chaining.
+       */
+      public Builder setIncludeMinValue(boolean value) {
+        
+        includeMinValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMinValue = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearIncludeMinValue() {
+        
+        includeMinValue_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean includeMaxValue_ ;
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMaxValue = 5;</code>
+       * @return The includeMaxValue.
+       */
+      @java.lang.Override
+      public boolean getIncludeMaxValue() {
+        return includeMaxValue_;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMaxValue = 5;</code>
+       * @param value The includeMaxValue to set.
+       * @return This builder for chaining.
+       */
+      public Builder setIncludeMaxValue(boolean value) {
+        
+        includeMaxValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMaxValue = 5;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearIncludeMaxValue() {
+        
+        includeMaxValue_ = false;
+        onChanged();
+        return this;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -9167,100 +7122,155 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.Kpi)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiValueRange)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.Kpi)
-    private static final monitoring.Monitoring.Kpi DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiValueRange)
+    private static final monitoring.Monitoring.KpiValueRange DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.Kpi();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValueRange();
     }
 
-    public static monitoring.Monitoring.Kpi getDefaultInstance() {
+    public static monitoring.Monitoring.KpiValueRange getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<Kpi>
-        PARSER = new com.google.protobuf.AbstractParser<Kpi>() {
+    private static final com.google.protobuf.Parser<KpiValueRange>
+        PARSER = new com.google.protobuf.AbstractParser<KpiValueRange>() {
       @java.lang.Override
-      public Kpi parsePartialFrom(
+      public KpiValueRange parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Kpi(input, extensionRegistry);
+        return new KpiValueRange(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<Kpi> parser() {
+    public static com.google.protobuf.Parser<KpiValueRange> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<Kpi> getParserForType() {
+    public com.google.protobuf.Parser<KpiValueRange> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiValueRangeOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiValueRange)
+  public interface KpiValueOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiValue)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return Whether the kpiMinValue field is set.
+     * <code>int32 int32Val = 1;</code>
+     * @return Whether the int32Val field is set.
+     */
+    boolean hasInt32Val();
+    /**
+     * <code>int32 int32Val = 1;</code>
+     * @return The int32Val.
+     */
+    int getInt32Val();
+
+    /**
+     * <code>uint32 uint32Val = 2;</code>
+     * @return Whether the uint32Val field is set.
+     */
+    boolean hasUint32Val();
+    /**
+     * <code>uint32 uint32Val = 2;</code>
+     * @return The uint32Val.
+     */
+    int getUint32Val();
+
+    /**
+     * <code>int64 int64Val = 3;</code>
+     * @return Whether the int64Val field is set.
+     */
+    boolean hasInt64Val();
+    /**
+     * <code>int64 int64Val = 3;</code>
+     * @return The int64Val.
+     */
+    long getInt64Val();
+
+    /**
+     * <code>uint64 uint64Val = 4;</code>
+     * @return Whether the uint64Val field is set.
      */
-    boolean hasKpiMinValue();
+    boolean hasUint64Val();
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return The kpiMinValue.
+     * <code>uint64 uint64Val = 4;</code>
+     * @return The uint64Val.
      */
-    monitoring.Monitoring.KpiValue getKpiMinValue();
+    long getUint64Val();
+
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * <code>float floatVal = 5;</code>
+     * @return Whether the floatVal field is set.
      */
-    monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder();
+    boolean hasFloatVal();
+    /**
+     * <code>float floatVal = 5;</code>
+     * @return The floatVal.
+     */
+    float getFloatVal();
 
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return Whether the kpiMaxValue field is set.
+     * <code>string stringVal = 6;</code>
+     * @return Whether the stringVal field is set.
      */
-    boolean hasKpiMaxValue();
+    boolean hasStringVal();
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return The kpiMaxValue.
+     * <code>string stringVal = 6;</code>
+     * @return The stringVal.
      */
-    monitoring.Monitoring.KpiValue getKpiMaxValue();
+    java.lang.String getStringVal();
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * <code>string stringVal = 6;</code>
+     * @return The bytes for stringVal.
      */
-    monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder();
+    com.google.protobuf.ByteString
+        getStringValBytes();
+
+    /**
+     * <code>bool boolVal = 7;</code>
+     * @return Whether the boolVal field is set.
+     */
+    boolean hasBoolVal();
+    /**
+     * <code>bool boolVal = 7;</code>
+     * @return The boolVal.
+     */
+    boolean getBoolVal();
+
+    public monitoring.Monitoring.KpiValue.ValueCase getValueCase();
   }
   /**
-   * Protobuf type {@code monitoring.KpiValueRange}
+   * Protobuf type {@code monitoring.KpiValue}
    */
-  public static final class KpiValueRange extends
+  public static final class KpiValue extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiValueRange)
-      KpiValueRangeOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiValue)
+      KpiValueOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiValueRange.newBuilder() to construct.
-    private KpiValueRange(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiValue.newBuilder() to construct.
+    private KpiValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiValueRange() {
+    private KpiValue() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiValueRange();
+      return new KpiValue();
     }
 
     @java.lang.Override
@@ -9268,7 +7278,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiValueRange(
+    private KpiValue(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -9286,30 +7296,40 @@ public final class Monitoring {
             case 0:
               done = true;
               break;
-            case 10: {
-              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
-              if (kpiMinValue_ != null) {
-                subBuilder = kpiMinValue_.toBuilder();
-              }
-              kpiMinValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiMinValue_);
-                kpiMinValue_ = subBuilder.buildPartial();
-              }
-
+            case 8: {
+              valueCase_ = 1;
+              value_ = input.readInt32();
               break;
             }
-            case 18: {
-              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
-              if (kpiMaxValue_ != null) {
-                subBuilder = kpiMaxValue_.toBuilder();
-              }
-              kpiMaxValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiMaxValue_);
-                kpiMaxValue_ = subBuilder.buildPartial();
-              }
-
+            case 16: {
+              valueCase_ = 2;
+              value_ = input.readUInt32();
+              break;
+            }
+            case 24: {
+              valueCase_ = 3;
+              value_ = input.readInt64();
+              break;
+            }
+            case 32: {
+              valueCase_ = 4;
+              value_ = input.readUInt64();
+              break;
+            }
+            case 45: {
+              valueCase_ = 5;
+              value_ = input.readFloat();
+              break;
+            }
+            case 50: {
+              java.lang.String s = input.readStringRequireUtf8();
+              valueCase_ = 6;
+              value_ = s;
+              break;
+            }
+            case 56: {
+              valueCase_ = 7;
+              value_ = input.readBool();
               break;
             }
             default: {
@@ -9333,67 +7353,244 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
+              monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
     }
 
-    public static final int KPIMINVALUE_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.KpiValue kpiMinValue_;
+    private int valueCase_ = 0;
+    private java.lang.Object value_;
+    public enum ValueCase
+        implements com.google.protobuf.Internal.EnumLite,
+            com.google.protobuf.AbstractMessage.InternalOneOfEnum {
+      INT32VAL(1),
+      UINT32VAL(2),
+      INT64VAL(3),
+      UINT64VAL(4),
+      FLOATVAL(5),
+      STRINGVAL(6),
+      BOOLVAL(7),
+      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 INT32VAL;
+          case 2: return UINT32VAL;
+          case 3: return INT64VAL;
+          case 4: return UINT64VAL;
+          case 5: return FLOATVAL;
+          case 6: return STRINGVAL;
+          case 7: 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 INT32VAL_FIELD_NUMBER = 1;
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return Whether the kpiMinValue field is set.
+     * <code>int32 int32Val = 1;</code>
+     * @return Whether the int32Val field is set.
      */
     @java.lang.Override
-    public boolean hasKpiMinValue() {
-      return kpiMinValue_ != null;
+    public boolean hasInt32Val() {
+      return valueCase_ == 1;
     }
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return The kpiMinValue.
+     * <code>int32 int32Val = 1;</code>
+     * @return The int32Val.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getKpiMinValue() {
-      return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
+    public int getInt32Val() {
+      if (valueCase_ == 1) {
+        return (java.lang.Integer) value_;
+      }
+      return 0;
     }
+
+    public static final int UINT32VAL_FIELD_NUMBER = 2;
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * <code>uint32 uint32Val = 2;</code>
+     * @return Whether the uint32Val field is set.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
-      return getKpiMinValue();
+    public boolean hasUint32Val() {
+      return valueCase_ == 2;
+    }
+    /**
+     * <code>uint32 uint32Val = 2;</code>
+     * @return The uint32Val.
+     */
+    @java.lang.Override
+    public int getUint32Val() {
+      if (valueCase_ == 2) {
+        return (java.lang.Integer) value_;
+      }
+      return 0;
     }
 
-    public static final int KPIMAXVALUE_FIELD_NUMBER = 2;
-    private monitoring.Monitoring.KpiValue kpiMaxValue_;
+    public static final int INT64VAL_FIELD_NUMBER = 3;
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return Whether the kpiMaxValue field is set.
+     * <code>int64 int64Val = 3;</code>
+     * @return Whether the int64Val field is set.
      */
     @java.lang.Override
-    public boolean hasKpiMaxValue() {
-      return kpiMaxValue_ != null;
+    public boolean hasInt64Val() {
+      return valueCase_ == 3;
+    }
+    /**
+     * <code>int64 int64Val = 3;</code>
+     * @return The int64Val.
+     */
+    @java.lang.Override
+    public long getInt64Val() {
+      if (valueCase_ == 3) {
+        return (java.lang.Long) value_;
+      }
+      return 0L;
+    }
+
+    public static final int UINT64VAL_FIELD_NUMBER = 4;
+    /**
+     * <code>uint64 uint64Val = 4;</code>
+     * @return Whether the uint64Val field is set.
+     */
+    @java.lang.Override
+    public boolean hasUint64Val() {
+      return valueCase_ == 4;
+    }
+    /**
+     * <code>uint64 uint64Val = 4;</code>
+     * @return The uint64Val.
+     */
+    @java.lang.Override
+    public long getUint64Val() {
+      if (valueCase_ == 4) {
+        return (java.lang.Long) value_;
+      }
+      return 0L;
+    }
+
+    public static final int FLOATVAL_FIELD_NUMBER = 5;
+    /**
+     * <code>float floatVal = 5;</code>
+     * @return Whether the floatVal field is set.
+     */
+    @java.lang.Override
+    public boolean hasFloatVal() {
+      return valueCase_ == 5;
+    }
+    /**
+     * <code>float floatVal = 5;</code>
+     * @return The floatVal.
+     */
+    @java.lang.Override
+    public float getFloatVal() {
+      if (valueCase_ == 5) {
+        return (java.lang.Float) value_;
+      }
+      return 0F;
+    }
+
+    public static final int STRINGVAL_FIELD_NUMBER = 6;
+    /**
+     * <code>string stringVal = 6;</code>
+     * @return Whether the stringVal field is set.
+     */
+    public boolean hasStringVal() {
+      return valueCase_ == 6;
+    }
+    /**
+     * <code>string stringVal = 6;</code>
+     * @return The stringVal.
+     */
+    public java.lang.String getStringVal() {
+      java.lang.Object ref = "";
+      if (valueCase_ == 6) {
+        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_ == 6) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>string stringVal = 6;</code>
+     * @return The bytes for stringVal.
+     */
+    public com.google.protobuf.ByteString
+        getStringValBytes() {
+      java.lang.Object ref = "";
+      if (valueCase_ == 6) {
+        ref = value_;
+      }
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        if (valueCase_ == 6) {
+          value_ = b;
+        }
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
     }
+
+    public static final int BOOLVAL_FIELD_NUMBER = 7;
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return The kpiMaxValue.
+     * <code>bool boolVal = 7;</code>
+     * @return Whether the boolVal field is set.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getKpiMaxValue() {
-      return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
+    public boolean hasBoolVal() {
+      return valueCase_ == 7;
     }
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * <code>bool boolVal = 7;</code>
+     * @return The boolVal.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
-      return getKpiMaxValue();
+    public boolean getBoolVal() {
+      if (valueCase_ == 7) {
+        return (java.lang.Boolean) value_;
+      }
+      return false;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -9410,11 +7607,32 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (kpiMinValue_ != null) {
-        output.writeMessage(1, getKpiMinValue());
+      if (valueCase_ == 1) {
+        output.writeInt32(
+            1, (int)((java.lang.Integer) value_));
       }
-      if (kpiMaxValue_ != null) {
-        output.writeMessage(2, getKpiMaxValue());
+      if (valueCase_ == 2) {
+        output.writeUInt32(
+            2, (int)((java.lang.Integer) value_));
+      }
+      if (valueCase_ == 3) {
+        output.writeInt64(
+            3, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 4) {
+        output.writeUInt64(
+            4, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 5) {
+        output.writeFloat(
+            5, (float)((java.lang.Float) value_));
+      }
+      if (valueCase_ == 6) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, value_);
+      }
+      if (valueCase_ == 7) {
+        output.writeBool(
+            7, (boolean)((java.lang.Boolean) value_));
       }
       unknownFields.writeTo(output);
     }
@@ -9425,13 +7643,38 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (kpiMinValue_ != null) {
+      if (valueCase_ == 1) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getKpiMinValue());
+          .computeInt32Size(
+              1, (int)((java.lang.Integer) value_));
       }
-      if (kpiMaxValue_ != null) {
+      if (valueCase_ == 2) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, getKpiMaxValue());
+          .computeUInt32Size(
+              2, (int)((java.lang.Integer) value_));
+      }
+      if (valueCase_ == 3) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(
+              3, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 4) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt64Size(
+              4, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 5) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(
+              5, (float)((java.lang.Float) value_));
+      }
+      if (valueCase_ == 6) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, value_);
+      }
+      if (valueCase_ == 7) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(
+              7, (boolean)((java.lang.Boolean) value_));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -9443,20 +7686,44 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiValueRange)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiValue)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiValueRange other = (monitoring.Monitoring.KpiValueRange) obj;
+      monitoring.Monitoring.KpiValue other = (monitoring.Monitoring.KpiValue) obj;
 
-      if (hasKpiMinValue() != other.hasKpiMinValue()) return false;
-      if (hasKpiMinValue()) {
-        if (!getKpiMinValue()
-            .equals(other.getKpiMinValue())) return false;
-      }
-      if (hasKpiMaxValue() != other.hasKpiMaxValue()) return false;
-      if (hasKpiMaxValue()) {
-        if (!getKpiMaxValue()
-            .equals(other.getKpiMaxValue())) return false;
+      if (!getValueCase().equals(other.getValueCase())) return false;
+      switch (valueCase_) {
+        case 1:
+          if (getInt32Val()
+              != other.getInt32Val()) return false;
+          break;
+        case 2:
+          if (getUint32Val()
+              != other.getUint32Val()) return false;
+          break;
+        case 3:
+          if (getInt64Val()
+              != other.getInt64Val()) return false;
+          break;
+        case 4:
+          if (getUint64Val()
+              != other.getUint64Val()) return false;
+          break;
+        case 5:
+          if (java.lang.Float.floatToIntBits(getFloatVal())
+              != java.lang.Float.floatToIntBits(
+                  other.getFloatVal())) return false;
+          break;
+        case 6:
+          if (!getStringVal()
+              .equals(other.getStringVal())) return false;
+          break;
+        case 7:
+          if (getBoolVal()
+              != other.getBoolVal()) return false;
+          break;
+        case 0:
+        default:
       }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -9469,82 +7736,110 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasKpiMinValue()) {
-        hash = (37 * hash) + KPIMINVALUE_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiMinValue().hashCode();
-      }
-      if (hasKpiMaxValue()) {
-        hash = (37 * hash) + KPIMAXVALUE_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiMaxValue().hashCode();
+      switch (valueCase_) {
+        case 1:
+          hash = (37 * hash) + INT32VAL_FIELD_NUMBER;
+          hash = (53 * hash) + getInt32Val();
+          break;
+        case 2:
+          hash = (37 * hash) + UINT32VAL_FIELD_NUMBER;
+          hash = (53 * hash) + getUint32Val();
+          break;
+        case 3:
+          hash = (37 * hash) + INT64VAL_FIELD_NUMBER;
+          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+              getInt64Val());
+          break;
+        case 4:
+          hash = (37 * hash) + UINT64VAL_FIELD_NUMBER;
+          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+              getUint64Val());
+          break;
+        case 5:
+          hash = (37 * hash) + FLOATVAL_FIELD_NUMBER;
+          hash = (53 * hash) + java.lang.Float.floatToIntBits(
+              getFloatVal());
+          break;
+        case 6:
+          hash = (37 * hash) + STRINGVAL_FIELD_NUMBER;
+          hash = (53 * hash) + getStringVal().hashCode();
+          break;
+        case 7:
+          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.KpiValueRange parseFrom(
+    public static monitoring.Monitoring.KpiValue parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(
+    public static monitoring.Monitoring.KpiValue parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(byte[] data)
+    public static monitoring.Monitoring.KpiValue parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(java.io.InputStream input)
+    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.KpiValueRange parseFrom(
+    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.KpiValueRange parseDelimitedFrom(java.io.InputStream input)
+    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.KpiValueRange parseDelimitedFrom(
+    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.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(
+    public static monitoring.Monitoring.KpiValue parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -9557,7 +7852,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiValueRange prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiValue prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -9573,26 +7868,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiValueRange}
+     * Protobuf type {@code monitoring.KpiValue}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiValueRange)
-        monitoring.Monitoring.KpiValueRangeOrBuilder {
+        // @@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_KpiValueRange_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
+                monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiValueRange.newBuilder()
+      // Construct using monitoring.Monitoring.KpiValue.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -9610,35 +7905,25 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValue_ = null;
-        } else {
-          kpiMinValue_ = null;
-          kpiMinValueBuilder_ = null;
-        }
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValue_ = null;
-        } else {
-          kpiMaxValue_ = null;
-          kpiMaxValueBuilder_ = null;
-        }
+        valueCase_ = 0;
+        value_ = null;
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiValueRange.getDefaultInstance();
+      public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiValue.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValueRange build() {
-        monitoring.Monitoring.KpiValueRange result = buildPartial();
+      public monitoring.Monitoring.KpiValue build() {
+        monitoring.Monitoring.KpiValue result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -9646,18 +7931,30 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValueRange buildPartial() {
-        monitoring.Monitoring.KpiValueRange result = new monitoring.Monitoring.KpiValueRange(this);
-        if (kpiMinValueBuilder_ == null) {
-          result.kpiMinValue_ = kpiMinValue_;
-        } else {
-          result.kpiMinValue_ = kpiMinValueBuilder_.build();
+      public monitoring.Monitoring.KpiValue buildPartial() {
+        monitoring.Monitoring.KpiValue result = new monitoring.Monitoring.KpiValue(this);
+        if (valueCase_ == 1) {
+          result.value_ = value_;
         }
-        if (kpiMaxValueBuilder_ == null) {
-          result.kpiMaxValue_ = kpiMaxValue_;
-        } else {
-          result.kpiMaxValue_ = kpiMaxValueBuilder_.build();
+        if (valueCase_ == 2) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 3) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 4) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 5) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 6) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 7) {
+          result.value_ = value_;
         }
+        result.valueCase_ = valueCase_;
         onBuilt();
         return result;
       }
@@ -9696,21 +7993,50 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiValueRange) {
-          return mergeFrom((monitoring.Monitoring.KpiValueRange)other);
+        if (other instanceof monitoring.Monitoring.KpiValue) {
+          return mergeFrom((monitoring.Monitoring.KpiValue)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.KpiValueRange other) {
-        if (other == monitoring.Monitoring.KpiValueRange.getDefaultInstance()) return this;
-        if (other.hasKpiMinValue()) {
-          mergeKpiMinValue(other.getKpiMinValue());
-        }
-        if (other.hasKpiMaxValue()) {
-          mergeKpiMaxValue(other.getKpiMaxValue());
+      public Builder mergeFrom(monitoring.Monitoring.KpiValue other) {
+        if (other == monitoring.Monitoring.KpiValue.getDefaultInstance()) return this;
+        switch (other.getValueCase()) {
+          case INT32VAL: {
+            setInt32Val(other.getInt32Val());
+            break;
+          }
+          case UINT32VAL: {
+            setUint32Val(other.getUint32Val());
+            break;
+          }
+          case INT64VAL: {
+            setInt64Val(other.getInt64Val());
+            break;
+          }
+          case UINT64VAL: {
+            setUint64Val(other.getUint64Val());
+            break;
+          }
+          case FLOATVAL: {
+            setFloatVal(other.getFloatVal());
+            break;
+          }
+          case STRINGVAL: {
+            valueCase_ = 6;
+            value_ = other.value_;
+            onChanged();
+            break;
+          }
+          case BOOLVAL: {
+            setBoolVal(other.getBoolVal());
+            break;
+          }
+          case VALUE_NOT_SET: {
+            break;
+          }
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -9727,11 +8053,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiValueRange parsedMessage = null;
+        monitoring.Monitoring.KpiValue parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiValueRange) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiValue) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -9740,243 +8066,363 @@ public final class Monitoring {
         }
         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;
+      }
+
 
-      private monitoring.Monitoring.KpiValue kpiMinValue_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMinValueBuilder_;
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-       * @return Whether the kpiMinValue field is set.
+       * <code>int32 int32Val = 1;</code>
+       * @return Whether the int32Val field is set.
        */
-      public boolean hasKpiMinValue() {
-        return kpiMinValueBuilder_ != null || kpiMinValue_ != null;
+      public boolean hasInt32Val() {
+        return valueCase_ == 1;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-       * @return The kpiMinValue.
+       * <code>int32 int32Val = 1;</code>
+       * @return The int32Val.
        */
-      public monitoring.Monitoring.KpiValue getKpiMinValue() {
-        if (kpiMinValueBuilder_ == null) {
-          return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
-        } else {
-          return kpiMinValueBuilder_.getMessage();
+      public int getInt32Val() {
+        if (valueCase_ == 1) {
+          return (java.lang.Integer) value_;
         }
+        return 0;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>int32 int32Val = 1;</code>
+       * @param value The int32Val to set.
+       * @return This builder for chaining.
        */
-      public Builder setKpiMinValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMinValueBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          kpiMinValue_ = value;
-          onChanged();
-        } else {
-          kpiMinValueBuilder_.setMessage(value);
-        }
-
+      public Builder setInt32Val(int value) {
+        valueCase_ = 1;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>int32 int32Val = 1;</code>
+       * @return This builder for chaining.
        */
-      public Builder setKpiMinValue(
-          monitoring.Monitoring.KpiValue.Builder builderForValue) {
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValue_ = builderForValue.build();
+      public Builder clearInt32Val() {
+        if (valueCase_ == 1) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMinValueBuilder_.setMessage(builderForValue.build());
         }
+        return this;
+      }
 
+      /**
+       * <code>uint32 uint32Val = 2;</code>
+       * @return Whether the uint32Val field is set.
+       */
+      public boolean hasUint32Val() {
+        return valueCase_ == 2;
+      }
+      /**
+       * <code>uint32 uint32Val = 2;</code>
+       * @return The uint32Val.
+       */
+      public int getUint32Val() {
+        if (valueCase_ == 2) {
+          return (java.lang.Integer) value_;
+        }
+        return 0;
+      }
+      /**
+       * <code>uint32 uint32Val = 2;</code>
+       * @param value The uint32Val to set.
+       * @return This builder for chaining.
+       */
+      public Builder setUint32Val(int value) {
+        valueCase_ = 2;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint32 uint32Val = 2;</code>
+       * @return This builder for chaining.
        */
-      public Builder mergeKpiMinValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMinValueBuilder_ == null) {
-          if (kpiMinValue_ != null) {
-            kpiMinValue_ =
-              monitoring.Monitoring.KpiValue.newBuilder(kpiMinValue_).mergeFrom(value).buildPartial();
-          } else {
-            kpiMinValue_ = value;
-          }
+      public Builder clearUint32Val() {
+        if (valueCase_ == 2) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMinValueBuilder_.mergeFrom(value);
         }
+        return this;
+      }
 
+      /**
+       * <code>int64 int64Val = 3;</code>
+       * @return Whether the int64Val field is set.
+       */
+      public boolean hasInt64Val() {
+        return valueCase_ == 3;
+      }
+      /**
+       * <code>int64 int64Val = 3;</code>
+       * @return The int64Val.
+       */
+      public long getInt64Val() {
+        if (valueCase_ == 3) {
+          return (java.lang.Long) value_;
+        }
+        return 0L;
+      }
+      /**
+       * <code>int64 int64Val = 3;</code>
+       * @param value The int64Val to set.
+       * @return This builder for chaining.
+       */
+      public Builder setInt64Val(long value) {
+        valueCase_ = 3;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>int64 int64Val = 3;</code>
+       * @return This builder for chaining.
        */
-      public Builder clearKpiMinValue() {
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValue_ = null;
+      public Builder clearInt64Val() {
+        if (valueCase_ == 3) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMinValue_ = null;
-          kpiMinValueBuilder_ = null;
         }
-
         return this;
       }
+
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint64 uint64Val = 4;</code>
+       * @return Whether the uint64Val field is set.
        */
-      public monitoring.Monitoring.KpiValue.Builder getKpiMinValueBuilder() {
-        
-        onChanged();
-        return getKpiMinValueFieldBuilder().getBuilder();
+      public boolean hasUint64Val() {
+        return valueCase_ == 4;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint64 uint64Val = 4;</code>
+       * @return The uint64Val.
        */
-      public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
-        if (kpiMinValueBuilder_ != null) {
-          return kpiMinValueBuilder_.getMessageOrBuilder();
-        } else {
-          return kpiMinValue_ == null ?
-              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
+      public long getUint64Val() {
+        if (valueCase_ == 4) {
+          return (java.lang.Long) value_;
         }
+        return 0L;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint64 uint64Val = 4;</code>
+       * @param value The uint64Val to set.
+       * @return This builder for chaining.
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
-          getKpiMinValueFieldBuilder() {
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
-                  getKpiMinValue(),
-                  getParentForChildren(),
-                  isClean());
-          kpiMinValue_ = null;
+      public Builder setUint64Val(long value) {
+        valueCase_ = 4;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>uint64 uint64Val = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearUint64Val() {
+        if (valueCase_ == 4) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
         }
-        return kpiMinValueBuilder_;
+        return this;
       }
 
-      private monitoring.Monitoring.KpiValue kpiMaxValue_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMaxValueBuilder_;
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-       * @return Whether the kpiMaxValue field is set.
+       * <code>float floatVal = 5;</code>
+       * @return Whether the floatVal field is set.
        */
-      public boolean hasKpiMaxValue() {
-        return kpiMaxValueBuilder_ != null || kpiMaxValue_ != null;
+      public boolean hasFloatVal() {
+        return valueCase_ == 5;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-       * @return The kpiMaxValue.
+       * <code>float floatVal = 5;</code>
+       * @return The floatVal.
        */
-      public monitoring.Monitoring.KpiValue getKpiMaxValue() {
-        if (kpiMaxValueBuilder_ == null) {
-          return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
-        } else {
-          return kpiMaxValueBuilder_.getMessage();
+      public float getFloatVal() {
+        if (valueCase_ == 5) {
+          return (java.lang.Float) value_;
         }
+        return 0F;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>float floatVal = 5;</code>
+       * @param value The floatVal to set.
+       * @return This builder for chaining.
        */
-      public Builder setKpiMaxValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMaxValueBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          kpiMaxValue_ = value;
+      public Builder setFloatVal(float value) {
+        valueCase_ = 5;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float floatVal = 5;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearFloatVal() {
+        if (valueCase_ == 5) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMaxValueBuilder_.setMessage(value);
         }
-
         return this;
       }
+
+      /**
+       * <code>string stringVal = 6;</code>
+       * @return Whether the stringVal field is set.
+       */
+      @java.lang.Override
+      public boolean hasStringVal() {
+        return valueCase_ == 6;
+      }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @return The stringVal.
        */
-      public Builder setKpiMaxValue(
-          monitoring.Monitoring.KpiValue.Builder builderForValue) {
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValue_ = builderForValue.build();
-          onChanged();
+      @java.lang.Override
+      public java.lang.String getStringVal() {
+        java.lang.Object ref = "";
+        if (valueCase_ == 6) {
+          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_ == 6) {
+            value_ = s;
+          }
+          return s;
         } else {
-          kpiMaxValueBuilder_.setMessage(builderForValue.build());
+          return (java.lang.String) ref;
         }
-
-        return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @return The bytes for stringVal.
        */
-      public Builder mergeKpiMaxValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMaxValueBuilder_ == null) {
-          if (kpiMaxValue_ != null) {
-            kpiMaxValue_ =
-              monitoring.Monitoring.KpiValue.newBuilder(kpiMaxValue_).mergeFrom(value).buildPartial();
-          } else {
-            kpiMaxValue_ = value;
+      @java.lang.Override
+      public com.google.protobuf.ByteString
+          getStringValBytes() {
+        java.lang.Object ref = "";
+        if (valueCase_ == 6) {
+          ref = value_;
+        }
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          if (valueCase_ == 6) {
+            value_ = b;
           }
-          onChanged();
+          return b;
         } else {
-          kpiMaxValueBuilder_.mergeFrom(value);
+          return (com.google.protobuf.ByteString) ref;
         }
-
+      }
+      /**
+       * <code>string stringVal = 6;</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_ = 6;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @return This builder for chaining.
        */
-      public Builder clearKpiMaxValue() {
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValue_ = null;
+      public Builder clearStringVal() {
+        if (valueCase_ == 6) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMaxValue_ = null;
-          kpiMaxValueBuilder_ = null;
         }
-
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @param value The bytes for stringVal to set.
+       * @return This builder for chaining.
        */
-      public monitoring.Monitoring.KpiValue.Builder getKpiMaxValueBuilder() {
-        
+      public Builder setStringValBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        valueCase_ = 6;
+        value_ = value;
         onChanged();
-        return getKpiMaxValueFieldBuilder().getBuilder();
+        return this;
       }
+
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>bool boolVal = 7;</code>
+       * @return Whether the boolVal field is set.
        */
-      public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
-        if (kpiMaxValueBuilder_ != null) {
-          return kpiMaxValueBuilder_.getMessageOrBuilder();
-        } else {
-          return kpiMaxValue_ == null ?
-              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
+      public boolean hasBoolVal() {
+        return valueCase_ == 7;
+      }
+      /**
+       * <code>bool boolVal = 7;</code>
+       * @return The boolVal.
+       */
+      public boolean getBoolVal() {
+        if (valueCase_ == 7) {
+          return (java.lang.Boolean) value_;
         }
+        return false;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>bool boolVal = 7;</code>
+       * @param value The boolVal to set.
+       * @return This builder for chaining.
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
-          getKpiMaxValueFieldBuilder() {
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
-                  getKpiMaxValue(),
-                  getParentForChildren(),
-                  isClean());
-          kpiMaxValue_ = null;
+      public Builder setBoolVal(boolean value) {
+        valueCase_ = 7;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>bool boolVal = 7;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearBoolVal() {
+        if (valueCase_ == 7) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
         }
-        return kpiMaxValueBuilder_;
+        return this;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -9991,122 +8437,95 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiValueRange)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiValue)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiValueRange)
-    private static final monitoring.Monitoring.KpiValueRange DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiValue)
+    private static final monitoring.Monitoring.KpiValue DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValueRange();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValue();
     }
 
-    public static monitoring.Monitoring.KpiValueRange getDefaultInstance() {
+    public static monitoring.Monitoring.KpiValue getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiValueRange>
-        PARSER = new com.google.protobuf.AbstractParser<KpiValueRange>() {
+    private static final com.google.protobuf.Parser<KpiValue>
+        PARSER = new com.google.protobuf.AbstractParser<KpiValue>() {
       @java.lang.Override
-      public KpiValueRange parsePartialFrom(
+      public KpiValue parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiValueRange(input, extensionRegistry);
+        return new KpiValue(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiValueRange> parser() {
+    public static com.google.protobuf.Parser<KpiValue> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiValueRange> getParserForType() {
+    public com.google.protobuf.Parser<KpiValue> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiValueOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiValue)
+  public interface KpiListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiList)
       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.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    boolean hasStringVal();
+    java.util.List<monitoring.Monitoring.Kpi> 
+        getKpiListList();
     /**
-     * <code>string stringVal = 3;</code>
-     * @return The stringVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    java.lang.String getStringVal();
+    monitoring.Monitoring.Kpi getKpiList(int index);
     /**
-     * <code>string stringVal = 3;</code>
-     * @return The bytes for stringVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    com.google.protobuf.ByteString
-        getStringValBytes();
-
+    int getKpiListCount();
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return Whether the boolVal field is set.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    boolean hasBoolVal();
+    java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+        getKpiListOrBuilderList();
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return The boolVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    boolean getBoolVal();
-
-    public monitoring.Monitoring.KpiValue.ValueCase getValueCase();
+    monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+        int index);
   }
   /**
-   * Protobuf type {@code monitoring.KpiValue}
+   * Protobuf type {@code monitoring.KpiList}
    */
-  public static final class KpiValue extends
+  public static final class KpiList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiValue)
-      KpiValueOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiList)
+      KpiListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiValue.newBuilder() to construct.
-    private KpiValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiList.newBuilder() to construct.
+    private KpiList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiValue() {
+    private KpiList() {
+      kpiList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiValue();
+      return new KpiList();
     }
 
     @java.lang.Override
@@ -10114,7 +8533,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiValue(
+    private KpiList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -10122,6 +8541,7 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -10132,25 +8552,13 @@ public final class Monitoring {
             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();
+            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: {
@@ -10168,181 +8576,64 @@ public final class Monitoring {
         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_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;
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
     }
-    /**
-     * <code>uint32 intVal = 1;</code>
-     * @return The intVal.
-     */
+
     @java.lang.Override
-    public int getIntVal() {
-      if (valueCase_ == 1) {
-        return (java.lang.Integer) value_;
-      }
-      return 0;
+    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 FLOATVAL_FIELD_NUMBER = 2;
+    public static final int KPI_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.Kpi> kpiList_;
     /**
-     * <code>float floatVal = 2;</code>
-     * @return Whether the floatVal field is set.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @java.lang.Override
-    public boolean hasFloatVal() {
-      return valueCase_ == 2;
+    public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
+      return kpiList_;
     }
     /**
-     * <code>float floatVal = 2;</code>
-     * @return The floatVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @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;
-      }
+    public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+        getKpiListOrBuilderList() {
+      return kpiList_;
     }
     /**
-     * <code>string stringVal = 3;</code>
-     * @return The bytes for stringVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    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;
-      }
+    @java.lang.Override
+    public int getKpiListCount() {
+      return kpiList_.size();
     }
-
-    public static final int BOOLVAL_FIELD_NUMBER = 4;
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return Whether the boolVal field is set.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @java.lang.Override
-    public boolean hasBoolVal() {
-      return valueCase_ == 4;
+    public monitoring.Monitoring.Kpi getKpiList(int index) {
+      return kpiList_.get(index);
     }
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return The boolVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @java.lang.Override
-    public boolean getBoolVal() {
-      if (valueCase_ == 4) {
-        return (java.lang.Boolean) value_;
-      }
-      return false;
+    public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+        int index) {
+      return kpiList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -10359,20 +8650,8 @@ public final class Monitoring {
     @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_));
+      for (int i = 0; i < kpiList_.size(); i++) {
+        output.writeMessage(1, kpiList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -10383,23 +8662,9 @@ public final class Monitoring {
       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) {
+      for (int i = 0; i < kpiList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(
-              4, (boolean)((java.lang.Boolean) value_));
+          .computeMessageSize(1, kpiList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -10411,33 +8676,13 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiValue)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiList)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiValue other = (monitoring.Monitoring.KpiValue) obj;
+      monitoring.Monitoring.KpiList other = (monitoring.Monitoring.KpiList) 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 (!getKpiListList()
+          .equals(other.getKpiListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -10449,96 +8694,78 @@ public final class Monitoring {
       }
       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:
+      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.KpiValue parseFrom(
+    public static monitoring.Monitoring.KpiList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValue parseFrom(
+    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.KpiValue parseFrom(
+    public static monitoring.Monitoring.KpiList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValue parseFrom(
+    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.KpiValue parseFrom(byte[] data)
+    public static monitoring.Monitoring.KpiList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValue parseFrom(
+    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.KpiValue parseFrom(java.io.InputStream input)
+    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.KpiValue parseFrom(
+    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.KpiValue parseDelimitedFrom(java.io.InputStream input)
+    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.KpiValue parseDelimitedFrom(
+    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.KpiValue parseFrom(
+    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.KpiValue parseFrom(
+    public static monitoring.Monitoring.KpiList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -10551,7 +8778,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiValue prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -10567,26 +8794,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiValue}
+     * Protobuf type {@code monitoring.KpiList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiValue)
-        monitoring.Monitoring.KpiValueOrBuilder {
+        // @@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_KpiValue_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
+                monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiValue.newBuilder()
+      // Construct using monitoring.Monitoring.KpiList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -10599,52 +8826,54 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getKpiListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        valueCase_ = 0;
-        value_ = null;
+        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_KpiValue_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiValue.getDefaultInstance();
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValue build() {
-        monitoring.Monitoring.KpiValue result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
+      public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiList.getDefaultInstance();
       }
 
       @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_;
+      public monitoring.Monitoring.KpiList build() {
+        monitoring.Monitoring.KpiList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
-        if (valueCase_ == 4) {
-          result.value_ = value_;
+        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();
         }
-        result.valueCase_ = valueCase_;
         onBuilt();
         return result;
       }
@@ -10683,37 +8912,40 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiValue) {
-          return mergeFrom((monitoring.Monitoring.KpiValue)other);
+        if (other instanceof monitoring.Monitoring.KpiList) {
+          return mergeFrom((monitoring.Monitoring.KpiList)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_;
+      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();
-            break;
           }
-          case BOOLVAL: {
-            setBoolVal(other.getBoolVal());
-            break;
-          }
-          case VALUE_NOT_SET: {
-            break;
+        } 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);
@@ -10731,11 +8963,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiValue parsedMessage = null;
+        monitoring.Monitoring.KpiList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiValue) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -10744,240 +8976,246 @@ public final class Monitoring {
         }
         return this;
       }
-      private int valueCase_ = 0;
-      private java.lang.Object value_;
-      public ValueCase
-          getValueCase() {
-        return ValueCase.forNumber(
-            valueCase_);
-      }
+      private int bitField0_;
 
-      public Builder clearValue() {
-        valueCase_ = 0;
-        value_ = null;
-        onChanged();
-        return this;
+      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>uint32 intVal = 1;</code>
-       * @return Whether the intVal field is set.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public boolean hasIntVal() {
-        return valueCase_ == 1;
+      public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
+        if (kpiListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        } else {
+          return kpiListBuilder_.getMessageList();
+        }
       }
       /**
-       * <code>uint32 intVal = 1;</code>
-       * @return The intVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public int getIntVal() {
-        if (valueCase_ == 1) {
-          return (java.lang.Integer) value_;
+      public int getKpiListCount() {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.size();
+        } else {
+          return kpiListBuilder_.getCount();
         }
-        return 0;
       }
       /**
-       * <code>uint32 intVal = 1;</code>
-       * @param value The intVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setIntVal(int value) {
-        valueCase_ = 1;
-        value_ = value;
-        onChanged();
-        return this;
+      public monitoring.Monitoring.Kpi getKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);
+        } else {
+          return kpiListBuilder_.getMessage(index);
+        }
       }
       /**
-       * <code>uint32 intVal = 1;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearIntVal() {
-        if (valueCase_ == 1) {
-          valueCase_ = 0;
-          value_ = null;
+      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>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.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public float getFloatVal() {
-        if (valueCase_ == 2) {
-          return (java.lang.Float) value_;
+      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 0F;
+        return this;
       }
       /**
-       * <code>float floatVal = 2;</code>
-       * @param value The floatVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setFloatVal(float value) {
-        valueCase_ = 2;
-        value_ = value;
-        onChanged();
+      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>float floatVal = 2;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearFloatVal() {
-        if (valueCase_ == 2) {
-          valueCase_ = 0;
-          value_ = null;
+      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>string stringVal = 3;</code>
-       * @return Whether the stringVal field is set.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      @java.lang.Override
-      public boolean hasStringVal() {
-        return valueCase_ == 3;
+      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>string stringVal = 3;</code>
-       * @return The stringVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      @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;
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(index, builderForValue.build());
+          onChanged();
         } else {
-          return (java.lang.String) ref;
+          kpiListBuilder_.addMessage(index, builderForValue.build());
         }
+        return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @return The bytes for stringVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      @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;
+      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 {
-          return (com.google.protobuf.ByteString) ref;
+          kpiListBuilder_.addAllMessages(values);
         }
+        return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @param value The stringVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setStringVal(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  valueCase_ = 3;
-        value_ = value;
-        onChanged();
+      public Builder clearKpiList() {
+        if (kpiListBuilder_ == null) {
+          kpiList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiListBuilder_.clear();
+        }
         return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearStringVal() {
-        if (valueCase_ == 3) {
-          valueCase_ = 0;
-          value_ = null;
+      public Builder removeKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.remove(index);
           onChanged();
+        } else {
+          kpiListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @param value The bytes for stringVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setStringValBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        valueCase_ = 3;
-        value_ = value;
-        onChanged();
-        return this;
+      public monitoring.Monitoring.Kpi.Builder getKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().getBuilder(index);
       }
-
       /**
-       * <code>bool boolVal = 4;</code>
-       * @return Whether the boolVal field is set.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public boolean hasBoolVal() {
-        return valueCase_ == 4;
+      public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+          int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);  } else {
+          return kpiListBuilder_.getMessageOrBuilder(index);
+        }
       }
       /**
-       * <code>bool boolVal = 4;</code>
-       * @return The boolVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public boolean getBoolVal() {
-        if (valueCase_ == 4) {
-          return (java.lang.Boolean) value_;
+      public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+           getKpiListOrBuilderList() {
+        if (kpiListBuilder_ != null) {
+          return kpiListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiList_);
         }
-        return false;
       }
       /**
-       * <code>bool boolVal = 4;</code>
-       * @param value The boolVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setBoolVal(boolean value) {
-        valueCase_ = 4;
-        value_ = value;
-        onChanged();
-        return this;
+      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder() {
+        return getKpiListFieldBuilder().addBuilder(
+            monitoring.Monitoring.Kpi.getDefaultInstance());
       }
       /**
-       * <code>bool boolVal = 4;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearBoolVal() {
-        if (valueCase_ == 4) {
-          valueCase_ = 0;
-          value_ = null;
-          onChanged();
+      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 this;
+        return kpiListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -10992,95 +9230,95 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiValue)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiList)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiValue)
-    private static final monitoring.Monitoring.KpiValue DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiList)
+    private static final monitoring.Monitoring.KpiList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValue();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiList();
     }
 
-    public static monitoring.Monitoring.KpiValue getDefaultInstance() {
+    public static monitoring.Monitoring.KpiList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiValue>
-        PARSER = new com.google.protobuf.AbstractParser<KpiValue>() {
+    private static final com.google.protobuf.Parser<KpiList>
+        PARSER = new com.google.protobuf.AbstractParser<KpiList>() {
       @java.lang.Override
-      public KpiValue parsePartialFrom(
+      public KpiList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiValue(input, extensionRegistry);
+        return new KpiList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiValue> parser() {
+    public static com.google.protobuf.Parser<KpiList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiValue> getParserForType() {
+    public com.google.protobuf.Parser<KpiList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiList)
+  public interface KpiDescriptorListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiDescriptorList)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    java.util.List<monitoring.Monitoring.Kpi> 
-        getKpiListList();
+    java.util.List<monitoring.Monitoring.KpiDescriptor> 
+        getKpiDescriptorListList();
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    monitoring.Monitoring.Kpi getKpiList(int index);
+    monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index);
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    int getKpiListCount();
+    int getKpiDescriptorListCount();
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
-        getKpiListOrBuilderList();
+    java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
+        getKpiDescriptorListOrBuilderList();
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+    monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
         int index);
   }
   /**
-   * Protobuf type {@code monitoring.KpiList}
+   * Protobuf type {@code monitoring.KpiDescriptorList}
    */
-  public static final class KpiList extends
+  public static final class KpiDescriptorList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiList)
-      KpiListOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiDescriptorList)
+      KpiDescriptorListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiList.newBuilder() to construct.
-    private KpiList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiDescriptorList.newBuilder() to construct.
+    private KpiDescriptorList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiList() {
-      kpiList_ = java.util.Collections.emptyList();
+    private KpiDescriptorList() {
+      kpiDescriptorList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiList();
+      return new KpiDescriptorList();
     }
 
     @java.lang.Override
@@ -11088,7 +9326,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiList(
+    private KpiDescriptorList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -11109,11 +9347,11 @@ public final class Monitoring {
               break;
             case 10: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.Kpi>();
+                kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              kpiList_.add(
-                  input.readMessage(monitoring.Monitoring.Kpi.parser(), extensionRegistry));
+              kpiDescriptorList_.add(
+                  input.readMessage(monitoring.Monitoring.KpiDescriptor.parser(), extensionRegistry));
               break;
             }
             default: {
@@ -11132,7 +9370,7 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+          kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -11140,55 +9378,55 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
+              monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
     }
 
-    public static final int KPI_LIST_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.Kpi> kpiList_;
+    public static final int KPI_DESCRIPTOR_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_;
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
-      return kpiList_;
+    public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
+      return kpiDescriptorList_;
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
-        getKpiListOrBuilderList() {
-      return kpiList_;
+    public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
+        getKpiDescriptorListOrBuilderList() {
+      return kpiDescriptorList_;
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public int getKpiListCount() {
-      return kpiList_.size();
+    public int getKpiDescriptorListCount() {
+      return kpiDescriptorList_.size();
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.Kpi getKpiList(int index) {
-      return kpiList_.get(index);
+    public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
+      return kpiDescriptorList_.get(index);
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+    public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
         int index) {
-      return kpiList_.get(index);
+      return kpiDescriptorList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -11205,8 +9443,8 @@ public final class Monitoring {
     @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));
+      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
+        output.writeMessage(1, kpiDescriptorList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -11217,9 +9455,9 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      for (int i = 0; i < kpiList_.size(); i++) {
+      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, kpiList_.get(i));
+          .computeMessageSize(1, kpiDescriptorList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -11231,13 +9469,13 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiList)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiDescriptorList)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiList other = (monitoring.Monitoring.KpiList) obj;
+      monitoring.Monitoring.KpiDescriptorList other = (monitoring.Monitoring.KpiDescriptorList) obj;
 
-      if (!getKpiListList()
-          .equals(other.getKpiListList())) return false;
+      if (!getKpiDescriptorListList()
+          .equals(other.getKpiDescriptorListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -11249,78 +9487,78 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getKpiListCount() > 0) {
-        hash = (37 * hash) + KPI_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiListList().hashCode();
+      if (getKpiDescriptorListCount() > 0) {
+        hash = (37 * hash) + KPI_DESCRIPTOR_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiDescriptorListList().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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)
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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)
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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)
+    public static monitoring.Monitoring.KpiDescriptorList parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiList parseDelimitedFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -11333,7 +9571,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiList prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiDescriptorList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -11349,26 +9587,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiList}
+     * Protobuf type {@code monitoring.KpiDescriptorList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiList)
-        monitoring.Monitoring.KpiListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiDescriptorList)
+        monitoring.Monitoring.KpiDescriptorListOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
+                monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiList.newBuilder()
+      // Construct using monitoring.Monitoring.KpiDescriptorList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -11381,17 +9619,17 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiListFieldBuilder();
+          getKpiDescriptorListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+        if (kpiDescriptorListBuilder_ == null) {
+          kpiDescriptorList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          kpiListBuilder_.clear();
+          kpiDescriptorListBuilder_.clear();
         }
         return this;
       }
@@ -11399,17 +9637,17 @@ public final class Monitoring {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiList.getDefaultInstance();
+      public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiDescriptorList.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiList build() {
-        monitoring.Monitoring.KpiList result = buildPartial();
+      public monitoring.Monitoring.KpiDescriptorList build() {
+        monitoring.Monitoring.KpiDescriptorList result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -11417,17 +9655,17 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiList buildPartial() {
-        monitoring.Monitoring.KpiList result = new monitoring.Monitoring.KpiList(this);
+      public monitoring.Monitoring.KpiDescriptorList buildPartial() {
+        monitoring.Monitoring.KpiDescriptorList result = new monitoring.Monitoring.KpiDescriptorList(this);
         int from_bitField0_ = bitField0_;
-        if (kpiListBuilder_ == null) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (((bitField0_ & 0x00000001) != 0)) {
-            kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+            kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
-          result.kpiList_ = kpiList_;
+          result.kpiDescriptorList_ = kpiDescriptorList_;
         } else {
-          result.kpiList_ = kpiListBuilder_.build();
+          result.kpiDescriptorList_ = kpiDescriptorListBuilder_.build();
         }
         onBuilt();
         return result;
@@ -11467,39 +9705,39 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiList) {
-          return mergeFrom((monitoring.Monitoring.KpiList)other);
+        if (other instanceof monitoring.Monitoring.KpiDescriptorList) {
+          return mergeFrom((monitoring.Monitoring.KpiDescriptorList)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_;
+      public Builder mergeFrom(monitoring.Monitoring.KpiDescriptorList other) {
+        if (other == monitoring.Monitoring.KpiDescriptorList.getDefaultInstance()) return this;
+        if (kpiDescriptorListBuilder_ == null) {
+          if (!other.kpiDescriptorList_.isEmpty()) {
+            if (kpiDescriptorList_.isEmpty()) {
+              kpiDescriptorList_ = other.kpiDescriptorList_;
               bitField0_ = (bitField0_ & ~0x00000001);
             } else {
-              ensureKpiListIsMutable();
-              kpiList_.addAll(other.kpiList_);
+              ensureKpiDescriptorListIsMutable();
+              kpiDescriptorList_.addAll(other.kpiDescriptorList_);
             }
             onChanged();
           }
         } else {
-          if (!other.kpiList_.isEmpty()) {
-            if (kpiListBuilder_.isEmpty()) {
-              kpiListBuilder_.dispose();
-              kpiListBuilder_ = null;
-              kpiList_ = other.kpiList_;
+          if (!other.kpiDescriptorList_.isEmpty()) {
+            if (kpiDescriptorListBuilder_.isEmpty()) {
+              kpiDescriptorListBuilder_.dispose();
+              kpiDescriptorListBuilder_ = null;
+              kpiDescriptorList_ = other.kpiDescriptorList_;
               bitField0_ = (bitField0_ & ~0x00000001);
-              kpiListBuilder_ = 
+              kpiDescriptorListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiListFieldBuilder() : null;
+                   getKpiDescriptorListFieldBuilder() : null;
             } else {
-              kpiListBuilder_.addAllMessages(other.kpiList_);
+              kpiDescriptorListBuilder_.addAllMessages(other.kpiDescriptorList_);
             }
           }
         }
@@ -11518,11 +9756,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiList parsedMessage = null;
+        monitoring.Monitoring.KpiDescriptorList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiList) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiDescriptorList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -11533,244 +9771,244 @@ public final class Monitoring {
       }
       private int bitField0_;
 
-      private java.util.List<monitoring.Monitoring.Kpi> kpiList_ =
+      private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_ =
         java.util.Collections.emptyList();
-      private void ensureKpiListIsMutable() {
+      private void ensureKpiDescriptorListIsMutable() {
         if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.Kpi>(kpiList_);
+          kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>(kpiDescriptorList_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.Kpi, monitoring.Monitoring.Kpi.Builder, monitoring.Monitoring.KpiOrBuilder> kpiListBuilder_;
+          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> kpiDescriptorListBuilder_;
 
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
-        if (kpiListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiList_);
+      public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
+        if (kpiDescriptorListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
         } else {
-          return kpiListBuilder_.getMessageList();
+          return kpiDescriptorListBuilder_.getMessageList();
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public int getKpiListCount() {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.size();
+      public int getKpiDescriptorListCount() {
+        if (kpiDescriptorListBuilder_ == null) {
+          return kpiDescriptorList_.size();
         } else {
-          return kpiListBuilder_.getCount();
+          return kpiDescriptorListBuilder_.getCount();
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi getKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);
+      public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
+        if (kpiDescriptorListBuilder_ == null) {
+          return kpiDescriptorList_.get(index);
         } else {
-          return kpiListBuilder_.getMessage(index);
+          return kpiDescriptorListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.Kpi value) {
-        if (kpiListBuilder_ == null) {
+      public Builder setKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor value) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.set(index, value);
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.set(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, value);
+          kpiDescriptorListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.set(index, builderForValue.build());
+      public Builder setKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, builderForValue.build());
+          kpiDescriptorListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(monitoring.Monitoring.Kpi value) {
-        if (kpiListBuilder_ == null) {
+      public Builder addKpiDescriptorList(monitoring.Monitoring.KpiDescriptor value) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(value);
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(value);
+          kpiDescriptorListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.Kpi value) {
-        if (kpiListBuilder_ == null) {
+      public Builder addKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor value) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(index, value);
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, value);
+          kpiDescriptorListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(
-          monitoring.Monitoring.Kpi.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(builderForValue.build());
+      public Builder addKpiDescriptorList(
+          monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(builderForValue.build());
+          kpiDescriptorListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(index, builderForValue.build());
+      public Builder addKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, builderForValue.build());
+          kpiDescriptorListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addAllKpiList(
-          java.lang.Iterable<? extends monitoring.Monitoring.Kpi> values) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
+      public Builder addAllKpiDescriptorList(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiDescriptor> values) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiList_);
+              values, kpiDescriptorList_);
           onChanged();
         } else {
-          kpiListBuilder_.addAllMessages(values);
+          kpiDescriptorListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder clearKpiList() {
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+      public Builder clearKpiDescriptorList() {
+        if (kpiDescriptorListBuilder_ == null) {
+          kpiDescriptorList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          kpiListBuilder_.clear();
+          kpiDescriptorListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder removeKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.remove(index);
+      public Builder removeKpiDescriptorList(int index) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.remove(index);
           onChanged();
         } else {
-          kpiListBuilder_.remove(index);
+          kpiDescriptorListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi.Builder getKpiListBuilder(
+      public monitoring.Monitoring.KpiDescriptor.Builder getKpiDescriptorListBuilder(
           int index) {
-        return getKpiListFieldBuilder().getBuilder(index);
+        return getKpiDescriptorListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+      public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
           int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);  } else {
-          return kpiListBuilder_.getMessageOrBuilder(index);
+        if (kpiDescriptorListBuilder_ == null) {
+          return kpiDescriptorList_.get(index);  } else {
+          return kpiDescriptorListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
-           getKpiListOrBuilderList() {
-        if (kpiListBuilder_ != null) {
-          return kpiListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
+           getKpiDescriptorListOrBuilderList() {
+        if (kpiDescriptorListBuilder_ != null) {
+          return kpiDescriptorListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(kpiList_);
+          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder() {
-        return getKpiListFieldBuilder().addBuilder(
-            monitoring.Monitoring.Kpi.getDefaultInstance());
+      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder() {
+        return getKpiDescriptorListFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder(
+      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder(
           int index) {
-        return getKpiListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.Kpi.getDefaultInstance());
+        return getKpiDescriptorListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.Kpi.Builder> 
-           getKpiListBuilderList() {
-        return getKpiListFieldBuilder().getBuilderList();
+      public java.util.List<monitoring.Monitoring.KpiDescriptor.Builder> 
+           getKpiDescriptorListBuilderList() {
+        return getKpiDescriptorListFieldBuilder().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_,
+          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> 
+          getKpiDescriptorListFieldBuilder() {
+        if (kpiDescriptorListBuilder_ == null) {
+          kpiDescriptorListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder>(
+                  kpiDescriptorList_,
                   ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          kpiList_ = null;
+          kpiDescriptorList_ = null;
         }
-        return kpiListBuilder_;
+        return kpiDescriptorListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -11785,128 +10023,251 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiList)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiDescriptorList)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiList)
-    private static final monitoring.Monitoring.KpiList DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiDescriptorList)
+    private static final monitoring.Monitoring.KpiDescriptorList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiList();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiDescriptorList();
     }
 
-    public static monitoring.Monitoring.KpiList getDefaultInstance() {
+    public static monitoring.Monitoring.KpiDescriptorList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiList>
-        PARSER = new com.google.protobuf.AbstractParser<KpiList>() {
+    private static final com.google.protobuf.Parser<KpiDescriptorList>
+        PARSER = new com.google.protobuf.AbstractParser<KpiDescriptorList>() {
       @java.lang.Override
-      public KpiList parsePartialFrom(
+      public KpiDescriptorList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiList(input, extensionRegistry);
+        return new KpiDescriptorList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiList> parser() {
+    public static com.google.protobuf.Parser<KpiDescriptorList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiList> getParserForType() {
+    public com.google.protobuf.Parser<KpiDescriptorList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiDescriptorListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiDescriptorList)
+  public interface SubsDescriptorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubsDescriptor)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
-    java.util.List<monitoring.Monitoring.KpiDescriptor> 
-        getKpiDescriptorListList();
+    boolean hasSubsId();
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return The subsId.
      */
-    monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index);
+    monitoring.Monitoring.SubscriptionID getSubsId();
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
-    int getKpiDescriptorListCount();
+    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder();
+
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return Whether the kpiId field is set.
      */
-    java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
-        getKpiDescriptorListOrBuilderList();
+    boolean hasKpiId();
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return The kpiId.
      */
-    monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
-        int index);
+    monitoring.Monitoring.KpiId getKpiId();
+    /**
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>float sampling_duration_s = 3;</code>
+     * @return The samplingDurationS.
+     */
+    float getSamplingDurationS();
+
+    /**
+     * <code>float sampling_interval_s = 4;</code>
+     * @return The samplingIntervalS.
+     */
+    float getSamplingIntervalS();
+
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
+     */
+    boolean hasStartTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
+     */
+    context.ContextOuterClass.Timestamp getStartTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder();
+
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
+     */
+    boolean hasEndTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
+     */
+    context.ContextOuterClass.Timestamp getEndTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.KpiDescriptorList}
+   * Protobuf type {@code monitoring.SubsDescriptor}
    */
-  public static final class KpiDescriptorList extends
+  public static final class SubsDescriptor extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiDescriptorList)
-      KpiDescriptorListOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubsDescriptor)
+      SubsDescriptorOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiDescriptorList.newBuilder() to construct.
-    private KpiDescriptorList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubsDescriptor.newBuilder() to construct.
+    private SubsDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiDescriptorList() {
-      kpiDescriptorList_ = java.util.Collections.emptyList();
+    private SubsDescriptor() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiDescriptorList();
+      return new SubsDescriptor();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
     }
+    private SubsDescriptor(
+        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.SubscriptionID.Builder subBuilder = null;
+              if (subsId_ != null) {
+                subBuilder = subsId_.toBuilder();
+              }
+              subsId_ = input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(subsId_);
+                subsId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              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 29: {
+
+              samplingDurationS_ = input.readFloat();
+              break;
+            }
+            case 37: {
 
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private KpiDescriptorList(
-        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;
+              samplingIntervalS_ = input.readFloat();
               break;
-            case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>();
-                mutable_bitField0_ |= 0x00000001;
+            }
+            case 42: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (startTimestamp_ != null) {
+                subBuilder = startTimestamp_.toBuilder();
               }
-              kpiDescriptorList_.add(
-                  input.readMessage(monitoring.Monitoring.KpiDescriptor.parser(), extensionRegistry));
+              startTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(startTimestamp_);
+                startTimestamp_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 50: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (endTimestamp_ != null) {
+                subBuilder = endTimestamp_.toBuilder();
+              }
+              endTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(endTimestamp_);
+                endTimestamp_ = subBuilder.buildPartial();
+              }
+
               break;
             }
             default: {
@@ -11924,64 +10285,171 @@ public final class Monitoring {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
-        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
+              monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.Builder.class);
     }
 
-    public static final int KPI_DESCRIPTOR_LIST_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_;
+    public static final int SUBS_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.SubscriptionID subsId_;
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
-      return kpiDescriptorList_;
+    public boolean hasSubsId() {
+      return subsId_ != null;
     }
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return The subsId.
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
-        getKpiDescriptorListOrBuilderList() {
-      return kpiDescriptorList_;
+    public monitoring.Monitoring.SubscriptionID getSubsId() {
+      return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
     }
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
     @java.lang.Override
-    public int getKpiDescriptorListCount() {
-      return kpiDescriptorList_.size();
+    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
+      return getSubsId();
     }
+
+    public static final int KPI_ID_FIELD_NUMBER = 2;
+    private monitoring.Monitoring.KpiId kpiId_;
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return Whether the kpiId field is set.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
-      return kpiDescriptorList_.get(index);
+    public boolean hasKpiId() {
+      return kpiId_ != null;
     }
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return The kpiId.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
-        int index) {
-      return kpiDescriptorList_.get(index);
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    }
+    /**
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
+    }
+
+    public static final int SAMPLING_DURATION_S_FIELD_NUMBER = 3;
+    private float samplingDurationS_;
+    /**
+     * <code>float sampling_duration_s = 3;</code>
+     * @return The samplingDurationS.
+     */
+    @java.lang.Override
+    public float getSamplingDurationS() {
+      return samplingDurationS_;
+    }
+
+    public static final int SAMPLING_INTERVAL_S_FIELD_NUMBER = 4;
+    private float samplingIntervalS_;
+    /**
+     * <code>float sampling_interval_s = 4;</code>
+     * @return The samplingIntervalS.
+     */
+    @java.lang.Override
+    public float getSamplingIntervalS() {
+      return samplingIntervalS_;
+    }
+
+    public static final int START_TIMESTAMP_FIELD_NUMBER = 5;
+    private context.ContextOuterClass.Timestamp startTimestamp_;
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasStartTimestamp() {
+      return startTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getStartTimestamp() {
+      return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+      return getStartTimestamp();
+    }
+
+    public static final int END_TIMESTAMP_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.Timestamp endTimestamp_;
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasEndTimestamp() {
+      return endTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getEndTimestamp() {
+      return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+      return getEndTimestamp();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -11998,8 +10466,23 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
-        output.writeMessage(1, kpiDescriptorList_.get(i));
+      if (subsId_ != null) {
+        output.writeMessage(1, getSubsId());
+      }
+      if (kpiId_ != null) {
+        output.writeMessage(2, getKpiId());
+      }
+      if (samplingDurationS_ != 0F) {
+        output.writeFloat(3, samplingDurationS_);
+      }
+      if (samplingIntervalS_ != 0F) {
+        output.writeFloat(4, samplingIntervalS_);
+      }
+      if (startTimestamp_ != null) {
+        output.writeMessage(5, getStartTimestamp());
+      }
+      if (endTimestamp_ != null) {
+        output.writeMessage(6, getEndTimestamp());
       }
       unknownFields.writeTo(output);
     }
@@ -12010,9 +10493,29 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
+      if (subsId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, kpiDescriptorList_.get(i));
+          .computeMessageSize(1, getSubsId());
+      }
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getKpiId());
+      }
+      if (samplingDurationS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, samplingDurationS_);
+      }
+      if (samplingIntervalS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(4, samplingIntervalS_);
+      }
+      if (startTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, getStartTimestamp());
+      }
+      if (endTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getEndTimestamp());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -12024,13 +10527,37 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiDescriptorList)) {
+      if (!(obj instanceof monitoring.Monitoring.SubsDescriptor)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiDescriptorList other = (monitoring.Monitoring.KpiDescriptorList) obj;
+      monitoring.Monitoring.SubsDescriptor other = (monitoring.Monitoring.SubsDescriptor) obj;
 
-      if (!getKpiDescriptorListList()
-          .equals(other.getKpiDescriptorListList())) return false;
+      if (hasSubsId() != other.hasSubsId()) return false;
+      if (hasSubsId()) {
+        if (!getSubsId()
+            .equals(other.getSubsId())) return false;
+      }
+      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 (hasStartTimestamp() != other.hasStartTimestamp()) return false;
+      if (hasStartTimestamp()) {
+        if (!getStartTimestamp()
+            .equals(other.getStartTimestamp())) return false;
+      }
+      if (hasEndTimestamp() != other.hasEndTimestamp()) return false;
+      if (hasEndTimestamp()) {
+        if (!getEndTimestamp()
+            .equals(other.getEndTimestamp())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -12042,78 +10569,96 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getKpiDescriptorListCount() > 0) {
-        hash = (37 * hash) + KPI_DESCRIPTOR_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiDescriptorListList().hashCode();
+      if (hasSubsId()) {
+        hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSubsId().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());
+      if (hasStartTimestamp()) {
+        hash = (37 * hash) + START_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getStartTimestamp().hashCode();
+      }
+      if (hasEndTimestamp()) {
+        hash = (37 * hash) + END_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getEndTimestamp().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor 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.KpiDescriptorList parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor 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.KpiDescriptorList parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsDescriptor parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseDelimitedFrom(
+    public static monitoring.Monitoring.SubsDescriptor 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.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -12126,7 +10671,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiDescriptorList prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubsDescriptor prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -12142,26 +10687,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiDescriptorList}
+     * Protobuf type {@code monitoring.SubsDescriptor}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiDescriptorList)
-        monitoring.Monitoring.KpiDescriptorListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubsDescriptor)
+        monitoring.Monitoring.SubsDescriptorOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
+                monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiDescriptorList.newBuilder()
+      // Construct using monitoring.Monitoring.SubsDescriptor.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -12174,17 +10719,38 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiDescriptorListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiDescriptorListBuilder_ == null) {
-          kpiDescriptorList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
         } else {
-          kpiDescriptorListBuilder_.clear();
+          subsId_ = null;
+          subsIdBuilder_ = null;
+        }
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+        samplingDurationS_ = 0F;
+
+        samplingIntervalS_ = 0F;
+
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
+        } else {
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
+        }
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
+        } else {
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
         }
         return this;
       }
@@ -12192,17 +10758,17 @@ public final class Monitoring {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiDescriptorList.getDefaultInstance();
+      public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubsDescriptor.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiDescriptorList build() {
-        monitoring.Monitoring.KpiDescriptorList result = buildPartial();
+      public monitoring.Monitoring.SubsDescriptor build() {
+        monitoring.Monitoring.SubsDescriptor result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -12210,17 +10776,29 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiDescriptorList buildPartial() {
-        monitoring.Monitoring.KpiDescriptorList result = new monitoring.Monitoring.KpiDescriptorList(this);
-        int from_bitField0_ = bitField0_;
-        if (kpiDescriptorListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.kpiDescriptorList_ = kpiDescriptorList_;
+      public monitoring.Monitoring.SubsDescriptor buildPartial() {
+        monitoring.Monitoring.SubsDescriptor result = new monitoring.Monitoring.SubsDescriptor(this);
+        if (subsIdBuilder_ == null) {
+          result.subsId_ = subsId_;
         } else {
-          result.kpiDescriptorList_ = kpiDescriptorListBuilder_.build();
+          result.subsId_ = subsIdBuilder_.build();
+        }
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.samplingDurationS_ = samplingDurationS_;
+        result.samplingIntervalS_ = samplingIntervalS_;
+        if (startTimestampBuilder_ == null) {
+          result.startTimestamp_ = startTimestamp_;
+        } else {
+          result.startTimestamp_ = startTimestampBuilder_.build();
+        }
+        if (endTimestampBuilder_ == null) {
+          result.endTimestamp_ = endTimestamp_;
+        } else {
+          result.endTimestamp_ = endTimestampBuilder_.build();
         }
         onBuilt();
         return result;
@@ -12258,312 +10836,673 @@ public final class Monitoring {
           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.KpiDescriptorList) {
-          return mergeFrom((monitoring.Monitoring.KpiDescriptorList)other);
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.SubsDescriptor) {
+          return mergeFrom((monitoring.Monitoring.SubsDescriptor)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.SubsDescriptor other) {
+        if (other == monitoring.Monitoring.SubsDescriptor.getDefaultInstance()) return this;
+        if (other.hasSubsId()) {
+          mergeSubsId(other.getSubsId());
+        }
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
+        if (other.getSamplingDurationS() != 0F) {
+          setSamplingDurationS(other.getSamplingDurationS());
+        }
+        if (other.getSamplingIntervalS() != 0F) {
+          setSamplingIntervalS(other.getSamplingIntervalS());
+        }
+        if (other.hasStartTimestamp()) {
+          mergeStartTimestamp(other.getStartTimestamp());
+        }
+        if (other.hasEndTimestamp()) {
+          mergeEndTimestamp(other.getEndTimestamp());
+        }
+        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.SubsDescriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.SubsDescriptor) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private monitoring.Monitoring.SubscriptionID subsId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsIdBuilder_;
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return Whether the subsId field is set.
+       */
+      public boolean hasSubsId() {
+        return subsIdBuilder_ != null || subsId_ != null;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return The subsId.
+       */
+      public monitoring.Monitoring.SubscriptionID getSubsId() {
+        if (subsIdBuilder_ == null) {
+          return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        } else {
+          return subsIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          subsId_ = value;
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(
+          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsIdBuilder_ == null) {
+          subsId_ = builderForValue.build();
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder mergeSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (subsId_ != null) {
+            subsId_ =
+              monitoring.Monitoring.SubscriptionID.newBuilder(subsId_).mergeFrom(value).buildPartial();
+          } else {
+            subsId_ = value;
+          }
+          onChanged();
+        } else {
+          subsIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder clearSubsId() {
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
+          onChanged();
+        } else {
+          subsId_ = null;
+          subsIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionID.Builder getSubsIdBuilder() {
+        
+        onChanged();
+        return getSubsIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
+        if (subsIdBuilder_ != null) {
+          return subsIdBuilder_.getMessageOrBuilder();
+        } else {
+          return subsId_ == null ?
+              monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
+          getSubsIdFieldBuilder() {
+        if (subsIdBuilder_ == null) {
+          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
+                  getSubsId(),
+                  getParentForChildren(),
+                  isClean());
+          subsId_ = null;
+        }
+        return subsIdBuilder_;
+      }
+
+      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 = 2;</code>
+       * @return Whether the kpiId field is set.
+       */
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       * @return The kpiId.
+       */
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         } else {
-          super.mergeFrom(other);
-          return this;
+          return kpiIdBuilder_.getMessage();
         }
       }
-
-      public Builder mergeFrom(monitoring.Monitoring.KpiDescriptorList other) {
-        if (other == monitoring.Monitoring.KpiDescriptorList.getDefaultInstance()) return this;
-        if (kpiDescriptorListBuilder_ == null) {
-          if (!other.kpiDescriptorList_.isEmpty()) {
-            if (kpiDescriptorList_.isEmpty()) {
-              kpiDescriptorList_ = other.kpiDescriptorList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiDescriptorListIsMutable();
-              kpiDescriptorList_.addAll(other.kpiDescriptorList_);
-            }
-            onChanged();
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       */
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          kpiId_ = value;
+          onChanged();
         } else {
-          if (!other.kpiDescriptorList_.isEmpty()) {
-            if (kpiDescriptorListBuilder_.isEmpty()) {
-              kpiDescriptorListBuilder_.dispose();
-              kpiDescriptorListBuilder_ = null;
-              kpiDescriptorList_ = other.kpiDescriptorList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiDescriptorListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiDescriptorListFieldBuilder() : null;
-            } else {
-              kpiDescriptorListBuilder_.addAllMessages(other.kpiDescriptorList_);
-            }
-          }
+          kpiIdBuilder_.setMessage(value);
         }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
+
         return this;
       }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       */
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
 
-      @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
+        return this;
       }
-
-      @java.lang.Override
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        monitoring.Monitoring.KpiDescriptorList parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiDescriptorList) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</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;
-      }
-      private int bitField0_;
 
-      private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiDescriptorListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>(kpiDescriptorList_);
-          bitField0_ |= 0x00000001;
-         }
+        return this;
       }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> kpiDescriptorListBuilder_;
-
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
-        if (kpiDescriptorListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
         } else {
-          return kpiDescriptorListBuilder_.getMessageList();
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
        */
-      public int getKpiDescriptorListCount() {
-        if (kpiDescriptorListBuilder_ == null) {
-          return kpiDescriptorList_.size();
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
         } else {
-          return kpiDescriptorListBuilder_.getCount();
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         }
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
-        if (kpiDescriptorListBuilder_ == null) {
-          return kpiDescriptorList_.get(index);
-        } else {
-          return kpiDescriptorListBuilder_.getMessage(index);
+      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>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>float sampling_duration_s = 3;</code>
+       * @return The samplingDurationS.
        */
-      public Builder setKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor value) {
-        if (kpiDescriptorListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.set(index, value);
-          onChanged();
+      @java.lang.Override
+      public float getSamplingDurationS() {
+        return samplingDurationS_;
+      }
+      /**
+       * <code>float sampling_duration_s = 3;</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 = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingDurationS() {
+        
+        samplingDurationS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float samplingIntervalS_ ;
+      /**
+       * <code>float sampling_interval_s = 4;</code>
+       * @return The samplingIntervalS.
+       */
+      @java.lang.Override
+      public float getSamplingIntervalS() {
+        return samplingIntervalS_;
+      }
+      /**
+       * <code>float sampling_interval_s = 4;</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 = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingIntervalS() {
+        
+        samplingIntervalS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private context.ContextOuterClass.Timestamp startTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> startTimestampBuilder_;
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return Whether the startTimestamp field is set.
+       */
+      public boolean hasStartTimestamp() {
+        return startTimestampBuilder_ != null || startTimestamp_ != null;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return The startTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
         } else {
-          kpiDescriptorListBuilder_.setMessage(index, value);
+          return startTimestampBuilder_.getMessage();
         }
-        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder setKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.set(index, builderForValue.build());
+      public Builder setStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          startTimestamp_ = value;
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.setMessage(index, builderForValue.build());
+          startTimestampBuilder_.setMessage(value);
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(monitoring.Monitoring.KpiDescriptor value) {
-        if (kpiDescriptorListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(value);
+      public Builder setStartTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = builderForValue.build();
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.addMessage(value);
+          startTimestampBuilder_.setMessage(builderForValue.build());
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor value) {
-        if (kpiDescriptorListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
+      public Builder mergeStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (startTimestamp_ != null) {
+            startTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(startTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            startTimestamp_ = value;
           }
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(index, value);
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.addMessage(index, value);
+          startTimestampBuilder_.mergeFrom(value);
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(
-          monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(builderForValue.build());
+      public Builder clearStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.addMessage(builderForValue.build());
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(index, builderForValue.build());
-          onChanged();
+      public context.ContextOuterClass.Timestamp.Builder getStartTimestampBuilder() {
+        
+        onChanged();
+        return getStartTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+        if (startTimestampBuilder_ != null) {
+          return startTimestampBuilder_.getMessageOrBuilder();
         } else {
-          kpiDescriptorListBuilder_.addMessage(index, builderForValue.build());
+          return startTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
         }
-        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addAllKpiDescriptorList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiDescriptor> values) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiDescriptorList_);
-          onChanged();
-        } else {
-          kpiDescriptorListBuilder_.addAllMessages(values);
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getStartTimestampFieldBuilder() {
+        if (startTimestampBuilder_ == null) {
+          startTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getStartTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          startTimestamp_ = null;
         }
-        return this;
+        return startTimestampBuilder_;
       }
+
+      private context.ContextOuterClass.Timestamp endTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> endTimestampBuilder_;
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return Whether the endTimestamp field is set.
        */
-      public Builder clearKpiDescriptorList() {
-        if (kpiDescriptorListBuilder_ == null) {
-          kpiDescriptorList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
+      public boolean hasEndTimestamp() {
+        return endTimestampBuilder_ != null || endTimestamp_ != null;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return The endTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
         } else {
-          kpiDescriptorListBuilder_.clear();
+          return endTimestampBuilder_.getMessage();
         }
-        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public Builder removeKpiDescriptorList(int index) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.remove(index);
+      public Builder setEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          endTimestamp_ = value;
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.remove(index);
+          endTimestampBuilder_.setMessage(value);
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor.Builder getKpiDescriptorListBuilder(
-          int index) {
-        return getKpiDescriptorListFieldBuilder().getBuilder(index);
+      public Builder setEndTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          endTimestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
-          int index) {
-        if (kpiDescriptorListBuilder_ == null) {
-          return kpiDescriptorList_.get(index);  } else {
-          return kpiDescriptorListBuilder_.getMessageOrBuilder(index);
+      public Builder mergeEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (endTimestamp_ != null) {
+            endTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(endTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            endTimestamp_ = value;
+          }
+          onChanged();
+        } else {
+          endTimestampBuilder_.mergeFrom(value);
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
-           getKpiDescriptorListOrBuilderList() {
-        if (kpiDescriptorListBuilder_ != null) {
-          return kpiDescriptorListBuilder_.getMessageOrBuilderList();
+      public Builder clearEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
+          onChanged();
         } else {
-          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder() {
-        return getKpiDescriptorListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
+      public context.ContextOuterClass.Timestamp.Builder getEndTimestampBuilder() {
+        
+        onChanged();
+        return getEndTimestampFieldBuilder().getBuilder();
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder(
-          int index) {
-        return getKpiDescriptorListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
+      public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+        if (endTimestampBuilder_ != null) {
+          return endTimestampBuilder_.getMessageOrBuilder();
+        } else {
+          return endTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
+        }
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiDescriptor.Builder> 
-           getKpiDescriptorListBuilderList() {
-        return getKpiDescriptorListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> 
-          getKpiDescriptorListFieldBuilder() {
-        if (kpiDescriptorListBuilder_ == null) {
-          kpiDescriptorListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder>(
-                  kpiDescriptorList_,
-                  ((bitField0_ & 0x00000001) != 0),
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getEndTimestampFieldBuilder() {
+        if (endTimestampBuilder_ == null) {
+          endTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getEndTimestamp(),
                   getParentForChildren(),
                   isClean());
-          kpiDescriptorList_ = null;
+          endTimestamp_ = null;
         }
-        return kpiDescriptorListBuilder_;
+        return endTimestampBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -12578,139 +11517,85 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiDescriptorList)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubsDescriptor)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiDescriptorList)
-    private static final monitoring.Monitoring.KpiDescriptorList DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubsDescriptor)
+    private static final monitoring.Monitoring.SubsDescriptor DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiDescriptorList();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsDescriptor();
     }
 
-    public static monitoring.Monitoring.KpiDescriptorList getDefaultInstance() {
+    public static monitoring.Monitoring.SubsDescriptor getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiDescriptorList>
-        PARSER = new com.google.protobuf.AbstractParser<KpiDescriptorList>() {
+    private static final com.google.protobuf.Parser<SubsDescriptor>
+        PARSER = new com.google.protobuf.AbstractParser<SubsDescriptor>() {
       @java.lang.Override
-      public KpiDescriptorList parsePartialFrom(
+      public SubsDescriptor parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiDescriptorList(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<KpiDescriptorList> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<KpiDescriptorList> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface SubsDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubsDescriptor)
-      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();
+        return new SubsDescriptor(input, extensionRegistry);
+      }
+    };
 
-    /**
-     * <code>float sampling_duration_s = 2;</code>
-     * @return The samplingDurationS.
-     */
-    float getSamplingDurationS();
+    public static com.google.protobuf.Parser<SubsDescriptor> parser() {
+      return PARSER;
+    }
 
-    /**
-     * <code>float sampling_interval_s = 3;</code>
-     * @return The samplingIntervalS.
-     */
-    float getSamplingIntervalS();
+    @java.lang.Override
+    public com.google.protobuf.Parser<SubsDescriptor> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SubscriptionIDOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubscriptionID)
+      com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The startDate.
-     */
-    java.lang.String getStartDate();
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The bytes for startDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
-    com.google.protobuf.ByteString
-        getStartDateBytes();
-
+    boolean hasSubsId();
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return The subsId.
      */
-    java.lang.String getEndDate();
+    context.ContextOuterClass.Uuid getSubsId();
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The bytes for endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
      */
-    com.google.protobuf.ByteString
-        getEndDateBytes();
+    context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.SubsDescriptor}
+   * Protobuf type {@code monitoring.SubscriptionID}
    */
-  public static final class SubsDescriptor extends
+  public static final class SubscriptionID extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubsDescriptor)
-      SubsDescriptorOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubscriptionID)
+      SubscriptionIDOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubsDescriptor.newBuilder() to construct.
-    private SubsDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubscriptionID.newBuilder() to construct.
+    private SubscriptionID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubsDescriptor() {
-      startDate_ = "";
-      endDate_ = "";
+    private SubscriptionID() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubsDescriptor();
+      return new SubscriptionID();
     }
 
     @java.lang.Override
@@ -12718,7 +11603,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubsDescriptor(
+    private SubscriptionID(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -12737,40 +11622,18 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              monitoring.Monitoring.KpiId.Builder subBuilder = null;
-              if (kpiId_ != null) {
-                subBuilder = kpiId_.toBuilder();
+              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              if (subsId_ != null) {
+                subBuilder = subsId_.toBuilder();
               }
-              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              subsId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiId_);
-                kpiId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(subsId_);
+                subsId_ = subBuilder.buildPartial();
               }
 
               break;
             }
-            case 21: {
-
-              samplingDurationS_ = input.readFloat();
-              break;
-            }
-            case 29: {
-
-              samplingIntervalS_ = input.readFloat();
-              break;
-            }
-            case 34: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              startDate_ = s;
-              break;
-            }
-            case 42: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              endDate_ = s;
-              break;
-            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -12792,155 +11655,41 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.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_;
+              monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
     }
 
-    public static final int START_DATE_FIELD_NUMBER = 4;
-    private volatile java.lang.Object startDate_;
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The startDate.
-     */
-    @java.lang.Override
-    public java.lang.String getStartDate() {
-      java.lang.Object ref = startDate_;
-      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();
-        startDate_ = s;
-        return s;
-      }
-    }
+    public static final int SUBS_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid subsId_;
     /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The bytes for startDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
     @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStartDateBytes() {
-      java.lang.Object ref = startDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        startDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
+    public boolean hasSubsId() {
+      return subsId_ != null;
     }
-
-    public static final int END_DATE_FIELD_NUMBER = 5;
-    private volatile java.lang.Object endDate_;
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return The subsId.
      */
     @java.lang.Override
-    public java.lang.String getEndDate() {
-      java.lang.Object ref = endDate_;
-      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();
-        endDate_ = s;
-        return s;
-      }
+    public context.ContextOuterClass.Uuid getSubsId() {
+      return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
     }
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The bytes for endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
      */
     @java.lang.Override
-    public com.google.protobuf.ByteString
-        getEndDateBytes() {
-      java.lang.Object ref = endDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        endDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
+    public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
+      return getSubsId();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -12957,20 +11706,8 @@ public final class Monitoring {
     @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_);
-      }
-      if (!getStartDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, startDate_);
-      }
-      if (!getEndDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, endDate_);
+      if (subsId_ != null) {
+        output.writeMessage(1, getSubsId());
       }
       unknownFields.writeTo(output);
     }
@@ -12981,23 +11718,9 @@ public final class Monitoring {
       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) {
+      if (subsId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(3, samplingIntervalS_);
-      }
-      if (!getStartDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, startDate_);
-      }
-      if (!getEndDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, endDate_);
+          .computeMessageSize(1, getSubsId());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -13009,26 +11732,16 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubsDescriptor)) {
+      if (!(obj instanceof monitoring.Monitoring.SubscriptionID)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubsDescriptor other = (monitoring.Monitoring.SubsDescriptor) obj;
+      monitoring.Monitoring.SubscriptionID other = (monitoring.Monitoring.SubscriptionID) obj;
 
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
+      if (hasSubsId() != other.hasSubsId()) return false;
+      if (hasSubsId()) {
+        if (!getSubsId()
+            .equals(other.getSubsId())) 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 (!getStartDate()
-          .equals(other.getStartDate())) return false;
-      if (!getEndDate()
-          .equals(other.getEndDate())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -13040,88 +11753,78 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
+      if (hasSubsId()) {
+        hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSubsId().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 = (37 * hash) + START_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getStartDate().hashCode();
-      hash = (37 * hash) + END_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getEndDate().hashCode();
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID 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.SubsDescriptor parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubscriptionID parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubscriptionID parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID 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.SubsDescriptor parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubscriptionID parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseDelimitedFrom(
+    public static monitoring.Monitoring.SubscriptionID 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.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -13134,7 +11837,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubsDescriptor prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubscriptionID prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -13150,26 +11853,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubsDescriptor}
+     * Protobuf type {@code monitoring.SubscriptionID}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubsDescriptor)
-        monitoring.Monitoring.SubsDescriptorOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubscriptionID)
+        monitoring.Monitoring.SubscriptionIDOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.Builder.class);
+                monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubsDescriptor.newBuilder()
+      // Construct using monitoring.Monitoring.SubscriptionID.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -13187,37 +11890,29 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          subsId_ = null;
+          subsIdBuilder_ = null;
         }
-        samplingDurationS_ = 0F;
-
-        samplingIntervalS_ = 0F;
-
-        startDate_ = "";
-
-        endDate_ = "";
-
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubsDescriptor.getDefaultInstance();
+      public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubscriptionID.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsDescriptor build() {
-        monitoring.Monitoring.SubsDescriptor result = buildPartial();
+      public monitoring.Monitoring.SubscriptionID build() {
+        monitoring.Monitoring.SubscriptionID result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -13225,17 +11920,13 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsDescriptor buildPartial() {
-        monitoring.Monitoring.SubsDescriptor result = new monitoring.Monitoring.SubsDescriptor(this);
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
+      public monitoring.Monitoring.SubscriptionID buildPartial() {
+        monitoring.Monitoring.SubscriptionID result = new monitoring.Monitoring.SubscriptionID(this);
+        if (subsIdBuilder_ == null) {
+          result.subsId_ = subsId_;
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          result.subsId_ = subsIdBuilder_.build();
         }
-        result.samplingDurationS_ = samplingDurationS_;
-        result.samplingIntervalS_ = samplingIntervalS_;
-        result.startDate_ = startDate_;
-        result.endDate_ = endDate_;
         onBuilt();
         return result;
       }
@@ -13250,457 +11941,189 @@ public final class Monitoring {
           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.SubsDescriptor) {
-          return mergeFrom((monitoring.Monitoring.SubsDescriptor)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(monitoring.Monitoring.SubsDescriptor other) {
-        if (other == monitoring.Monitoring.SubsDescriptor.getDefaultInstance()) return this;
-        if (other.hasKpiId()) {
-          mergeKpiId(other.getKpiId());
-        }
-        if (other.getSamplingDurationS() != 0F) {
-          setSamplingDurationS(other.getSamplingDurationS());
-        }
-        if (other.getSamplingIntervalS() != 0F) {
-          setSamplingIntervalS(other.getSamplingIntervalS());
-        }
-        if (!other.getStartDate().isEmpty()) {
-          startDate_ = other.startDate_;
-          onChanged();
-        }
-        if (!other.getEndDate().isEmpty()) {
-          endDate_ = other.endDate_;
-          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 {
-        monitoring.Monitoring.SubsDescriptor parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubsDescriptor) 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();
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
       }
-      /**
-       * <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_;
-        }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
       }
-      /**
-       * <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_;
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
       }
-
-      private float samplingDurationS_ ;
-      /**
-       * <code>float sampling_duration_s = 2;</code>
-       * @return The samplingDurationS.
-       */
       @java.lang.Override
-      public float getSamplingDurationS() {
-        return samplingDurationS_;
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
       }
-      /**
-       * <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;
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.SubscriptionID) {
+          return mergeFrom((monitoring.Monitoring.SubscriptionID)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
       }
-      /**
-       * <code>float sampling_duration_s = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSamplingDurationS() {
-        
-        samplingDurationS_ = 0F;
+
+      public Builder mergeFrom(monitoring.Monitoring.SubscriptionID other) {
+        if (other == monitoring.Monitoring.SubscriptionID.getDefaultInstance()) return this;
+        if (other.hasSubsId()) {
+          mergeSubsId(other.getSubsId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
       }
 
-      private float samplingIntervalS_ ;
-      /**
-       * <code>float sampling_interval_s = 3;</code>
-       * @return The samplingIntervalS.
-       */
       @java.lang.Override
-      public float getSamplingIntervalS() {
-        return samplingIntervalS_;
+      public final boolean isInitialized() {
+        return true;
       }
-      /**
-       * <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();
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.SubscriptionID parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.SubscriptionID) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
         return this;
       }
+
+      private context.ContextOuterClass.Uuid subsId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> subsIdBuilder_;
       /**
-       * <code>float sampling_interval_s = 3;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
+       * @return Whether the subsId field is set.
        */
-      public Builder clearSamplingIntervalS() {
-        
-        samplingIntervalS_ = 0F;
-        onChanged();
-        return this;
+      public boolean hasSubsId() {
+        return subsIdBuilder_ != null || subsId_ != null;
       }
-
-      private java.lang.Object startDate_ = "";
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @return The startDate.
+       * <code>.context.Uuid subs_id = 1;</code>
+       * @return The subsId.
        */
-      public java.lang.String getStartDate() {
-        java.lang.Object ref = startDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          startDate_ = s;
-          return s;
+      public context.ContextOuterClass.Uuid getSubsId() {
+        if (subsIdBuilder_ == null) {
+          return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
         } else {
-          return (java.lang.String) ref;
+          return subsIdBuilder_.getMessage();
         }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @return The bytes for startDate.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public com.google.protobuf.ByteString
-          getStartDateBytes() {
-        java.lang.Object ref = startDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          startDate_ = b;
-          return b;
+      public Builder setSubsId(context.ContextOuterClass.Uuid value) {
+        if (subsIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          subsId_ = value;
+          onChanged();
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          subsIdBuilder_.setMessage(value);
         }
-      }
-      /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @param value The startDate to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStartDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        startDate_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearStartDate() {
-        
-        startDate_ = getDefaultInstance().getStartDate();
-        onChanged();
+
         return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @param value The bytes for startDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder setStartDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        startDate_ = value;
-        onChanged();
+      public Builder setSubsId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (subsIdBuilder_ == null) {
+          subsId_ = builderForValue.build();
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(builderForValue.build());
+        }
+
         return this;
       }
-
-      private java.lang.Object endDate_ = "";
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @return The endDate.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public java.lang.String getEndDate() {
-        java.lang.Object ref = endDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          endDate_ = s;
-          return s;
+      public Builder mergeSubsId(context.ContextOuterClass.Uuid value) {
+        if (subsIdBuilder_ == null) {
+          if (subsId_ != null) {
+            subsId_ =
+              context.ContextOuterClass.Uuid.newBuilder(subsId_).mergeFrom(value).buildPartial();
+          } else {
+            subsId_ = value;
+          }
+          onChanged();
         } else {
-          return (java.lang.String) ref;
+          subsIdBuilder_.mergeFrom(value);
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @return The bytes for endDate.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public com.google.protobuf.ByteString
-          getEndDateBytes() {
-        java.lang.Object ref = endDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          endDate_ = b;
-          return b;
+      public Builder clearSubsId() {
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
+          onChanged();
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          subsId_ = null;
+          subsIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @param value The endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder setEndDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        endDate_ = value;
+      public context.ContextOuterClass.Uuid.Builder getSubsIdBuilder() {
+        
         onChanged();
-        return this;
+        return getSubsIdFieldBuilder().getBuilder();
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder clearEndDate() {
-        
-        endDate_ = getDefaultInstance().getEndDate();
-        onChanged();
-        return this;
+      public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
+        if (subsIdBuilder_ != null) {
+          return subsIdBuilder_.getMessageOrBuilder();
+        } else {
+          return subsId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+        }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @param value The bytes for endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder setEndDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        endDate_ = value;
-        onChanged();
-        return this;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getSubsIdFieldBuilder() {
+        if (subsIdBuilder_ == null) {
+          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getSubsId(),
+                  getParentForChildren(),
+                  isClean());
+          subsId_ = null;
+        }
+        return subsIdBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -13715,85 +12138,110 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.SubsDescriptor)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubscriptionID)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.SubsDescriptor)
-    private static final monitoring.Monitoring.SubsDescriptor DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubscriptionID)
+    private static final monitoring.Monitoring.SubscriptionID DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsDescriptor();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubscriptionID();
     }
 
-    public static monitoring.Monitoring.SubsDescriptor getDefaultInstance() {
+    public static monitoring.Monitoring.SubscriptionID getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<SubsDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<SubsDescriptor>() {
+    private static final com.google.protobuf.Parser<SubscriptionID>
+        PARSER = new com.google.protobuf.AbstractParser<SubscriptionID>() {
       @java.lang.Override
-      public SubsDescriptor parsePartialFrom(
+      public SubscriptionID parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubsDescriptor(input, extensionRegistry);
+        return new SubscriptionID(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<SubsDescriptor> parser() {
+    public static com.google.protobuf.Parser<SubscriptionID> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<SubsDescriptor> getParserForType() {
+    public com.google.protobuf.Parser<SubscriptionID> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
+    public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface SubscriptionIDOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubscriptionID)
+  public interface SubsResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubsResponse)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return Whether the subsId field is set.
      */
     boolean hasSubsId();
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return The subsId.
      */
-    context.ContextOuterClass.Uuid getSubsId();
+    monitoring.Monitoring.SubscriptionID getSubsId();
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder();
+    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder();
+
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiList> 
+        getKpiListList();
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    monitoring.Monitoring.KpiList getKpiList(int index);
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    int getKpiListCount();
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
+        getKpiListOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+        int index);
   }
   /**
-   * Protobuf type {@code monitoring.SubscriptionID}
+   * Protobuf type {@code monitoring.SubsResponse}
    */
-  public static final class SubscriptionID extends
+  public static final class SubsResponse extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubscriptionID)
-      SubscriptionIDOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubsResponse)
+      SubsResponseOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubscriptionID.newBuilder() to construct.
-    private SubscriptionID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubsResponse.newBuilder() to construct.
+    private SubsResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubscriptionID() {
+    private SubsResponse() {
+      kpiList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubscriptionID();
+      return new SubsResponse();
     }
 
     @java.lang.Override
@@ -13801,7 +12249,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubscriptionID(
+    private SubsResponse(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -13809,6 +12257,7 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -13820,11 +12269,11 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              monitoring.Monitoring.SubscriptionID.Builder subBuilder = null;
               if (subsId_ != null) {
                 subBuilder = subsId_.toBuilder();
               }
-              subsId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              subsId_ = input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(subsId_);
                 subsId_ = subBuilder.buildPartial();
@@ -13832,6 +12281,15 @@ public final class Monitoring {
 
               break;
             }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              kpiList_.add(
+                  input.readMessage(monitoring.Monitoring.KpiList.parser(), extensionRegistry));
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -13847,27 +12305,30 @@ public final class Monitoring {
         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_SubscriptionID_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
+              monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
     }
 
     public static final int SUBS_ID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid subsId_;
+    private monitoring.Monitoring.SubscriptionID subsId_;
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return Whether the subsId field is set.
      */
     @java.lang.Override
@@ -13875,21 +12336,61 @@ public final class Monitoring {
       return subsId_ != null;
     }
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return The subsId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getSubsId() {
-      return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+    public monitoring.Monitoring.SubscriptionID getSubsId() {
+      return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
     }
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
+    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
       return getSubsId();
     }
 
+    public static final int KPI_LIST_FIELD_NUMBER = 2;
+    private java.util.List<monitoring.Monitoring.KpiList> kpiList_;
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
+      return kpiList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
+        getKpiListOrBuilderList() {
+      return kpiList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public int getKpiListCount() {
+      return kpiList_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiList getKpiList(int index) {
+      return kpiList_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+        int index) {
+      return kpiList_.get(index);
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -13907,6 +12408,9 @@ public final class Monitoring {
       if (subsId_ != null) {
         output.writeMessage(1, getSubsId());
       }
+      for (int i = 0; i < kpiList_.size(); i++) {
+        output.writeMessage(2, kpiList_.get(i));
+      }
       unknownFields.writeTo(output);
     }
 
@@ -13920,6 +12424,10 @@ public final class Monitoring {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getSubsId());
       }
+      for (int i = 0; i < kpiList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, kpiList_.get(i));
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -13930,16 +12438,18 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubscriptionID)) {
+      if (!(obj instanceof monitoring.Monitoring.SubsResponse)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubscriptionID other = (monitoring.Monitoring.SubscriptionID) obj;
+      monitoring.Monitoring.SubsResponse other = (monitoring.Monitoring.SubsResponse) obj;
 
       if (hasSubsId() != other.hasSubsId()) return false;
       if (hasSubsId()) {
         if (!getSubsId()
             .equals(other.getSubsId())) return false;
       }
+      if (!getKpiListList()
+          .equals(other.getKpiListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -13955,74 +12465,78 @@ public final class Monitoring {
         hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
         hash = (53 * hash) + getSubsId().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.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse 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.SubscriptionID parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubsResponse parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsResponse parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse 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.SubscriptionID parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsResponse parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubscriptionID parseDelimitedFrom(
+    public static monitoring.Monitoring.SubsResponse 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.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -14035,7 +12549,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubscriptionID prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubsResponse prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -14051,26 +12565,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubscriptionID}
+     * Protobuf type {@code monitoring.SubsResponse}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubscriptionID)
-        monitoring.Monitoring.SubscriptionIDOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubsResponse)
+        monitoring.Monitoring.SubsResponseOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
+                monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubscriptionID.newBuilder()
+      // Construct using monitoring.Monitoring.SubsResponse.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -14083,6 +12597,7 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getKpiListFieldBuilder();
         }
       }
       @java.lang.Override
@@ -14094,23 +12609,29 @@ public final class Monitoring {
           subsId_ = null;
           subsIdBuilder_ = null;
         }
+        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_SubscriptionID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubscriptionID.getDefaultInstance();
+      public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubsResponse.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubscriptionID build() {
-        monitoring.Monitoring.SubscriptionID result = buildPartial();
+      public monitoring.Monitoring.SubsResponse build() {
+        monitoring.Monitoring.SubsResponse result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -14118,13 +12639,23 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubscriptionID buildPartial() {
-        monitoring.Monitoring.SubscriptionID result = new monitoring.Monitoring.SubscriptionID(this);
+      public monitoring.Monitoring.SubsResponse buildPartial() {
+        monitoring.Monitoring.SubsResponse result = new monitoring.Monitoring.SubsResponse(this);
+        int from_bitField0_ = bitField0_;
         if (subsIdBuilder_ == null) {
           result.subsId_ = subsId_;
         } else {
           result.subsId_ = subsIdBuilder_.build();
         }
+        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;
       }
@@ -14163,19 +12694,45 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.SubscriptionID) {
-          return mergeFrom((monitoring.Monitoring.SubscriptionID)other);
+        if (other instanceof monitoring.Monitoring.SubsResponse) {
+          return mergeFrom((monitoring.Monitoring.SubsResponse)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.SubscriptionID other) {
-        if (other == monitoring.Monitoring.SubscriptionID.getDefaultInstance()) return this;
+      public Builder mergeFrom(monitoring.Monitoring.SubsResponse other) {
+        if (other == monitoring.Monitoring.SubsResponse.getDefaultInstance()) return this;
         if (other.hasSubsId()) {
           mergeSubsId(other.getSubsId());
         }
+        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;
@@ -14191,11 +12748,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.SubscriptionID parsedMessage = null;
+        monitoring.Monitoring.SubsResponse parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubscriptionID) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.SubsResponse) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -14204,124 +12761,365 @@ public final class Monitoring {
         }
         return this;
       }
-
-      private context.ContextOuterClass.Uuid subsId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> subsIdBuilder_;
+      private int bitField0_;
+
+      private monitoring.Monitoring.SubscriptionID subsId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsIdBuilder_;
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return Whether the subsId field is set.
+       */
+      public boolean hasSubsId() {
+        return subsIdBuilder_ != null || subsId_ != null;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return The subsId.
+       */
+      public monitoring.Monitoring.SubscriptionID getSubsId() {
+        if (subsIdBuilder_ == null) {
+          return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        } else {
+          return subsIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          subsId_ = value;
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(
+          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsIdBuilder_ == null) {
+          subsId_ = builderForValue.build();
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder mergeSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (subsId_ != null) {
+            subsId_ =
+              monitoring.Monitoring.SubscriptionID.newBuilder(subsId_).mergeFrom(value).buildPartial();
+          } else {
+            subsId_ = value;
+          }
+          onChanged();
+        } else {
+          subsIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder clearSubsId() {
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
+          onChanged();
+        } else {
+          subsId_ = null;
+          subsIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionID.Builder getSubsIdBuilder() {
+        
+        onChanged();
+        return getSubsIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
+        if (subsIdBuilder_ != null) {
+          return subsIdBuilder_.getMessageOrBuilder();
+        } else {
+          return subsId_ == null ?
+              monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
+          getSubsIdFieldBuilder() {
+        if (subsIdBuilder_ == null) {
+          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
+                  getSubsId(),
+                  getParentForChildren(),
+                  isClean());
+          subsId_ = null;
+        }
+        return subsIdBuilder_;
+      }
+
+      private java.util.List<monitoring.Monitoring.KpiList> kpiList_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>(kpiList_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> kpiListBuilder_;
+
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
+        if (kpiListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        } else {
+          return kpiListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public int getKpiListCount() {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.size();
+        } else {
+          return kpiListBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiList getKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);
+        } else {
+          return kpiListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public Builder setKpiList(
+          int index, monitoring.Monitoring.KpiList value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.set(index, value);
+          onChanged();
+        } else {
+          kpiListBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
-       * @return Whether the subsId field is set.
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public boolean hasSubsId() {
-        return subsIdBuilder_ != null || subsId_ != null;
+      public Builder setKpiList(
+          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiListBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
-       * @return The subsId.
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public context.ContextOuterClass.Uuid getSubsId() {
-        if (subsIdBuilder_ == null) {
-          return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+      public Builder addKpiList(monitoring.Monitoring.KpiList value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.add(value);
+          onChanged();
         } else {
-          return subsIdBuilder_.getMessage();
+          kpiListBuilder_.addMessage(value);
         }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder setSubsId(context.ContextOuterClass.Uuid value) {
-        if (subsIdBuilder_ == null) {
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.KpiList value) {
+        if (kpiListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          subsId_ = value;
+          ensureKpiListIsMutable();
+          kpiList_.add(index, value);
           onChanged();
         } else {
-          subsIdBuilder_.setMessage(value);
+          kpiListBuilder_.addMessage(index, value);
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder setSubsId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
-        if (subsIdBuilder_ == null) {
-          subsId_ = builderForValue.build();
+      public Builder addKpiList(
+          monitoring.Monitoring.KpiList.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(builderForValue.build());
           onChanged();
         } else {
-          subsIdBuilder_.setMessage(builderForValue.build());
+          kpiListBuilder_.addMessage(builderForValue.build());
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder mergeSubsId(context.ContextOuterClass.Uuid value) {
-        if (subsIdBuilder_ == null) {
-          if (subsId_ != null) {
-            subsId_ =
-              context.ContextOuterClass.Uuid.newBuilder(subsId_).mergeFrom(value).buildPartial();
-          } else {
-            subsId_ = value;
-          }
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          subsIdBuilder_.mergeFrom(value);
+          kpiListBuilder_.addMessage(index, builderForValue.build());
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder clearSubsId() {
-        if (subsIdBuilder_ == null) {
-          subsId_ = null;
+      public Builder addAllKpiList(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiList> values) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiList_);
           onChanged();
         } else {
-          subsId_ = null;
-          subsIdBuilder_ = null;
+          kpiListBuilder_.addAllMessages(values);
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public context.ContextOuterClass.Uuid.Builder getSubsIdBuilder() {
-        
-        onChanged();
-        return getSubsIdFieldBuilder().getBuilder();
+      public Builder clearKpiList() {
+        if (kpiListBuilder_ == null) {
+          kpiList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiListBuilder_.clear();
+        }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
-        if (subsIdBuilder_ != null) {
-          return subsIdBuilder_.getMessageOrBuilder();
+      public Builder removeKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.remove(index);
+          onChanged();
         } else {
-          return subsId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+          kpiListBuilder_.remove(index);
         }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
-          getSubsIdFieldBuilder() {
-        if (subsIdBuilder_ == null) {
-          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
-                  getSubsId(),
+      public monitoring.Monitoring.KpiList.Builder getKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+          int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);  } else {
+          return kpiListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
+           getKpiListOrBuilderList() {
+        if (kpiListBuilder_ != null) {
+          return kpiListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder() {
+        return getKpiListFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiList.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiList.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiList.Builder> 
+           getKpiListBuilderList() {
+        return getKpiListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> 
+          getKpiListFieldBuilder() {
+        if (kpiListBuilder_ == null) {
+          kpiListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder>(
+                  kpiList_,
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          subsId_ = null;
+          kpiList_ = null;
         }
-        return subsIdBuilder_;
+        return kpiListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -14336,110 +13134,95 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.SubscriptionID)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubsResponse)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.SubscriptionID)
-    private static final monitoring.Monitoring.SubscriptionID DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubsResponse)
+    private static final monitoring.Monitoring.SubsResponse DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubscriptionID();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsResponse();
     }
 
-    public static monitoring.Monitoring.SubscriptionID getDefaultInstance() {
+    public static monitoring.Monitoring.SubsResponse getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<SubscriptionID>
-        PARSER = new com.google.protobuf.AbstractParser<SubscriptionID>() {
+    private static final com.google.protobuf.Parser<SubsResponse>
+        PARSER = new com.google.protobuf.AbstractParser<SubsResponse>() {
       @java.lang.Override
-      public SubscriptionID parsePartialFrom(
+      public SubsResponse parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubscriptionID(input, extensionRegistry);
+        return new SubsResponse(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<SubscriptionID> parser() {
+    public static com.google.protobuf.Parser<SubsResponse> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<SubscriptionID> getParserForType() {
+    public com.google.protobuf.Parser<SubsResponse> getParserForType() {
       return PARSER;
     }
 
-    @java.lang.Override
-    public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface SubsResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubsResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return Whether the subsId field is set.
-     */
-    boolean hasSubsId();
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return The subsId.
-     */
-    monitoring.Monitoring.SubscriptionID getSubsId();
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     */
-    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder();
-
+    @java.lang.Override
+    public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SubsIDListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubsIDList)
+      com.google.protobuf.MessageOrBuilder {
+
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    java.util.List<monitoring.Monitoring.KpiList> 
-        getKpiListList();
+    java.util.List<monitoring.Monitoring.SubscriptionID> 
+        getSubsListList();
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    monitoring.Monitoring.KpiList getKpiList(int index);
+    monitoring.Monitoring.SubscriptionID getSubsList(int index);
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    int getKpiListCount();
+    int getSubsListCount();
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
-        getKpiListOrBuilderList();
+    java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
+        getSubsListOrBuilderList();
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
         int index);
   }
   /**
-   * Protobuf type {@code monitoring.SubsResponse}
+   * Protobuf type {@code monitoring.SubsIDList}
    */
-  public static final class SubsResponse extends
+  public static final class SubsIDList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubsResponse)
-      SubsResponseOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubsIDList)
+      SubsIDListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubsResponse.newBuilder() to construct.
-    private SubsResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubsIDList.newBuilder() to construct.
+    private SubsIDList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubsResponse() {
-      kpiList_ = java.util.Collections.emptyList();
+    private SubsIDList() {
+      subsList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubsResponse();
+      return new SubsIDList();
     }
 
     @java.lang.Override
@@ -14447,7 +13230,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubsResponse(
+    private SubsIDList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -14467,25 +13250,12 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              monitoring.Monitoring.SubscriptionID.Builder subBuilder = null;
-              if (subsId_ != null) {
-                subBuilder = subsId_.toBuilder();
-              }
-              subsId_ = input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(subsId_);
-                subsId_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 18: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>();
+                subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              kpiList_.add(
-                  input.readMessage(monitoring.Monitoring.KpiList.parser(), extensionRegistry));
+              subsList_.add(
+                  input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry));
               break;
             }
             default: {
@@ -14504,7 +13274,7 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+          subsList_ = java.util.Collections.unmodifiableList(subsList_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -14512,81 +13282,55 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
-    }
-
-    public static final int SUBS_ID_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.SubscriptionID subsId_;
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return Whether the subsId field is set.
-     */
-    @java.lang.Override
-    public boolean hasSubsId() {
-      return subsId_ != null;
-    }
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return The subsId.
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.SubscriptionID getSubsId() {
-      return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
-    }
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
-      return getSubsId();
+              monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
     }
 
-    public static final int KPI_LIST_FIELD_NUMBER = 2;
-    private java.util.List<monitoring.Monitoring.KpiList> kpiList_;
+    public static final int SUBS_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_;
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
-      return kpiList_;
+    public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
+      return subsList_;
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
-        getKpiListOrBuilderList() {
-      return kpiList_;
+    public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
+        getSubsListOrBuilderList() {
+      return subsList_;
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public int getKpiListCount() {
-      return kpiList_.size();
+    public int getSubsListCount() {
+      return subsList_.size();
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiList getKpiList(int index) {
-      return kpiList_.get(index);
+    public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
+      return subsList_.get(index);
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
         int index) {
-      return kpiList_.get(index);
+      return subsList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -14603,11 +13347,8 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (subsId_ != null) {
-        output.writeMessage(1, getSubsId());
-      }
-      for (int i = 0; i < kpiList_.size(); i++) {
-        output.writeMessage(2, kpiList_.get(i));
+      for (int i = 0; i < subsList_.size(); i++) {
+        output.writeMessage(1, subsList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -14618,13 +13359,9 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (subsId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getSubsId());
-      }
-      for (int i = 0; i < kpiList_.size(); i++) {
+      for (int i = 0; i < subsList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, kpiList_.get(i));
+          .computeMessageSize(1, subsList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -14636,18 +13373,13 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubsResponse)) {
+      if (!(obj instanceof monitoring.Monitoring.SubsIDList)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubsResponse other = (monitoring.Monitoring.SubsResponse) obj;
+      monitoring.Monitoring.SubsIDList other = (monitoring.Monitoring.SubsIDList) obj;
 
-      if (hasSubsId() != other.hasSubsId()) return false;
-      if (hasSubsId()) {
-        if (!getSubsId()
-            .equals(other.getSubsId())) return false;
-      }
-      if (!getKpiListList()
-          .equals(other.getKpiListList())) return false;
+      if (!getSubsListList()
+          .equals(other.getSubsListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -14659,82 +13391,78 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasSubsId()) {
-        hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getSubsId().hashCode();
-      }
-      if (getKpiListCount() > 0) {
-        hash = (37 * hash) + KPI_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiListList().hashCode();
+      if (getSubsListCount() > 0) {
+        hash = (37 * hash) + SUBS_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getSubsListList().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList 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.SubsResponse parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubsIDList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsIDList parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList 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.SubsResponse parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsIDList parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsResponse parseDelimitedFrom(
+    public static monitoring.Monitoring.SubsIDList 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.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -14747,7 +13475,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubsResponse prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubsIDList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -14763,26 +13491,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubsResponse}
+     * Protobuf type {@code monitoring.SubsIDList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubsResponse)
-        monitoring.Monitoring.SubsResponseOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubsIDList)
+        monitoring.Monitoring.SubsIDListOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
+                monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubsResponse.newBuilder()
+      // Construct using monitoring.Monitoring.SubsIDList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -14795,23 +13523,17 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiListFieldBuilder();
+          getSubsListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (subsIdBuilder_ == null) {
-          subsId_ = null;
-        } else {
-          subsId_ = null;
-          subsIdBuilder_ = null;
-        }
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+        if (subsListBuilder_ == null) {
+          subsList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          kpiListBuilder_.clear();
+          subsListBuilder_.clear();
         }
         return this;
       }
@@ -14819,40 +13541,35 @@ public final class Monitoring {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubsResponse.getDefaultInstance();
+      public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubsIDList.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsResponse build() {
-        monitoring.Monitoring.SubsResponse result = buildPartial();
+      public monitoring.Monitoring.SubsIDList build() {
+        monitoring.Monitoring.SubsIDList result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      @java.lang.Override
-      public monitoring.Monitoring.SubsResponse buildPartial() {
-        monitoring.Monitoring.SubsResponse result = new monitoring.Monitoring.SubsResponse(this);
-        int from_bitField0_ = bitField0_;
-        if (subsIdBuilder_ == null) {
-          result.subsId_ = subsId_;
-        } else {
-          result.subsId_ = subsIdBuilder_.build();
-        }
-        if (kpiListBuilder_ == null) {
+      @java.lang.Override
+      public monitoring.Monitoring.SubsIDList buildPartial() {
+        monitoring.Monitoring.SubsIDList result = new monitoring.Monitoring.SubsIDList(this);
+        int from_bitField0_ = bitField0_;
+        if (subsListBuilder_ == null) {
           if (((bitField0_ & 0x00000001) != 0)) {
-            kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+            subsList_ = java.util.Collections.unmodifiableList(subsList_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
-          result.kpiList_ = kpiList_;
+          result.subsList_ = subsList_;
         } else {
-          result.kpiList_ = kpiListBuilder_.build();
+          result.subsList_ = subsListBuilder_.build();
         }
         onBuilt();
         return result;
@@ -14892,42 +13609,39 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.SubsResponse) {
-          return mergeFrom((monitoring.Monitoring.SubsResponse)other);
+        if (other instanceof monitoring.Monitoring.SubsIDList) {
+          return mergeFrom((monitoring.Monitoring.SubsIDList)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.SubsResponse other) {
-        if (other == monitoring.Monitoring.SubsResponse.getDefaultInstance()) return this;
-        if (other.hasSubsId()) {
-          mergeSubsId(other.getSubsId());
-        }
-        if (kpiListBuilder_ == null) {
-          if (!other.kpiList_.isEmpty()) {
-            if (kpiList_.isEmpty()) {
-              kpiList_ = other.kpiList_;
+      public Builder mergeFrom(monitoring.Monitoring.SubsIDList other) {
+        if (other == monitoring.Monitoring.SubsIDList.getDefaultInstance()) return this;
+        if (subsListBuilder_ == null) {
+          if (!other.subsList_.isEmpty()) {
+            if (subsList_.isEmpty()) {
+              subsList_ = other.subsList_;
               bitField0_ = (bitField0_ & ~0x00000001);
             } else {
-              ensureKpiListIsMutable();
-              kpiList_.addAll(other.kpiList_);
+              ensureSubsListIsMutable();
+              subsList_.addAll(other.subsList_);
             }
             onChanged();
           }
         } else {
-          if (!other.kpiList_.isEmpty()) {
-            if (kpiListBuilder_.isEmpty()) {
-              kpiListBuilder_.dispose();
-              kpiListBuilder_ = null;
-              kpiList_ = other.kpiList_;
+          if (!other.subsList_.isEmpty()) {
+            if (subsListBuilder_.isEmpty()) {
+              subsListBuilder_.dispose();
+              subsListBuilder_ = null;
+              subsList_ = other.subsList_;
               bitField0_ = (bitField0_ & ~0x00000001);
-              kpiListBuilder_ = 
+              subsListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiListFieldBuilder() : null;
+                   getSubsListFieldBuilder() : null;
             } else {
-              kpiListBuilder_.addAllMessages(other.kpiList_);
+              subsListBuilder_.addAllMessages(other.subsList_);
             }
           }
         }
@@ -14946,11 +13660,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.SubsResponse parsedMessage = null;
+        monitoring.Monitoring.SubsIDList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubsResponse) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.SubsIDList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -14961,363 +13675,244 @@ public final class Monitoring {
       }
       private int bitField0_;
 
-      private monitoring.Monitoring.SubscriptionID subsId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsIdBuilder_;
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       * @return Whether the subsId field is set.
-       */
-      public boolean hasSubsId() {
-        return subsIdBuilder_ != null || subsId_ != null;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       * @return The subsId.
-       */
-      public monitoring.Monitoring.SubscriptionID getSubsId() {
-        if (subsIdBuilder_ == null) {
-          return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
-        } else {
-          return subsIdBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder setSubsId(monitoring.Monitoring.SubscriptionID value) {
-        if (subsIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          subsId_ = value;
-          onChanged();
-        } else {
-          subsIdBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder setSubsId(
-          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsIdBuilder_ == null) {
-          subsId_ = builderForValue.build();
-          onChanged();
-        } else {
-          subsIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder mergeSubsId(monitoring.Monitoring.SubscriptionID value) {
-        if (subsIdBuilder_ == null) {
-          if (subsId_ != null) {
-            subsId_ =
-              monitoring.Monitoring.SubscriptionID.newBuilder(subsId_).mergeFrom(value).buildPartial();
-          } else {
-            subsId_ = value;
-          }
-          onChanged();
-        } else {
-          subsIdBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder clearSubsId() {
-        if (subsIdBuilder_ == null) {
-          subsId_ = null;
-          onChanged();
-        } else {
-          subsId_ = null;
-          subsIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder getSubsIdBuilder() {
-        
-        onChanged();
-        return getSubsIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
-        if (subsIdBuilder_ != null) {
-          return subsIdBuilder_.getMessageOrBuilder();
-        } else {
-          return subsId_ == null ?
-              monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
-        }
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
-          getSubsIdFieldBuilder() {
-        if (subsIdBuilder_ == null) {
-          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
-                  getSubsId(),
-                  getParentForChildren(),
-                  isClean());
-          subsId_ = null;
-        }
-        return subsIdBuilder_;
-      }
-
-      private java.util.List<monitoring.Monitoring.KpiList> kpiList_ =
+      private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_ =
         java.util.Collections.emptyList();
-      private void ensureKpiListIsMutable() {
+      private void ensureSubsListIsMutable() {
         if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>(kpiList_);
+          subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>(subsList_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> kpiListBuilder_;
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsListBuilder_;
 
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
-        if (kpiListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiList_);
+      public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
+        if (subsListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(subsList_);
         } else {
-          return kpiListBuilder_.getMessageList();
+          return subsListBuilder_.getMessageList();
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public int getKpiListCount() {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.size();
+      public int getSubsListCount() {
+        if (subsListBuilder_ == null) {
+          return subsList_.size();
         } else {
-          return kpiListBuilder_.getCount();
+          return subsListBuilder_.getCount();
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList getKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);
+      public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
+        if (subsListBuilder_ == null) {
+          return subsList_.get(index);
         } else {
-          return kpiListBuilder_.getMessage(index);
+          return subsListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.KpiList value) {
-        if (kpiListBuilder_ == null) {
+      public Builder setSubsList(
+          int index, monitoring.Monitoring.SubscriptionID value) {
+        if (subsListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.set(index, value);
+          ensureSubsListIsMutable();
+          subsList_.set(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, value);
+          subsListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.set(index, builderForValue.build());
+      public Builder setSubsList(
+          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, builderForValue.build());
+          subsListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addKpiList(monitoring.Monitoring.KpiList value) {
-        if (kpiListBuilder_ == null) {
+      public Builder addSubsList(monitoring.Monitoring.SubscriptionID value) {
+        if (subsListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(value);
+          ensureSubsListIsMutable();
+          subsList_.add(value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(value);
+          subsListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
-       */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.KpiList value) {
-        if (kpiListBuilder_ == null) {
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+       */
+      public Builder addSubsList(
+          int index, monitoring.Monitoring.SubscriptionID value) {
+        if (subsListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(index, value);
+          ensureSubsListIsMutable();
+          subsList_.add(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, value);
+          subsListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addKpiList(
-          monitoring.Monitoring.KpiList.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(builderForValue.build());
+      public Builder addSubsList(
+          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.add(builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(builderForValue.build());
+          subsListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(index, builderForValue.build());
+      public Builder addSubsList(
+          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, builderForValue.build());
+          subsListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addAllKpiList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiList> values) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
+      public Builder addAllSubsList(
+          java.lang.Iterable<? extends monitoring.Monitoring.SubscriptionID> values) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiList_);
+              values, subsList_);
           onChanged();
         } else {
-          kpiListBuilder_.addAllMessages(values);
+          subsListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder clearKpiList() {
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+      public Builder clearSubsList() {
+        if (subsListBuilder_ == null) {
+          subsList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          kpiListBuilder_.clear();
+          subsListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder removeKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.remove(index);
+      public Builder removeSubsList(int index) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.remove(index);
           onChanged();
         } else {
-          kpiListBuilder_.remove(index);
+          subsListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList.Builder getKpiListBuilder(
+      public monitoring.Monitoring.SubscriptionID.Builder getSubsListBuilder(
           int index) {
-        return getKpiListFieldBuilder().getBuilder(index);
+        return getSubsListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
           int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);  } else {
-          return kpiListBuilder_.getMessageOrBuilder(index);
+        if (subsListBuilder_ == null) {
+          return subsList_.get(index);  } else {
+          return subsListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
-           getKpiListOrBuilderList() {
-        if (kpiListBuilder_ != null) {
-          return kpiListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
+           getSubsListOrBuilderList() {
+        if (subsListBuilder_ != null) {
+          return subsListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(kpiList_);
+          return java.util.Collections.unmodifiableList(subsList_);
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder() {
-        return getKpiListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiList.getDefaultInstance());
+      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder() {
+        return getSubsListFieldBuilder().addBuilder(
+            monitoring.Monitoring.SubscriptionID.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder(
+      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder(
           int index) {
-        return getKpiListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiList.getDefaultInstance());
+        return getSubsListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.SubscriptionID.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiList.Builder> 
-           getKpiListBuilderList() {
-        return getKpiListFieldBuilder().getBuilderList();
+      public java.util.List<monitoring.Monitoring.SubscriptionID.Builder> 
+           getSubsListBuilderList() {
+        return getSubsListFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> 
-          getKpiListFieldBuilder() {
-        if (kpiListBuilder_ == null) {
-          kpiListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder>(
-                  kpiList_,
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
+          getSubsListFieldBuilder() {
+        if (subsListBuilder_ == null) {
+          subsListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
+                  subsList_,
                   ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          kpiList_ = null;
+          subsList_ = null;
         }
-        return kpiListBuilder_;
+        return subsListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -15332,95 +13927,176 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.SubsResponse)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubsIDList)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.SubsResponse)
-    private static final monitoring.Monitoring.SubsResponse DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubsIDList)
+    private static final monitoring.Monitoring.SubsIDList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsResponse();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsIDList();
     }
 
-    public static monitoring.Monitoring.SubsResponse getDefaultInstance() {
+    public static monitoring.Monitoring.SubsIDList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<SubsResponse>
-        PARSER = new com.google.protobuf.AbstractParser<SubsResponse>() {
+    private static final com.google.protobuf.Parser<SubsIDList>
+        PARSER = new com.google.protobuf.AbstractParser<SubsIDList>() {
       @java.lang.Override
-      public SubsResponse parsePartialFrom(
+      public SubsIDList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubsResponse(input, extensionRegistry);
+        return new SubsIDList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<SubsResponse> parser() {
+    public static com.google.protobuf.Parser<SubsIDList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<SubsResponse> getParserForType() {
+    public com.google.protobuf.Parser<SubsIDList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
+    public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface SubsIDListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubsIDList)
+  public interface AlarmDescriptorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.AlarmDescriptor)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
      */
-    java.util.List<monitoring.Monitoring.SubscriptionID> 
-        getSubsListList();
+    boolean hasAlarmId();
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return The alarmId.
      */
-    monitoring.Monitoring.SubscriptionID getSubsList(int index);
+    monitoring.Monitoring.AlarmID getAlarmId();
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
      */
-    int getSubsListCount();
+    monitoring.Monitoring.AlarmIDOrBuilder getAlarmIdOrBuilder();
+
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The alarmDescription.
      */
-    java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
-        getSubsListOrBuilderList();
+    java.lang.String getAlarmDescription();
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The bytes for alarmDescription.
      */
-    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
+    com.google.protobuf.ByteString
+        getAlarmDescriptionBytes();
+
+    /**
+     * <code>string name = 3;</code>
+     * @return The name.
+     */
+    java.lang.String getName();
+    /**
+     * <code>string name = 3;</code>
+     * @return The bytes for name.
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiId> 
+        getKpiIdList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    monitoring.Monitoring.KpiId getKpiId(int index);
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    int getKpiIdCount();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiValueRange> 
+        getKpiValueRangeList();
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    monitoring.Monitoring.KpiValueRange getKpiValueRange(int index);
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    int getKpiValueRangeCount();
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiValueRangeOrBuilder> 
+        getKpiValueRangeOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder(
         int index);
+
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return Whether the timestamp field is set.
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return The timestamp.
+     */
+    context.ContextOuterClass.Timestamp getTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.SubsIDList}
+   * Protobuf type {@code monitoring.AlarmDescriptor}
    */
-  public static final class SubsIDList extends
+  public static final class AlarmDescriptor extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubsIDList)
-      SubsIDListOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.AlarmDescriptor)
+      AlarmDescriptorOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubsIDList.newBuilder() to construct.
-    private SubsIDList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use AlarmDescriptor.newBuilder() to construct.
+    private AlarmDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubsIDList() {
-      subsList_ = java.util.Collections.emptyList();
+    private AlarmDescriptor() {
+      alarmDescription_ = "";
+      name_ = "";
+      kpiId_ = java.util.Collections.emptyList();
+      kpiValueRange_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubsIDList();
+      return new AlarmDescriptor();
     }
 
     @java.lang.Override
@@ -15428,7 +14104,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubsIDList(
+    private AlarmDescriptor(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -15448,12 +14124,59 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
+              monitoring.Monitoring.AlarmID.Builder subBuilder = null;
+              if (alarmId_ != null) {
+                subBuilder = alarmId_.toBuilder();
+              }
+              alarmId_ = input.readMessage(monitoring.Monitoring.AlarmID.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(alarmId_);
+                alarmId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              alarmDescription_ = s;
+              break;
+            }
+            case 26: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              name_ = s;
+              break;
+            }
+            case 34: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>();
+                kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              subsList_.add(
-                  input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry));
+              kpiId_.add(
+                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
+              break;
+            }
+            case 42: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                kpiValueRange_ = new java.util.ArrayList<monitoring.Monitoring.KpiValueRange>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              kpiValueRange_.add(
+                  input.readMessage(monitoring.Monitoring.KpiValueRange.parser(), extensionRegistry));
+              break;
+            }
+            case 50: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (timestamp_ != null) {
+                subBuilder = timestamp_.toBuilder();
+              }
+              timestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(timestamp_);
+                timestamp_ = subBuilder.buildPartial();
+              }
+
               break;
             }
             default: {
@@ -15472,7 +14195,10 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          subsList_ = java.util.Collections.unmodifiableList(subsList_);
+          kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+        }
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
+          kpiValueRange_ = java.util.Collections.unmodifiableList(kpiValueRange_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -15480,55 +14206,223 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
+              monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
     }
 
-    public static final int SUBS_LIST_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_;
+    public static final int ALARM_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.AlarmID alarmId_;
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
-      return subsList_;
+    public boolean hasAlarmId() {
+      return alarmId_ != null;
     }
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return The alarmId.
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
-        getSubsListOrBuilderList() {
-      return subsList_;
+    public monitoring.Monitoring.AlarmID getAlarmId() {
+      return alarmId_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmId_;
     }
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
      */
     @java.lang.Override
-    public int getSubsListCount() {
-      return subsList_.size();
+    public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIdOrBuilder() {
+      return getAlarmId();
     }
+
+    public static final int ALARM_DESCRIPTION_FIELD_NUMBER = 2;
+    private volatile java.lang.Object alarmDescription_;
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The alarmDescription.
      */
     @java.lang.Override
-    public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
-      return subsList_.get(index);
+    public java.lang.String getAlarmDescription() {
+      java.lang.Object ref = alarmDescription_;
+      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();
+        alarmDescription_ = s;
+        return s;
+      }
     }
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The bytes for alarmDescription.
      */
     @java.lang.Override
-    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
+    public com.google.protobuf.ByteString
+        getAlarmDescriptionBytes() {
+      java.lang.Object ref = alarmDescription_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        alarmDescription_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int NAME_FIELD_NUMBER = 3;
+    private volatile java.lang.Object name_;
+    /**
+     * <code>string name = 3;</code>
+     * @return The name.
+     */
+    @java.lang.Override
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      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();
+        name_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string name = 3;</code>
+     * @return The bytes for name.
+     */
+    @java.lang.Override
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int KPI_ID_FIELD_NUMBER = 4;
+    private java.util.List<monitoring.Monitoring.KpiId> kpiId_;
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+      return kpiId_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdOrBuilderList() {
+      return kpiId_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public int getKpiIdCount() {
+      return kpiId_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiId(int index) {
+      return kpiId_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
         int index) {
-      return subsList_.get(index);
+      return kpiId_.get(index);
+    }
+
+    public static final int KPI_VALUE_RANGE_FIELD_NUMBER = 5;
+    private java.util.List<monitoring.Monitoring.KpiValueRange> kpiValueRange_;
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiValueRange> getKpiValueRangeList() {
+      return kpiValueRange_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiValueRangeOrBuilder> 
+        getKpiValueRangeOrBuilderList() {
+      return kpiValueRange_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public int getKpiValueRangeCount() {
+      return kpiValueRange_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueRange getKpiValueRange(int index) {
+      return kpiValueRange_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder(
+        int index) {
+      return kpiValueRange_.get(index);
+    }
+
+    public static final int TIMESTAMP_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.Timestamp timestamp_;
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return Whether the timestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasTimestamp() {
+      return timestamp_ != null;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getTimestamp() {
+      return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+      return getTimestamp();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -15545,21 +14439,54 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      for (int i = 0; i < subsList_.size(); i++) {
-        output.writeMessage(1, subsList_.get(i));
+      if (alarmId_ != null) {
+        output.writeMessage(1, getAlarmId());
+      }
+      if (!getAlarmDescriptionBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, alarmDescription_);
+      }
+      if (!getNameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, name_);
+      }
+      for (int i = 0; i < kpiId_.size(); i++) {
+        output.writeMessage(4, kpiId_.get(i));
+      }
+      for (int i = 0; i < kpiValueRange_.size(); i++) {
+        output.writeMessage(5, kpiValueRange_.get(i));
+      }
+      if (timestamp_ != null) {
+        output.writeMessage(6, getTimestamp());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (alarmId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getAlarmId());
+      }
+      if (!getAlarmDescriptionBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, alarmDescription_);
+      }
+      if (!getNameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, name_);
+      }
+      for (int i = 0; i < kpiId_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, kpiId_.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 < subsList_.size(); i++) {
+      for (int i = 0; i < kpiValueRange_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, subsList_.get(i));
+          .computeMessageSize(5, kpiValueRange_.get(i));
+      }
+      if (timestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getTimestamp());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -15571,13 +14498,29 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubsIDList)) {
+      if (!(obj instanceof monitoring.Monitoring.AlarmDescriptor)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubsIDList other = (monitoring.Monitoring.SubsIDList) obj;
+      monitoring.Monitoring.AlarmDescriptor other = (monitoring.Monitoring.AlarmDescriptor) obj;
 
-      if (!getSubsListList()
-          .equals(other.getSubsListList())) return false;
+      if (hasAlarmId() != other.hasAlarmId()) return false;
+      if (hasAlarmId()) {
+        if (!getAlarmId()
+            .equals(other.getAlarmId())) return false;
+      }
+      if (!getAlarmDescription()
+          .equals(other.getAlarmDescription())) return false;
+      if (!getName()
+          .equals(other.getName())) return false;
+      if (!getKpiIdList()
+          .equals(other.getKpiIdList())) return false;
+      if (!getKpiValueRangeList()
+          .equals(other.getKpiValueRangeList())) return false;
+      if (hasTimestamp() != other.hasTimestamp()) return false;
+      if (hasTimestamp()) {
+        if (!getTimestamp()
+            .equals(other.getTimestamp())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -15589,78 +14532,94 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getSubsListCount() > 0) {
-        hash = (37 * hash) + SUBS_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getSubsListList().hashCode();
+      if (hasAlarmId()) {
+        hash = (37 * hash) + ALARM_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getAlarmId().hashCode();
+      }
+      hash = (37 * hash) + ALARM_DESCRIPTION_FIELD_NUMBER;
+      hash = (53 * hash) + getAlarmDescription().hashCode();
+      hash = (37 * hash) + NAME_FIELD_NUMBER;
+      hash = (53 * hash) + getName().hashCode();
+      if (getKpiIdCount() > 0) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiIdList().hashCode();
+      }
+      if (getKpiValueRangeCount() > 0) {
+        hash = (37 * hash) + KPI_VALUE_RANGE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiValueRangeList().hashCode();
+      }
+      if (hasTimestamp()) {
+        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getTimestamp().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor 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.SubsIDList parseFrom(byte[] data)
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor 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.SubsIDList parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmDescriptor parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsIDList parseDelimitedFrom(
+    public static monitoring.Monitoring.AlarmDescriptor 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.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -15673,7 +14632,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubsIDList prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.AlarmDescriptor prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -15689,26 +14648,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubsIDList}
+     * Protobuf type {@code monitoring.AlarmDescriptor}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubsIDList)
-        monitoring.Monitoring.SubsIDListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.AlarmDescriptor)
+        monitoring.Monitoring.AlarmDescriptorOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
+                monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubsIDList.newBuilder()
+      // Construct using monitoring.Monitoring.AlarmDescriptor.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -15721,1670 +14680,1731 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getSubsListFieldBuilder();
+          getKpiIdFieldBuilder();
+          getKpiValueRangeFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (subsListBuilder_ == null) {
-          subsList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-        } else {
-          subsListBuilder_.clear();
-        }
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubsIDList.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.SubsIDList build() {
-        monitoring.Monitoring.SubsIDList result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.SubsIDList buildPartial() {
-        monitoring.Monitoring.SubsIDList result = new monitoring.Monitoring.SubsIDList(this);
-        int from_bitField0_ = bitField0_;
-        if (subsListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            subsList_ = java.util.Collections.unmodifiableList(subsList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.subsList_ = subsList_;
-        } else {
-          result.subsList_ = subsListBuilder_.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.SubsIDList) {
-          return mergeFrom((monitoring.Monitoring.SubsIDList)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(monitoring.Monitoring.SubsIDList other) {
-        if (other == monitoring.Monitoring.SubsIDList.getDefaultInstance()) return this;
-        if (subsListBuilder_ == null) {
-          if (!other.subsList_.isEmpty()) {
-            if (subsList_.isEmpty()) {
-              subsList_ = other.subsList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureSubsListIsMutable();
-              subsList_.addAll(other.subsList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.subsList_.isEmpty()) {
-            if (subsListBuilder_.isEmpty()) {
-              subsListBuilder_.dispose();
-              subsListBuilder_ = null;
-              subsList_ = other.subsList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              subsListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getSubsListFieldBuilder() : null;
-            } else {
-              subsListBuilder_.addAllMessages(other.subsList_);
-            }
-          }
-        }
-        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.SubsIDList parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubsIDList) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_ =
-        java.util.Collections.emptyList();
-      private void ensureSubsListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>(subsList_);
-          bitField0_ |= 0x00000001;
-         }
-      }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsListBuilder_;
-
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
-        if (subsListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(subsList_);
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
         } else {
-          return subsListBuilder_.getMessageList();
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public int getSubsListCount() {
-        if (subsListBuilder_ == null) {
-          return subsList_.size();
+        alarmDescription_ = "";
+
+        name_ = "";
+
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          return subsListBuilder_.getCount();
+          kpiIdBuilder_.clear();
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
-        if (subsListBuilder_ == null) {
-          return subsList_.get(index);
+        if (kpiValueRangeBuilder_ == null) {
+          kpiValueRange_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
         } else {
-          return subsListBuilder_.getMessage(index);
+          kpiValueRangeBuilder_.clear();
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder setSubsList(
-          int index, monitoring.Monitoring.SubscriptionID value) {
-        if (subsListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureSubsListIsMutable();
-          subsList_.set(index, value);
-          onChanged();
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
         } else {
-          subsListBuilder_.setMessage(index, value);
+          timestamp_ = null;
+          timestampBuilder_ = null;
         }
         return this;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder setSubsList(
-          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          subsListBuilder_.setMessage(index, builderForValue.build());
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
+        return monitoring.Monitoring.AlarmDescriptor.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmDescriptor build() {
+        monitoring.Monitoring.AlarmDescriptor result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
-        return this;
+        return result;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(monitoring.Monitoring.SubscriptionID value) {
-        if (subsListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureSubsListIsMutable();
-          subsList_.add(value);
-          onChanged();
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmDescriptor buildPartial() {
+        monitoring.Monitoring.AlarmDescriptor result = new monitoring.Monitoring.AlarmDescriptor(this);
+        int from_bitField0_ = bitField0_;
+        if (alarmIdBuilder_ == null) {
+          result.alarmId_ = alarmId_;
         } else {
-          subsListBuilder_.addMessage(value);
+          result.alarmId_ = alarmIdBuilder_.build();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(
-          int index, monitoring.Monitoring.SubscriptionID value) {
-        if (subsListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
+        result.alarmDescription_ = alarmDescription_;
+        result.name_ = name_;
+        if (kpiIdBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+            bitField0_ = (bitField0_ & ~0x00000001);
           }
-          ensureSubsListIsMutable();
-          subsList_.add(index, value);
-          onChanged();
+          result.kpiId_ = kpiId_;
         } else {
-          subsListBuilder_.addMessage(index, value);
+          result.kpiId_ = kpiIdBuilder_.build();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(
-          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.add(builderForValue.build());
-          onChanged();
+        if (kpiValueRangeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) != 0)) {
+            kpiValueRange_ = java.util.Collections.unmodifiableList(kpiValueRange_);
+            bitField0_ = (bitField0_ & ~0x00000002);
+          }
+          result.kpiValueRange_ = kpiValueRange_;
         } else {
-          subsListBuilder_.addMessage(builderForValue.build());
+          result.kpiValueRange_ = kpiValueRangeBuilder_.build();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(
-          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.add(index, builderForValue.build());
-          onChanged();
+        if (timestampBuilder_ == null) {
+          result.timestamp_ = timestamp_;
         } else {
-          subsListBuilder_.addMessage(index, builderForValue.build());
+          result.timestamp_ = timestampBuilder_.build();
         }
-        return this;
+        onBuilt();
+        return result;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addAllSubsList(
-          java.lang.Iterable<? extends monitoring.Monitoring.SubscriptionID> values) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, subsList_);
-          onChanged();
+
+      @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.AlarmDescriptor) {
+          return mergeFrom((monitoring.Monitoring.AlarmDescriptor)other);
         } else {
-          subsListBuilder_.addAllMessages(values);
+          super.mergeFrom(other);
+          return this;
         }
-        return this;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder clearSubsList() {
-        if (subsListBuilder_ == null) {
-          subsList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+
+      public Builder mergeFrom(monitoring.Monitoring.AlarmDescriptor other) {
+        if (other == monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()) return this;
+        if (other.hasAlarmId()) {
+          mergeAlarmId(other.getAlarmId());
+        }
+        if (!other.getAlarmDescription().isEmpty()) {
+          alarmDescription_ = other.alarmDescription_;
           onChanged();
-        } else {
-          subsListBuilder_.clear();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder removeSubsList(int index) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.remove(index);
+        if (!other.getName().isEmpty()) {
+          name_ = other.name_;
           onChanged();
-        } else {
-          subsListBuilder_.remove(index);
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder getSubsListBuilder(
-          int index) {
-        return getSubsListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
-          int index) {
-        if (subsListBuilder_ == null) {
-          return subsList_.get(index);  } else {
-          return subsListBuilder_.getMessageOrBuilder(index);
+        if (kpiIdBuilder_ == null) {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiId_.isEmpty()) {
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiIdIsMutable();
+              kpiId_.addAll(other.kpiId_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiIdBuilder_.isEmpty()) {
+              kpiIdBuilder_.dispose();
+              kpiIdBuilder_ = null;
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiIdBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiIdFieldBuilder() : null;
+            } else {
+              kpiIdBuilder_.addAllMessages(other.kpiId_);
+            }
+          }
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
-           getSubsListOrBuilderList() {
-        if (subsListBuilder_ != null) {
-          return subsListBuilder_.getMessageOrBuilderList();
+        if (kpiValueRangeBuilder_ == null) {
+          if (!other.kpiValueRange_.isEmpty()) {
+            if (kpiValueRange_.isEmpty()) {
+              kpiValueRange_ = other.kpiValueRange_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+            } else {
+              ensureKpiValueRangeIsMutable();
+              kpiValueRange_.addAll(other.kpiValueRange_);
+            }
+            onChanged();
+          }
         } else {
-          return java.util.Collections.unmodifiableList(subsList_);
+          if (!other.kpiValueRange_.isEmpty()) {
+            if (kpiValueRangeBuilder_.isEmpty()) {
+              kpiValueRangeBuilder_.dispose();
+              kpiValueRangeBuilder_ = null;
+              kpiValueRange_ = other.kpiValueRange_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+              kpiValueRangeBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiValueRangeFieldBuilder() : null;
+            } else {
+              kpiValueRangeBuilder_.addAllMessages(other.kpiValueRange_);
+            }
+          }
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder() {
-        return getSubsListFieldBuilder().addBuilder(
-            monitoring.Monitoring.SubscriptionID.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder(
-          int index) {
-        return getSubsListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.SubscriptionID.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.SubscriptionID.Builder> 
-           getSubsListBuilderList() {
-        return getSubsListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
-          getSubsListFieldBuilder() {
-        if (subsListBuilder_ == null) {
-          subsListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
-                  subsList_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          subsList_ = null;
+        if (other.hasTimestamp()) {
+          mergeTimestamp(other.getTimestamp());
         }
-        return subsListBuilder_;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
       }
 
       @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      public final boolean isInitialized() {
+        return true;
       }
 
-
-      // @@protoc_insertion_point(builder_scope:monitoring.SubsIDList)
-    }
-
-    // @@protoc_insertion_point(class_scope:monitoring.SubsIDList)
-    private static final monitoring.Monitoring.SubsIDList DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsIDList();
-    }
-
-    public static monitoring.Monitoring.SubsIDList getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<SubsIDList>
-        PARSER = new com.google.protobuf.AbstractParser<SubsIDList>() {
       @java.lang.Override
-      public SubsIDList parsePartialFrom(
+      public Builder mergeFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubsIDList(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<SubsIDList> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<SubsIDList> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface AlarmDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.AlarmDescriptor)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The alarmDescription.
-     */
-    java.lang.String getAlarmDescription();
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The bytes for alarmDescription.
-     */
-    com.google.protobuf.ByteString
-        getAlarmDescriptionBytes();
-
-    /**
-     * <code>string name = 2;</code>
-     * @return The name.
-     */
-    java.lang.String getName();
-    /**
-     * <code>string name = 2;</code>
-     * @return The bytes for name.
-     */
-    com.google.protobuf.ByteString
-        getNameBytes();
-
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     * @return Whether the kpiId field is set.
-     */
-    boolean hasKpiId();
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     * @return The kpiId.
-     */
-    monitoring.Monitoring.KpiId getKpiId();
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
-
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return Whether the kpiValueRange field is set.
-     */
-    boolean hasKpiValueRange();
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return The kpiValueRange.
-     */
-    monitoring.Monitoring.KpiValueRange getKpiValueRange();
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     */
-    monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder();
-
-    /**
-     * <code>string timestamp = 5;</code>
-     * @return The timestamp.
-     */
-    java.lang.String getTimestamp();
-    /**
-     * <code>string timestamp = 5;</code>
-     * @return The bytes for timestamp.
-     */
-    com.google.protobuf.ByteString
-        getTimestampBytes();
-  }
-  /**
-   * Protobuf type {@code monitoring.AlarmDescriptor}
-   */
-  public static final class AlarmDescriptor extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.AlarmDescriptor)
-      AlarmDescriptorOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use AlarmDescriptor.newBuilder() to construct.
-    private AlarmDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private AlarmDescriptor() {
-      alarmDescription_ = "";
-      name_ = "";
-      timestamp_ = "";
-    }
-
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new AlarmDescriptor();
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private AlarmDescriptor(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
+          throws java.io.IOException {
+        monitoring.Monitoring.AlarmDescriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.AlarmDescriptor) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
       }
-      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();
-
-              alarmDescription_ = s;
-              break;
-            }
-            case 18: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              name_ = s;
-              break;
-            }
-            case 26: {
-              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();
-              }
+      private int bitField0_;
 
-              break;
-            }
-            case 34: {
-              monitoring.Monitoring.KpiValueRange.Builder subBuilder = null;
-              if (kpiValueRange_ != null) {
-                subBuilder = kpiValueRange_.toBuilder();
-              }
-              kpiValueRange_ = input.readMessage(monitoring.Monitoring.KpiValueRange.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiValueRange_);
-                kpiValueRange_ = subBuilder.buildPartial();
-              }
+      private monitoring.Monitoring.AlarmID alarmId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> alarmIdBuilder_;
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       * @return Whether the alarmId field is set.
+       */
+      public boolean hasAlarmId() {
+        return alarmIdBuilder_ != null || alarmId_ != null;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       * @return The alarmId.
+       */
+      public monitoring.Monitoring.AlarmID getAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          return alarmId_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmId_;
+        } else {
+          return alarmIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder setAlarmId(monitoring.Monitoring.AlarmID value) {
+        if (alarmIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          alarmId_ = value;
+          onChanged();
+        } else {
+          alarmIdBuilder_.setMessage(value);
+        }
 
-              break;
-            }
-            case 42: {
-              java.lang.String s = input.readStringRequireUtf8();
+        return this;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder setAlarmId(
+          monitoring.Monitoring.AlarmID.Builder builderForValue) {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = builderForValue.build();
+          onChanged();
+        } else {
+          alarmIdBuilder_.setMessage(builderForValue.build());
+        }
 
-              timestamp_ = s;
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
+        return this;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder mergeAlarmId(monitoring.Monitoring.AlarmID value) {
+        if (alarmIdBuilder_ == null) {
+          if (alarmId_ != null) {
+            alarmId_ =
+              monitoring.Monitoring.AlarmID.newBuilder(alarmId_).mergeFrom(value).buildPartial();
+          } else {
+            alarmId_ = value;
           }
+          onChanged();
+        } else {
+          alarmIdBuilder_.mergeFrom(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 {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
+
+        return this;
       }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
-    }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder clearAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
+          onChanged();
+        } else {
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
+        }
 
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
-    }
+        return this;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public monitoring.Monitoring.AlarmID.Builder getAlarmIdBuilder() {
+        
+        onChanged();
+        return getAlarmIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIdOrBuilder() {
+        if (alarmIdBuilder_ != null) {
+          return alarmIdBuilder_.getMessageOrBuilder();
+        } else {
+          return alarmId_ == null ?
+              monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmId_;
+        }
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> 
+          getAlarmIdFieldBuilder() {
+        if (alarmIdBuilder_ == null) {
+          alarmIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder>(
+                  getAlarmId(),
+                  getParentForChildren(),
+                  isClean());
+          alarmId_ = null;
+        }
+        return alarmIdBuilder_;
+      }
 
-    public static final int ALARM_DESCRIPTION_FIELD_NUMBER = 1;
-    private volatile java.lang.Object alarmDescription_;
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The alarmDescription.
-     */
-    @java.lang.Override
-    public java.lang.String getAlarmDescription() {
-      java.lang.Object ref = alarmDescription_;
-      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();
-        alarmDescription_ = s;
-        return s;
+      private java.lang.Object alarmDescription_ = "";
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @return The alarmDescription.
+       */
+      public java.lang.String getAlarmDescription() {
+        java.lang.Object ref = alarmDescription_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          alarmDescription_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
       }
-    }
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The bytes for alarmDescription.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getAlarmDescriptionBytes() {
-      java.lang.Object ref = alarmDescription_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        alarmDescription_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @return The bytes for alarmDescription.
+       */
+      public com.google.protobuf.ByteString
+          getAlarmDescriptionBytes() {
+        java.lang.Object ref = alarmDescription_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          alarmDescription_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @param value The alarmDescription to set.
+       * @return This builder for chaining.
+       */
+      public Builder setAlarmDescription(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        alarmDescription_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearAlarmDescription() {
+        
+        alarmDescription_ = getDefaultInstance().getAlarmDescription();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @param value The bytes for alarmDescription to set.
+       * @return This builder for chaining.
+       */
+      public Builder setAlarmDescriptionBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        alarmDescription_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object name_ = "";
+      /**
+       * <code>string name = 3;</code>
+       * @return The name.
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
       }
-    }
-
-    public static final int NAME_FIELD_NUMBER = 2;
-    private volatile java.lang.Object name_;
-    /**
-     * <code>string name = 2;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      java.lang.Object ref = name_;
-      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();
-        name_ = s;
-        return s;
+      /**
+       * <code>string name = 3;</code>
+       * @return The bytes for name.
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
       }
-    }
-    /**
-     * <code>string name = 2;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      java.lang.Object ref = name_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        name_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      /**
+       * <code>string name = 3;</code>
+       * @param value The name to set.
+       * @return This builder for chaining.
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        name_ = value;
+        onChanged();
+        return this;
       }
-    }
-
-    public static final int KPI_ID_FIELD_NUMBER = 3;
-    private monitoring.Monitoring.KpiId kpiId_;
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     * @return Whether the kpiId field is set.
-     */
-    @java.lang.Override
-    public boolean hasKpiId() {
-      return kpiId_ != null;
-    }
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</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 = 3;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-      return getKpiId();
-    }
-
-    public static final int KPI_VALUE_RANGE_FIELD_NUMBER = 4;
-    private monitoring.Monitoring.KpiValueRange kpiValueRange_;
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return Whether the kpiValueRange field is set.
-     */
-    @java.lang.Override
-    public boolean hasKpiValueRange() {
-      return kpiValueRange_ != null;
-    }
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return The kpiValueRange.
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiValueRange getKpiValueRange() {
-      return kpiValueRange_ == null ? monitoring.Monitoring.KpiValueRange.getDefaultInstance() : kpiValueRange_;
-    }
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder() {
-      return getKpiValueRange();
-    }
-
-    public static final int TIMESTAMP_FIELD_NUMBER = 5;
-    private volatile java.lang.Object timestamp_;
-    /**
-     * <code>string timestamp = 5;</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 name = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearName() {
+        
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
       }
-    }
-    /**
-     * <code>string timestamp = 5;</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;
+      /**
+       * <code>string name = 3;</code>
+       * @param value The bytes for name to set.
+       * @return This builder for chaining.
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        name_ = value;
+        onChanged();
+        return this;
       }
-    }
 
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
+      private java.util.List<monitoring.Monitoring.KpiId> kpiId_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiIdIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiId_);
+          bitField0_ |= 0x00000001;
+         }
+      }
 
-      memoizedIsInitialized = 1;
-      return true;
-    }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
 
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (!getAlarmDescriptionBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, alarmDescription_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+        if (kpiIdBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        } else {
+          return kpiIdBuilder_.getMessageList();
+        }
       }
-      if (!getNameBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public int getKpiIdCount() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.size();
+        } else {
+          return kpiIdBuilder_.getCount();
+        }
       }
-      if (kpiId_ != null) {
-        output.writeMessage(3, getKpiId());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId getKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);
+        } else {
+          return kpiIdBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, value);
+        }
+        return this;
       }
-      if (kpiValueRange_ != null) {
-        output.writeMessage(4, getKpiValueRange());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (!getTimestampBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, timestamp_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(value);
+        }
+        return this;
       }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getAlarmDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, alarmDescription_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, value);
+        }
+        return this;
       }
-      if (!getNameBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
       }
-      if (kpiId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getKpiId());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (kpiValueRange_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getKpiValueRange());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addAllKpiId(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiId_);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addAllMessages(values);
+        }
+        return this;
       }
-      if (!getTimestampBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, timestamp_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiIdBuilder_.clear();
+        }
+        return this;
       }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder removeKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.remove(index);
+          onChanged();
+        } else {
+          kpiIdBuilder_.remove(index);
+        }
+        return this;
       }
-      if (!(obj instanceof monitoring.Monitoring.AlarmDescriptor)) {
-        return super.equals(obj);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().getBuilder(index);
       }
-      monitoring.Monitoring.AlarmDescriptor other = (monitoring.Monitoring.AlarmDescriptor) obj;
-
-      if (!getAlarmDescription()
-          .equals(other.getAlarmDescription())) return false;
-      if (!getName()
-          .equals(other.getName())) return false;
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
+          int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);  } else {
+          return kpiIdBuilder_.getMessageOrBuilder(index);
+        }
       }
-      if (hasKpiValueRange() != other.hasKpiValueRange()) return false;
-      if (hasKpiValueRange()) {
-        if (!getKpiValueRange()
-            .equals(other.getKpiValueRange())) return false;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+           getKpiIdOrBuilderList() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        }
       }
-      if (!getTimestamp()
-          .equals(other.getTimestamp())) return false;
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder() {
+        return getKpiIdFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiId.getDefaultInstance());
       }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + ALARM_DESCRIPTION_FIELD_NUMBER;
-      hash = (53 * hash) + getAlarmDescription().hashCode();
-      hash = (37 * hash) + NAME_FIELD_NUMBER;
-      hash = (53 * hash) + getName().hashCode();
-      if (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiId.getDefaultInstance());
       }
-      if (hasKpiValueRange()) {
-        hash = (37 * hash) + KPI_VALUE_RANGE_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiValueRange().hashCode();
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
+           getKpiIdBuilderList() {
+        return getKpiIdFieldBuilder().getBuilderList();
       }
-      hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
-      hash = (53 * hash) + getTimestamp().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor 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.AlarmDescriptor}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.AlarmDescriptor)
-        monitoring.Monitoring.AlarmDescriptorOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  kpiId_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
       }
 
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
+      private java.util.List<monitoring.Monitoring.KpiValueRange> kpiValueRange_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiValueRangeIsMutable() {
+        if (!((bitField0_ & 0x00000002) != 0)) {
+          kpiValueRange_ = new java.util.ArrayList<monitoring.Monitoring.KpiValueRange>(kpiValueRange_);
+          bitField0_ |= 0x00000002;
+         }
       }
 
-      // Construct using monitoring.Monitoring.AlarmDescriptor.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> kpiValueRangeBuilder_;
 
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiValueRange> getKpiValueRangeList() {
+        if (kpiValueRangeBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiValueRange_);
+        } else {
+          return kpiValueRangeBuilder_.getMessageList();
+        }
       }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public int getKpiValueRangeCount() {
+        if (kpiValueRangeBuilder_ == null) {
+          return kpiValueRange_.size();
+        } else {
+          return kpiValueRangeBuilder_.getCount();
         }
       }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        alarmDescription_ = "";
-
-        name_ = "";
-
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange getKpiValueRange(int index) {
+        if (kpiValueRangeBuilder_ == null) {
+          return kpiValueRange_.get(index);
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          return kpiValueRangeBuilder_.getMessage(index);
         }
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder setKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange value) {
         if (kpiValueRangeBuilder_ == null) {
-          kpiValueRange_ = null;
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.set(index, value);
+          onChanged();
         } else {
-          kpiValueRange_ = null;
-          kpiValueRangeBuilder_ = null;
+          kpiValueRangeBuilder_.setMessage(index, value);
         }
-        timestamp_ = "";
-
         return this;
       }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder setKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
-
-      @java.lang.Override
-      public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.AlarmDescriptor.getDefaultInstance();
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(monitoring.Monitoring.KpiValueRange value) {
+        if (kpiValueRangeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(value);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.addMessage(value);
+        }
+        return this;
       }
-
-      @java.lang.Override
-      public monitoring.Monitoring.AlarmDescriptor build() {
-        monitoring.Monitoring.AlarmDescriptor result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange value) {
+        if (kpiValueRangeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(index, value);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.addMessage(index, value);
         }
-        return result;
+        return this;
       }
-
-      @java.lang.Override
-      public monitoring.Monitoring.AlarmDescriptor buildPartial() {
-        monitoring.Monitoring.AlarmDescriptor result = new monitoring.Monitoring.AlarmDescriptor(this);
-        result.alarmDescription_ = alarmDescription_;
-        result.name_ = name_;
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(
+          monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(builderForValue.build());
+          onChanged();
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          kpiValueRangeBuilder_.addMessage(builderForValue.build());
         }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
         if (kpiValueRangeBuilder_ == null) {
-          result.kpiValueRange_ = kpiValueRange_;
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(index, builderForValue.build());
+          onChanged();
         } else {
-          result.kpiValueRange_ = kpiValueRangeBuilder_.build();
+          kpiValueRangeBuilder_.addMessage(index, builderForValue.build());
         }
-        result.timestamp_ = timestamp_;
-        onBuilt();
-        return result;
+        return this;
       }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addAllKpiValueRange(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiValueRange> values) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiValueRange_);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.addAllMessages(values);
+        }
+        return this;
       }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder clearKpiValueRange() {
+        if (kpiValueRangeBuilder_ == null) {
+          kpiValueRange_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.clear();
+        }
+        return this;
       }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder removeKpiValueRange(int index) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.remove(index);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.remove(index);
+        }
+        return this;
       }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange.Builder getKpiValueRangeBuilder(
+          int index) {
+        return getKpiValueRangeFieldBuilder().getBuilder(index);
       }
-      @java.lang.Override
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return super.setRepeatedField(field, index, value);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder(
+          int index) {
+        if (kpiValueRangeBuilder_ == null) {
+          return kpiValueRange_.get(index);  } else {
+          return kpiValueRangeBuilder_.getMessageOrBuilder(index);
+        }
       }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiValueRangeOrBuilder> 
+           getKpiValueRangeOrBuilderList() {
+        if (kpiValueRangeBuilder_ != null) {
+          return kpiValueRangeBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiValueRange_);
+        }
       }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.AlarmDescriptor) {
-          return mergeFrom((monitoring.Monitoring.AlarmDescriptor)other);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange.Builder addKpiValueRangeBuilder() {
+        return getKpiValueRangeFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiValueRange.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange.Builder addKpiValueRangeBuilder(
+          int index) {
+        return getKpiValueRangeFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiValueRange.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiValueRange.Builder> 
+           getKpiValueRangeBuilderList() {
+        return getKpiValueRangeFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> 
+          getKpiValueRangeFieldBuilder() {
+        if (kpiValueRangeBuilder_ == null) {
+          kpiValueRangeBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder>(
+                  kpiValueRange_,
+                  ((bitField0_ & 0x00000002) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiValueRange_ = null;
+        }
+        return kpiValueRangeBuilder_;
+      }
+
+      private context.ContextOuterClass.Timestamp timestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> timestampBuilder_;
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       * @return Whether the timestamp field is set.
+       */
+      public boolean hasTimestamp() {
+        return timestampBuilder_ != null || timestamp_ != null;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       * @return The timestamp.
+       */
+      public context.ContextOuterClass.Timestamp getTimestamp() {
+        if (timestampBuilder_ == null) {
+          return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        } else {
+          return timestampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder setTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          timestamp_ = value;
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder setTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (timestampBuilder_ == null) {
+          timestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder mergeTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (timestamp_ != null) {
+            timestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(timestamp_).mergeFrom(value).buildPartial();
+          } else {
+            timestamp_ = value;
+          }
+          onChanged();
         } else {
-          super.mergeFrom(other);
-          return this;
+          timestampBuilder_.mergeFrom(value);
         }
-      }
 
-      public Builder mergeFrom(monitoring.Monitoring.AlarmDescriptor other) {
-        if (other == monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()) return this;
-        if (!other.getAlarmDescription().isEmpty()) {
-          alarmDescription_ = other.alarmDescription_;
-          onChanged();
-        }
-        if (!other.getName().isEmpty()) {
-          name_ = other.name_;
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder clearTimestamp() {
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
           onChanged();
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
         }
-        if (other.hasKpiId()) {
-          mergeKpiId(other.getKpiId());
-        }
-        if (other.hasKpiValueRange()) {
-          mergeKpiValueRange(other.getKpiValueRange());
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getTimestampBuilder() {
+        
+        onChanged();
+        return getTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+        if (timestampBuilder_ != null) {
+          return timestampBuilder_.getMessageOrBuilder();
+        } else {
+          return timestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
         }
-        if (!other.getTimestamp().isEmpty()) {
-          timestamp_ = other.timestamp_;
-          onChanged();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getTimestampFieldBuilder() {
+        if (timestampBuilder_ == null) {
+          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          timestamp_ = null;
         }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
+        return timestampBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
       }
 
       @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
 
+
+      // @@protoc_insertion_point(builder_scope:monitoring.AlarmDescriptor)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.AlarmDescriptor)
+    private static final monitoring.Monitoring.AlarmDescriptor DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmDescriptor();
+    }
+
+    public static monitoring.Monitoring.AlarmDescriptor getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<AlarmDescriptor>
+        PARSER = new com.google.protobuf.AbstractParser<AlarmDescriptor>() {
       @java.lang.Override
-      public Builder mergeFrom(
+      public AlarmDescriptor parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        monitoring.Monitoring.AlarmDescriptor parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.AlarmDescriptor) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AlarmDescriptor(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<AlarmDescriptor> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AlarmDescriptor> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface AlarmIDOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.AlarmID)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
+     */
+    boolean hasAlarmId();
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return The alarmId.
+     */
+    context.ContextOuterClass.Uuid getAlarmId();
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder();
+  }
+  /**
+   * Protobuf type {@code monitoring.AlarmID}
+   */
+  public static final class AlarmID extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.AlarmID)
+      AlarmIDOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use AlarmID.newBuilder() to construct.
+    private AlarmID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private AlarmID() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new AlarmID();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AlarmID(
+        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 (alarmId_ != null) {
+                subBuilder = alarmId_.toBuilder();
+              }
+              alarmId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(alarmId_);
+                alarmId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
           }
         }
-        return this;
+      } 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_AlarmID_descriptor;
+    }
 
-      private java.lang.Object alarmDescription_ = "";
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @return The alarmDescription.
-       */
-      public java.lang.String getAlarmDescription() {
-        java.lang.Object ref = alarmDescription_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          alarmDescription_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
+    }
+
+    public static final int ALARM_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid alarmId_;
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
+     */
+    @java.lang.Override
+    public boolean hasAlarmId() {
+      return alarmId_ != null;
+    }
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return The alarmId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getAlarmId() {
+      return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+    }
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
+      return getAlarmId();
+    }
+
+    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 (alarmId_ != null) {
+        output.writeMessage(1, getAlarmId());
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @return The bytes for alarmDescription.
-       */
-      public com.google.protobuf.ByteString
-          getAlarmDescriptionBytes() {
-        java.lang.Object ref = alarmDescription_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          alarmDescription_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (alarmId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getAlarmId());
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @param value The alarmDescription to set.
-       * @return This builder for chaining.
-       */
-      public Builder setAlarmDescription(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        alarmDescription_ = value;
-        onChanged();
-        return this;
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearAlarmDescription() {
-        
-        alarmDescription_ = getDefaultInstance().getAlarmDescription();
-        onChanged();
-        return this;
+      if (!(obj instanceof monitoring.Monitoring.AlarmID)) {
+        return super.equals(obj);
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @param value The bytes for alarmDescription to set.
-       * @return This builder for chaining.
-       */
-      public Builder setAlarmDescriptionBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        alarmDescription_ = value;
-        onChanged();
-        return this;
+      monitoring.Monitoring.AlarmID other = (monitoring.Monitoring.AlarmID) obj;
+
+      if (hasAlarmId() != other.hasAlarmId()) return false;
+      if (hasAlarmId()) {
+        if (!getAlarmId()
+            .equals(other.getAlarmId())) return false;
       }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
 
-      private java.lang.Object name_ = "";
-      /**
-       * <code>string name = 2;</code>
-       * @return The name.
-       */
-      public java.lang.String getName() {
-        java.lang.Object ref = name_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          name_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
       }
-      /**
-       * <code>string name = 2;</code>
-       * @return The bytes for name.
-       */
-      public com.google.protobuf.ByteString
-          getNameBytes() {
-        java.lang.Object ref = name_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          name_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasAlarmId()) {
+        hash = (37 * hash) + ALARM_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getAlarmId().hashCode();
       }
-      /**
-       * <code>string name = 2;</code>
-       * @param value The name to set.
-       * @return This builder for chaining.
-       */
-      public Builder setName(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        name_ = value;
-        onChanged();
-        return this;
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID 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.AlarmID}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.AlarmID)
+        monitoring.Monitoring.AlarmIDOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
       }
-      /**
-       * <code>string name = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearName() {
-        
-        name_ = getDefaultInstance().getName();
-        onChanged();
-        return this;
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
       }
-      /**
-       * <code>string name = 2;</code>
-       * @param value The bytes for name to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNameBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        name_ = value;
-        onChanged();
-        return this;
+
+      // Construct using monitoring.Monitoring.AlarmID.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
       }
 
-      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 = 3;</code>
-       * @return Whether the kpiId field is set.
-       */
-      public boolean hasKpiId() {
-        return kpiIdBuilder_ != null || kpiId_ != null;
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       * @return The kpiId.
-       */
-      public monitoring.Monitoring.KpiId getKpiId() {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
-        } else {
-          return kpiIdBuilder_.getMessage();
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          kpiId_ = value;
-          onChanged();
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
         } else {
-          kpiIdBuilder_.setMessage(value);
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
         }
-
         return this;
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public Builder setKpiId(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = builderForValue.build();
-          onChanged();
-        } else {
-          kpiIdBuilder_.setMessage(builderForValue.build());
-        }
 
-        return this;
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</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;
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
+        return monitoring.Monitoring.AlarmID.getDefaultInstance();
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public Builder clearKpiId() {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
-          onChanged();
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmID build() {
+        monitoring.Monitoring.AlarmID result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmID buildPartial() {
+        monitoring.Monitoring.AlarmID result = new monitoring.Monitoring.AlarmID(this);
+        if (alarmIdBuilder_ == null) {
+          result.alarmId_ = alarmId_;
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          result.alarmId_ = alarmIdBuilder_.build();
         }
+        onBuilt();
+        return result;
+      }
 
-        return this;
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
-        
-        onChanged();
-        return getKpiIdFieldBuilder().getBuilder();
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-        if (kpiIdBuilder_ != null) {
-          return kpiIdBuilder_.getMessageOrBuilder();
+      @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.AlarmID) {
+          return mergeFrom((monitoring.Monitoring.AlarmID)other);
         } else {
-          return kpiId_ == null ?
-              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+          super.mergeFrom(other);
+          return this;
         }
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</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;
+
+      public Builder mergeFrom(monitoring.Monitoring.AlarmID other) {
+        if (other == monitoring.Monitoring.AlarmID.getDefaultInstance()) return this;
+        if (other.hasAlarmId()) {
+          mergeAlarmId(other.getAlarmId());
         }
-        return kpiIdBuilder_;
+        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.AlarmID parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.AlarmID) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
       }
 
-      private monitoring.Monitoring.KpiValueRange kpiValueRange_;
+      private context.ContextOuterClass.Uuid alarmId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> kpiValueRangeBuilder_;
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> alarmIdBuilder_;
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-       * @return Whether the kpiValueRange field is set.
+       * <code>.context.Uuid alarm_id = 1;</code>
+       * @return Whether the alarmId field is set.
        */
-      public boolean hasKpiValueRange() {
-        return kpiValueRangeBuilder_ != null || kpiValueRange_ != null;
+      public boolean hasAlarmId() {
+        return alarmIdBuilder_ != null || alarmId_ != null;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-       * @return The kpiValueRange.
+       * <code>.context.Uuid alarm_id = 1;</code>
+       * @return The alarmId.
        */
-      public monitoring.Monitoring.KpiValueRange getKpiValueRange() {
-        if (kpiValueRangeBuilder_ == null) {
-          return kpiValueRange_ == null ? monitoring.Monitoring.KpiValueRange.getDefaultInstance() : kpiValueRange_;
+      public context.ContextOuterClass.Uuid getAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
         } else {
-          return kpiValueRangeBuilder_.getMessage();
+          return alarmIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder setKpiValueRange(monitoring.Monitoring.KpiValueRange value) {
-        if (kpiValueRangeBuilder_ == null) {
+      public Builder setAlarmId(context.ContextOuterClass.Uuid value) {
+        if (alarmIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          kpiValueRange_ = value;
+          alarmId_ = value;
           onChanged();
         } else {
-          kpiValueRangeBuilder_.setMessage(value);
+          alarmIdBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder setKpiValueRange(
-          monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
-        if (kpiValueRangeBuilder_ == null) {
-          kpiValueRange_ = builderForValue.build();
+      public Builder setAlarmId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = builderForValue.build();
           onChanged();
         } else {
-          kpiValueRangeBuilder_.setMessage(builderForValue.build());
+          alarmIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder mergeKpiValueRange(monitoring.Monitoring.KpiValueRange value) {
-        if (kpiValueRangeBuilder_ == null) {
-          if (kpiValueRange_ != null) {
-            kpiValueRange_ =
-              monitoring.Monitoring.KpiValueRange.newBuilder(kpiValueRange_).mergeFrom(value).buildPartial();
+      public Builder mergeAlarmId(context.ContextOuterClass.Uuid value) {
+        if (alarmIdBuilder_ == null) {
+          if (alarmId_ != null) {
+            alarmId_ =
+              context.ContextOuterClass.Uuid.newBuilder(alarmId_).mergeFrom(value).buildPartial();
           } else {
-            kpiValueRange_ = value;
+            alarmId_ = value;
           }
           onChanged();
         } else {
-          kpiValueRangeBuilder_.mergeFrom(value);
+          alarmIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder clearKpiValueRange() {
-        if (kpiValueRangeBuilder_ == null) {
-          kpiValueRange_ = null;
+      public Builder clearAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
           onChanged();
         } else {
-          kpiValueRange_ = null;
-          kpiValueRangeBuilder_ = null;
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public monitoring.Monitoring.KpiValueRange.Builder getKpiValueRangeBuilder() {
+      public context.ContextOuterClass.Uuid.Builder getAlarmIdBuilder() {
         
         onChanged();
-        return getKpiValueRangeFieldBuilder().getBuilder();
+        return getAlarmIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder() {
-        if (kpiValueRangeBuilder_ != null) {
-          return kpiValueRangeBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
+        if (alarmIdBuilder_ != null) {
+          return alarmIdBuilder_.getMessageOrBuilder();
         } else {
-          return kpiValueRange_ == null ?
-              monitoring.Monitoring.KpiValueRange.getDefaultInstance() : kpiValueRange_;
+          return alarmId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
         }
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> 
-          getKpiValueRangeFieldBuilder() {
-        if (kpiValueRangeBuilder_ == null) {
-          kpiValueRangeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder>(
-                  getKpiValueRange(),
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getAlarmIdFieldBuilder() {
+        if (alarmIdBuilder_ == null) {
+          alarmIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getAlarmId(),
                   getParentForChildren(),
                   isClean());
-          kpiValueRange_ = null;
-        }
-        return kpiValueRangeBuilder_;
-      }
-
-      private java.lang.Object timestamp_ = "";
-      /**
-       * <code>string timestamp = 5;</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 = 5;</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;
+          alarmId_ = null;
         }
-      }
-      /**
-       * <code>string timestamp = 5;</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 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearTimestamp() {
-        
-        timestamp_ = getDefaultInstance().getTimestamp();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string timestamp = 5;</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;
+        return alarmIdBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -17399,85 +16419,97 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.AlarmDescriptor)
+      // @@protoc_insertion_point(builder_scope:monitoring.AlarmID)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.AlarmDescriptor)
-    private static final monitoring.Monitoring.AlarmDescriptor DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.AlarmID)
+    private static final monitoring.Monitoring.AlarmID DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmDescriptor();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmID();
     }
 
-    public static monitoring.Monitoring.AlarmDescriptor getDefaultInstance() {
+    public static monitoring.Monitoring.AlarmID getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<AlarmDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<AlarmDescriptor>() {
+    private static final com.google.protobuf.Parser<AlarmID>
+        PARSER = new com.google.protobuf.AbstractParser<AlarmID>() {
       @java.lang.Override
-      public AlarmDescriptor parsePartialFrom(
+      public AlarmID parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new AlarmDescriptor(input, extensionRegistry);
+        return new AlarmID(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<AlarmDescriptor> parser() {
+    public static com.google.protobuf.Parser<AlarmID> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<AlarmDescriptor> getParserForType() {
+    public com.google.protobuf.Parser<AlarmID> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
+    public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface AlarmIDOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.AlarmID)
+  public interface AlarmSubscriptionOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.AlarmSubscription)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return Whether the alarmId field is set.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return Whether the alarmID field is set.
      */
-    boolean hasAlarmId();
+    boolean hasAlarmID();
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return The alarmId.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return The alarmID.
      */
-    context.ContextOuterClass.Uuid getAlarmId();
+    monitoring.Monitoring.AlarmID getAlarmID();
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder();
+    monitoring.Monitoring.AlarmIDOrBuilder getAlarmIDOrBuilder();
+
+    /**
+     * <code>float subscription_timeout_s = 2;</code>
+     * @return The subscriptionTimeoutS.
+     */
+    float getSubscriptionTimeoutS();
+
+    /**
+     * <code>float subscription_frequency_ms = 3;</code>
+     * @return The subscriptionFrequencyMs.
+     */
+    float getSubscriptionFrequencyMs();
   }
   /**
-   * Protobuf type {@code monitoring.AlarmID}
+   * Protobuf type {@code monitoring.AlarmSubscription}
    */
-  public static final class AlarmID extends
+  public static final class AlarmSubscription extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.AlarmID)
-      AlarmIDOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.AlarmSubscription)
+      AlarmSubscriptionOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use AlarmID.newBuilder() to construct.
-    private AlarmID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use AlarmSubscription.newBuilder() to construct.
+    private AlarmSubscription(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private AlarmID() {
+    private AlarmSubscription() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new AlarmID();
+      return new AlarmSubscription();
     }
 
     @java.lang.Override
@@ -17485,7 +16517,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private AlarmID(
+    private AlarmSubscription(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -17504,18 +16536,28 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
-              if (alarmId_ != null) {
-                subBuilder = alarmId_.toBuilder();
+              monitoring.Monitoring.AlarmID.Builder subBuilder = null;
+              if (alarmID_ != null) {
+                subBuilder = alarmID_.toBuilder();
               }
-              alarmId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              alarmID_ = input.readMessage(monitoring.Monitoring.AlarmID.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(alarmId_);
-                alarmId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(alarmID_);
+                alarmID_ = subBuilder.buildPartial();
               }
 
               break;
             }
+            case 21: {
+
+              subscriptionTimeoutS_ = input.readFloat();
+              break;
+            }
+            case 29: {
+
+              subscriptionFrequencyMs_ = input.readFloat();
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -17537,41 +16579,63 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
+              monitoring.Monitoring.AlarmSubscription.class, monitoring.Monitoring.AlarmSubscription.Builder.class);
     }
 
-    public static final int ALARM_ID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid alarmId_;
+    public static final int ALARMID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.AlarmID alarmID_;
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return Whether the alarmId field is set.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return Whether the alarmID field is set.
      */
     @java.lang.Override
-    public boolean hasAlarmId() {
-      return alarmId_ != null;
+    public boolean hasAlarmID() {
+      return alarmID_ != null;
     }
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return The alarmId.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return The alarmID.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getAlarmId() {
-      return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+    public monitoring.Monitoring.AlarmID getAlarmID() {
+      return alarmID_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmID_;
     }
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
-      return getAlarmId();
+    public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIDOrBuilder() {
+      return getAlarmID();
+    }
+
+    public static final int SUBSCRIPTION_TIMEOUT_S_FIELD_NUMBER = 2;
+    private float subscriptionTimeoutS_;
+    /**
+     * <code>float subscription_timeout_s = 2;</code>
+     * @return The subscriptionTimeoutS.
+     */
+    @java.lang.Override
+    public float getSubscriptionTimeoutS() {
+      return subscriptionTimeoutS_;
+    }
+
+    public static final int SUBSCRIPTION_FREQUENCY_MS_FIELD_NUMBER = 3;
+    private float subscriptionFrequencyMs_;
+    /**
+     * <code>float subscription_frequency_ms = 3;</code>
+     * @return The subscriptionFrequencyMs.
+     */
+    @java.lang.Override
+    public float getSubscriptionFrequencyMs() {
+      return subscriptionFrequencyMs_;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -17588,8 +16652,14 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (alarmId_ != null) {
-        output.writeMessage(1, getAlarmId());
+      if (alarmID_ != null) {
+        output.writeMessage(1, getAlarmID());
+      }
+      if (subscriptionTimeoutS_ != 0F) {
+        output.writeFloat(2, subscriptionTimeoutS_);
+      }
+      if (subscriptionFrequencyMs_ != 0F) {
+        output.writeFloat(3, subscriptionFrequencyMs_);
       }
       unknownFields.writeTo(output);
     }
@@ -17600,9 +16670,17 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (alarmId_ != null) {
+      if (alarmID_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getAlarmId());
+          .computeMessageSize(1, getAlarmID());
+      }
+      if (subscriptionTimeoutS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(2, subscriptionTimeoutS_);
+      }
+      if (subscriptionFrequencyMs_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, subscriptionFrequencyMs_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -17614,16 +16692,22 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.AlarmID)) {
+      if (!(obj instanceof monitoring.Monitoring.AlarmSubscription)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.AlarmID other = (monitoring.Monitoring.AlarmID) obj;
+      monitoring.Monitoring.AlarmSubscription other = (monitoring.Monitoring.AlarmSubscription) obj;
 
-      if (hasAlarmId() != other.hasAlarmId()) return false;
-      if (hasAlarmId()) {
-        if (!getAlarmId()
-            .equals(other.getAlarmId())) return false;
+      if (hasAlarmID() != other.hasAlarmID()) return false;
+      if (hasAlarmID()) {
+        if (!getAlarmID()
+            .equals(other.getAlarmID())) return false;
       }
+      if (java.lang.Float.floatToIntBits(getSubscriptionTimeoutS())
+          != java.lang.Float.floatToIntBits(
+              other.getSubscriptionTimeoutS())) return false;
+      if (java.lang.Float.floatToIntBits(getSubscriptionFrequencyMs())
+          != java.lang.Float.floatToIntBits(
+              other.getSubscriptionFrequencyMs())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -17635,78 +16719,84 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasAlarmId()) {
-        hash = (37 * hash) + ALARM_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getAlarmId().hashCode();
+      if (hasAlarmID()) {
+        hash = (37 * hash) + ALARMID_FIELD_NUMBER;
+        hash = (53 * hash) + getAlarmID().hashCode();
       }
+      hash = (37 * hash) + SUBSCRIPTION_TIMEOUT_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSubscriptionTimeoutS());
+      hash = (37 * hash) + SUBSCRIPTION_FREQUENCY_MS_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSubscriptionFrequencyMs());
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription 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.AlarmID parseFrom(byte[] data)
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription 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.AlarmID parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmSubscription parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.AlarmID parseDelimitedFrom(
+    public static monitoring.Monitoring.AlarmSubscription 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.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -17719,7 +16809,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.AlarmID prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.AlarmSubscription prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -17735,26 +16825,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.AlarmID}
+     * Protobuf type {@code monitoring.AlarmSubscription}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.AlarmID)
-        monitoring.Monitoring.AlarmIDOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.AlarmSubscription)
+        monitoring.Monitoring.AlarmSubscriptionOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
+                monitoring.Monitoring.AlarmSubscription.class, monitoring.Monitoring.AlarmSubscription.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.AlarmID.newBuilder()
+      // Construct using monitoring.Monitoring.AlarmSubscription.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -17772,29 +16862,33 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (alarmIdBuilder_ == null) {
-          alarmId_ = null;
+        if (alarmIDBuilder_ == null) {
+          alarmID_ = null;
         } else {
-          alarmId_ = null;
-          alarmIdBuilder_ = null;
+          alarmID_ = null;
+          alarmIDBuilder_ = null;
         }
+        subscriptionTimeoutS_ = 0F;
+
+        subscriptionFrequencyMs_ = 0F;
+
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
-        return monitoring.Monitoring.AlarmID.getDefaultInstance();
+      public monitoring.Monitoring.AlarmSubscription getDefaultInstanceForType() {
+        return monitoring.Monitoring.AlarmSubscription.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.AlarmID build() {
-        monitoring.Monitoring.AlarmID result = buildPartial();
+      public monitoring.Monitoring.AlarmSubscription build() {
+        monitoring.Monitoring.AlarmSubscription result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -17802,13 +16896,15 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.AlarmID buildPartial() {
-        monitoring.Monitoring.AlarmID result = new monitoring.Monitoring.AlarmID(this);
-        if (alarmIdBuilder_ == null) {
-          result.alarmId_ = alarmId_;
+      public monitoring.Monitoring.AlarmSubscription buildPartial() {
+        monitoring.Monitoring.AlarmSubscription result = new monitoring.Monitoring.AlarmSubscription(this);
+        if (alarmIDBuilder_ == null) {
+          result.alarmID_ = alarmID_;
         } else {
-          result.alarmId_ = alarmIdBuilder_.build();
+          result.alarmID_ = alarmIDBuilder_.build();
         }
+        result.subscriptionTimeoutS_ = subscriptionTimeoutS_;
+        result.subscriptionFrequencyMs_ = subscriptionFrequencyMs_;
         onBuilt();
         return result;
       }
@@ -17847,18 +16943,24 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.AlarmID) {
-          return mergeFrom((monitoring.Monitoring.AlarmID)other);
+        if (other instanceof monitoring.Monitoring.AlarmSubscription) {
+          return mergeFrom((monitoring.Monitoring.AlarmSubscription)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.AlarmID other) {
-        if (other == monitoring.Monitoring.AlarmID.getDefaultInstance()) return this;
-        if (other.hasAlarmId()) {
-          mergeAlarmId(other.getAlarmId());
+      public Builder mergeFrom(monitoring.Monitoring.AlarmSubscription other) {
+        if (other == monitoring.Monitoring.AlarmSubscription.getDefaultInstance()) return this;
+        if (other.hasAlarmID()) {
+          mergeAlarmID(other.getAlarmID());
+        }
+        if (other.getSubscriptionTimeoutS() != 0F) {
+          setSubscriptionTimeoutS(other.getSubscriptionTimeoutS());
+        }
+        if (other.getSubscriptionFrequencyMs() != 0F) {
+          setSubscriptionFrequencyMs(other.getSubscriptionFrequencyMs());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -17875,11 +16977,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.AlarmID parsedMessage = null;
+        monitoring.Monitoring.AlarmSubscription parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.AlarmID) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.AlarmSubscription) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -17889,123 +16991,185 @@ public final class Monitoring {
         return this;
       }
 
-      private context.ContextOuterClass.Uuid alarmId_;
+      private monitoring.Monitoring.AlarmID alarmID_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> alarmIdBuilder_;
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> alarmIDBuilder_;
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
-       * @return Whether the alarmId field is set.
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
+       * @return Whether the alarmID field is set.
        */
-      public boolean hasAlarmId() {
-        return alarmIdBuilder_ != null || alarmId_ != null;
+      public boolean hasAlarmID() {
+        return alarmIDBuilder_ != null || alarmID_ != null;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
-       * @return The alarmId.
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
+       * @return The alarmID.
        */
-      public context.ContextOuterClass.Uuid getAlarmId() {
-        if (alarmIdBuilder_ == null) {
-          return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+      public monitoring.Monitoring.AlarmID getAlarmID() {
+        if (alarmIDBuilder_ == null) {
+          return alarmID_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmID_;
         } else {
-          return alarmIdBuilder_.getMessage();
+          return alarmIDBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder setAlarmId(context.ContextOuterClass.Uuid value) {
-        if (alarmIdBuilder_ == null) {
+      public Builder setAlarmID(monitoring.Monitoring.AlarmID value) {
+        if (alarmIDBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          alarmId_ = value;
+          alarmID_ = value;
           onChanged();
         } else {
-          alarmIdBuilder_.setMessage(value);
+          alarmIDBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder setAlarmId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
-        if (alarmIdBuilder_ == null) {
-          alarmId_ = builderForValue.build();
+      public Builder setAlarmID(
+          monitoring.Monitoring.AlarmID.Builder builderForValue) {
+        if (alarmIDBuilder_ == null) {
+          alarmID_ = builderForValue.build();
           onChanged();
         } else {
-          alarmIdBuilder_.setMessage(builderForValue.build());
+          alarmIDBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder mergeAlarmId(context.ContextOuterClass.Uuid value) {
-        if (alarmIdBuilder_ == null) {
-          if (alarmId_ != null) {
-            alarmId_ =
-              context.ContextOuterClass.Uuid.newBuilder(alarmId_).mergeFrom(value).buildPartial();
+      public Builder mergeAlarmID(monitoring.Monitoring.AlarmID value) {
+        if (alarmIDBuilder_ == null) {
+          if (alarmID_ != null) {
+            alarmID_ =
+              monitoring.Monitoring.AlarmID.newBuilder(alarmID_).mergeFrom(value).buildPartial();
           } else {
-            alarmId_ = value;
+            alarmID_ = value;
           }
           onChanged();
         } else {
-          alarmIdBuilder_.mergeFrom(value);
+          alarmIDBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder clearAlarmId() {
-        if (alarmIdBuilder_ == null) {
-          alarmId_ = null;
+      public Builder clearAlarmID() {
+        if (alarmIDBuilder_ == null) {
+          alarmID_ = null;
           onChanged();
         } else {
-          alarmId_ = null;
-          alarmIdBuilder_ = null;
+          alarmID_ = null;
+          alarmIDBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public context.ContextOuterClass.Uuid.Builder getAlarmIdBuilder() {
+      public monitoring.Monitoring.AlarmID.Builder getAlarmIDBuilder() {
         
         onChanged();
-        return getAlarmIdFieldBuilder().getBuilder();
+        return getAlarmIDFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
-        if (alarmIdBuilder_ != null) {
-          return alarmIdBuilder_.getMessageOrBuilder();
+      public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIDOrBuilder() {
+        if (alarmIDBuilder_ != null) {
+          return alarmIDBuilder_.getMessageOrBuilder();
         } else {
-          return alarmId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+          return alarmID_ == null ?
+              monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmID_;
         }
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
-          getAlarmIdFieldBuilder() {
-        if (alarmIdBuilder_ == null) {
-          alarmIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
-                  getAlarmId(),
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> 
+          getAlarmIDFieldBuilder() {
+        if (alarmIDBuilder_ == null) {
+          alarmIDBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder>(
+                  getAlarmID(),
                   getParentForChildren(),
                   isClean());
-          alarmId_ = null;
+          alarmID_ = null;
         }
-        return alarmIdBuilder_;
+        return alarmIDBuilder_;
+      }
+
+      private float subscriptionTimeoutS_ ;
+      /**
+       * <code>float subscription_timeout_s = 2;</code>
+       * @return The subscriptionTimeoutS.
+       */
+      @java.lang.Override
+      public float getSubscriptionTimeoutS() {
+        return subscriptionTimeoutS_;
+      }
+      /**
+       * <code>float subscription_timeout_s = 2;</code>
+       * @param value The subscriptionTimeoutS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSubscriptionTimeoutS(float value) {
+        
+        subscriptionTimeoutS_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float subscription_timeout_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSubscriptionTimeoutS() {
+        
+        subscriptionTimeoutS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float subscriptionFrequencyMs_ ;
+      /**
+       * <code>float subscription_frequency_ms = 3;</code>
+       * @return The subscriptionFrequencyMs.
+       */
+      @java.lang.Override
+      public float getSubscriptionFrequencyMs() {
+        return subscriptionFrequencyMs_;
+      }
+      /**
+       * <code>float subscription_frequency_ms = 3;</code>
+       * @param value The subscriptionFrequencyMs to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSubscriptionFrequencyMs(float value) {
+        
+        subscriptionFrequencyMs_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float subscription_frequency_ms = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSubscriptionFrequencyMs() {
+        
+        subscriptionFrequencyMs_ = 0F;
+        onChanged();
+        return this;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -18020,41 +17184,41 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.AlarmID)
+      // @@protoc_insertion_point(builder_scope:monitoring.AlarmSubscription)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.AlarmID)
-    private static final monitoring.Monitoring.AlarmID DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.AlarmSubscription)
+    private static final monitoring.Monitoring.AlarmSubscription DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmID();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmSubscription();
     }
 
-    public static monitoring.Monitoring.AlarmID getDefaultInstance() {
+    public static monitoring.Monitoring.AlarmSubscription getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<AlarmID>
-        PARSER = new com.google.protobuf.AbstractParser<AlarmID>() {
+    private static final com.google.protobuf.Parser<AlarmSubscription>
+        PARSER = new com.google.protobuf.AbstractParser<AlarmSubscription>() {
       @java.lang.Override
-      public AlarmID parsePartialFrom(
+      public AlarmSubscription parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new AlarmID(input, extensionRegistry);
+        return new AlarmSubscription(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<AlarmID> parser() {
+    public static com.google.protobuf.Parser<AlarmSubscription> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<AlarmID> getParserForType() {
+    public com.google.protobuf.Parser<AlarmSubscription> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
+    public monitoring.Monitoring.AlarmSubscription getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
@@ -18105,6 +17269,21 @@ public final class Monitoring {
      * <code>.monitoring.KpiValue kpi_value = 3;</code>
      */
     monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
+
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return Whether the timestamp field is set.
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return The timestamp.
+     */
+    context.ContextOuterClass.Timestamp getTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder();
   }
   /**
    * Protobuf type {@code monitoring.AlarmResponse}
@@ -18184,6 +17363,19 @@ public final class Monitoring {
 
               break;
             }
+            case 34: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (timestamp_ != null) {
+                subBuilder = timestamp_.toBuilder();
+              }
+              timestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(timestamp_);
+                timestamp_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -18306,6 +17498,32 @@ public final class Monitoring {
       return getKpiValue();
     }
 
+    public static final int TIMESTAMP_FIELD_NUMBER = 4;
+    private context.ContextOuterClass.Timestamp timestamp_;
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return Whether the timestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasTimestamp() {
+      return timestamp_ != null;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getTimestamp() {
+      return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+      return getTimestamp();
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -18329,6 +17547,9 @@ public final class Monitoring {
       if (kpiValue_ != null) {
         output.writeMessage(3, getKpiValue());
       }
+      if (timestamp_ != null) {
+        output.writeMessage(4, getTimestamp());
+      }
       unknownFields.writeTo(output);
     }
 
@@ -18349,6 +17570,10 @@ public final class Monitoring {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getKpiValue());
       }
+      if (timestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, getTimestamp());
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -18376,6 +17601,11 @@ public final class Monitoring {
         if (!getKpiValue()
             .equals(other.getKpiValue())) return false;
       }
+      if (hasTimestamp() != other.hasTimestamp()) return false;
+      if (hasTimestamp()) {
+        if (!getTimestamp()
+            .equals(other.getTimestamp())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -18397,6 +17627,10 @@ public final class Monitoring {
         hash = (37 * hash) + KPI_VALUE_FIELD_NUMBER;
         hash = (53 * hash) + getKpiValue().hashCode();
       }
+      if (hasTimestamp()) {
+        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getTimestamp().hashCode();
+      }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -18544,6 +17778,12 @@ public final class Monitoring {
           kpiValue_ = null;
           kpiValueBuilder_ = null;
         }
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
         return this;
       }
 
@@ -18581,6 +17821,11 @@ public final class Monitoring {
         } else {
           result.kpiValue_ = kpiValueBuilder_.build();
         }
+        if (timestampBuilder_ == null) {
+          result.timestamp_ = timestamp_;
+        } else {
+          result.timestamp_ = timestampBuilder_.build();
+        }
         onBuilt();
         return result;
       }
@@ -18639,6 +17884,9 @@ public final class Monitoring {
         if (other.hasKpiValue()) {
           mergeKpiValue(other.getKpiValue());
         }
+        if (other.hasTimestamp()) {
+          mergeTimestamp(other.getTimestamp());
+        }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
@@ -18981,6 +18229,125 @@ public final class Monitoring {
         }
         return kpiValueBuilder_;
       }
+
+      private context.ContextOuterClass.Timestamp timestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> timestampBuilder_;
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       * @return Whether the timestamp field is set.
+       */
+      public boolean hasTimestamp() {
+        return timestampBuilder_ != null || timestamp_ != null;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       * @return The timestamp.
+       */
+      public context.ContextOuterClass.Timestamp getTimestamp() {
+        if (timestampBuilder_ == null) {
+          return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        } else {
+          return timestampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder setTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          timestamp_ = value;
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder setTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (timestampBuilder_ == null) {
+          timestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder mergeTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (timestamp_ != null) {
+            timestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(timestamp_).mergeFrom(value).buildPartial();
+          } else {
+            timestamp_ = value;
+          }
+          onChanged();
+        } else {
+          timestampBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder clearTimestamp() {
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+          onChanged();
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getTimestampBuilder() {
+        
+        onChanged();
+        return getTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+        if (timestampBuilder_ != null) {
+          return timestampBuilder_.getMessageOrBuilder();
+        } else {
+          return timestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getTimestampFieldBuilder() {
+        if (timestampBuilder_ == null) {
+          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          timestamp_ = null;
+        }
+        return timestampBuilder_;
+      }
       @java.lang.Override
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
@@ -19832,16 +19199,6 @@ public final class Monitoring {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_monitoring_KpiDescriptor_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_monitoring_BundleKpiDescriptor_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_monitoring_EditedKpiDescriptor_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_monitoring_MonitorKpiRequest_descriptor;
   private static final 
@@ -19912,6 +19269,11 @@ public final class Monitoring {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_monitoring_AlarmID_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_AlarmSubscription_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_AlarmSubscription_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_monitoring_AlarmResponse_descriptor;
   private static final 
@@ -19932,97 +19294,95 @@ public final class Monitoring {
   static {
     java.lang.String[] descriptorData = {
       "\n\020monitoring.proto\022\nmonitoring\032\rcontext." +
-      "proto\032\026kpi_sample_types.proto\"\376\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\022\"\n\010slice_id\030\006 \001(\0132\020.context.S" +
-      "liceId\"\254\002\n\023BundleKpiDescriptor\022\027\n\017kpi_de" +
-      "scription\030\001 \001(\t\022&\n\013kpi_id_list\030\002 \003(\0132\021.m" +
-      "onitoring.KpiId\0228\n\017kpi_sample_type\030\003 \001(\016" +
-      "2\037.kpi_sample_types.KpiSampleType\022$\n\tdev" +
-      "ice_id\030\004 \001(\0132\021.context.DeviceId\022(\n\013endpo" +
-      "int_id\030\005 \001(\0132\023.context.EndPointId\022&\n\nser" +
-      "vice_id\030\006 \001(\0132\022.context.ServiceId\022\"\n\010sli" +
-      "ce_id\030\007 \001(\0132\020.context.SliceId\"\317\002\n\023Edited" +
-      "KpiDescriptor\022!\n\006kpi_id\030\001 \001(\0132\021.monitori" +
-      "ng.KpiId\022\027\n\017kpi_description\030\002 \001(\t\022&\n\013kpi" +
-      "_id_list\030\003 \003(\0132\021.monitoring.KpiId\0228\n\017kpi" +
-      "_sample_type\030\004 \001(\0162\037.kpi_sample_types.Kp" +
-      "iSampleType\022$\n\tdevice_id\030\005 \001(\0132\021.context" +
-      ".DeviceId\022(\n\013endpoint_id\030\006 \001(\0132\023.context" +
-      ".EndPointId\022&\n\nservice_id\030\007 \001(\0132\022.contex" +
-      "t.ServiceId\022\"\n\010slice_id\030\010 \001(\0132\020.context." +
-      "SliceId\"l\n\021MonitorKpiRequest\022!\n\006kpi_id\030\001" +
-      " \001(\0132\021.monitoring.KpiId\022\033\n\023monitoring_wi" +
-      "ndow_s\030\002 \001(\002\022\027\n\017sampling_rate_s\030\003 \001(\002\"\241\001" +
-      "\n\010KpiQuery\022!\n\006kpi_id\030\001 \003(\0132\021.monitoring." +
-      "KpiId\022\033\n\023monitoring_window_s\030\002 \001(\002\022\027\n\017sa" +
-      "mpling_rate_s\030\003 \001(\002\022\026\n\016last_n_samples\030\004 " +
-      "\001(\r\022\022\n\nstart_date\030\005 \001(\t\022\020\n\010end_date\030\006 \001(" +
-      "\t\"&\n\005KpiId\022\035\n\006kpi_id\030\001 \001(\0132\r.context.Uui" +
-      "d\"d\n\003Kpi\022!\n\006kpi_id\030\001 \001(\0132\021.monitoring.Kp" +
-      "iId\022\021\n\ttimestamp\030\002 \001(\t\022\'\n\tkpi_value\030\003 \001(" +
-      "\0132\024.monitoring.KpiValue\"e\n\rKpiValueRange" +
-      "\022)\n\013kpiMinValue\030\001 \001(\0132\024.monitoring.KpiVa" +
-      "lue\022)\n\013kpiMaxValue\030\002 \001(\0132\024.monitoring.Kp" +
-      "iValue\"a\n\010KpiValue\022\020\n\006intVal\030\001 \001(\rH\000\022\022\n\010" +
-      "floatVal\030\002 \001(\002H\000\022\023\n\tstringVal\030\003 \001(\tH\000\022\021\n" +
-      "\007boolVal\030\004 \001(\010H\000B\007\n\005value\",\n\007KpiList\022!\n\010" +
-      "kpi_list\030\001 \003(\0132\017.monitoring.Kpi\"K\n\021KpiDe" +
-      "scriptorList\0226\n\023kpi_descriptor_list\030\001 \003(" +
-      "\0132\031.monitoring.KpiDescriptor\"\223\001\n\016SubsDes" +
+      "proto\032\026kpi_sample_types.proto\"\311\002\n\rKpiDes" +
       "criptor\022!\n\006kpi_id\030\001 \001(\0132\021.monitoring.Kpi" +
-      "Id\022\033\n\023sampling_duration_s\030\002 \001(\002\022\033\n\023sampl" +
-      "ing_interval_s\030\003 \001(\002\022\022\n\nstart_date\030\004 \001(\t" +
-      "\022\020\n\010end_date\030\005 \001(\t\"0\n\016SubscriptionID\022\036\n\007" +
-      "subs_id\030\001 \001(\0132\r.context.Uuid\"b\n\014SubsResp" +
-      "onse\022+\n\007subs_id\030\001 \001(\0132\032.monitoring.Subsc" +
-      "riptionID\022%\n\010kpi_list\030\002 \003(\0132\023.monitoring" +
-      ".KpiList\";\n\nSubsIDList\022-\n\tsubs_list\030\001 \003(" +
-      "\0132\032.monitoring.SubscriptionID\"\244\001\n\017AlarmD" +
-      "escriptor\022\031\n\021alarm_description\030\001 \001(\t\022\014\n\004" +
-      "name\030\002 \001(\t\022!\n\006kpi_id\030\003 \001(\0132\021.monitoring." +
-      "KpiId\0222\n\017kpi_value_range\030\004 \001(\0132\031.monitor" +
-      "ing.KpiValueRange\022\021\n\ttimestamp\030\005 \001(\t\"*\n\007" +
-      "AlarmID\022\037\n\010alarm_id\030\001 \001(\0132\r.context.Uuid" +
-      "\"m\n\rAlarmResponse\022%\n\010alarm_id\030\001 \001(\0132\023.mo" +
-      "nitoring.AlarmID\022\014\n\004text\030\002 \001(\t\022\'\n\tkpi_va" +
-      "lue\030\003 \001(\0132\024.monitoring.KpiValue\"6\n\013Alarm" +
-      "IDList\022\'\n\nalarm_list\030\001 \003(\0132\023.monitoring." +
-      "AlarmID2\271\t\n\021MonitoringService\022;\n\tCreateK" +
-      "pi\022\031.monitoring.KpiDescriptor\032\021.monitori" +
-      "ng.KpiId\"\000\022F\n\021EditKpiDescriptor\022\037.monito" +
-      "ring.EditedKpiDescriptor\032\016.context.Empty" +
-      "\"\000\0220\n\tDeleteKpi\022\021.monitoring.KpiId\032\016.con" +
-      "text.Empty\"\000\022G\n\024GetKpiDescriptorList\022\016.c" +
-      "ontext.Empty\032\035.monitoring.KpiDescriptorL" +
-      "ist\"\000\022G\n\017CreateBundleKpi\022\037.monitoring.Bu" +
-      "ndleKpiDescriptor\032\021.monitoring.KpiId\"\000\022B" +
-      "\n\020GetKpiDescriptor\022\021.monitoring.KpiId\032\031." +
-      "monitoring.KpiDescriptor\"\000\022/\n\nIncludeKpi" +
-      "\022\017.monitoring.Kpi\032\016.context.Empty\"\000\022=\n\nM" +
-      "onitorKpi\022\035.monitoring.MonitorKpiRequest" +
-      "\032\016.context.Empty\"\000\022;\n\014QueryKpiData\022\024.mon" +
-      "itoring.KpiQuery\032\023.monitoring.KpiList\"\000\022" +
-      "C\n\014SubscribeKpi\022\032.monitoring.SubsDescrip" +
-      "tor\032\023.monitoring.KpiList\"\0000\001\022M\n\021GetSubsD" +
-      "escriptor\022\032.monitoring.SubscriptionID\032\032." +
-      "monitoring.SubsDescriptor\"\000\022<\n\020GetSubscr" +
-      "iptions\022\016.context.Empty\032\026.monitoring.Sub" +
-      "sIDList\"\000\022C\n\023EditKpiSubscription\022\032.monit" +
-      "oring.SubsDescriptor\032\016.context.Empty\"\000\022D" +
-      "\n\016CreateKpiAlarm\022\033.monitoring.AlarmDescr" +
-      "iptor\032\023.monitoring.AlarmID\"\000\022=\n\014EditKpiA" +
-      "larm\022\033.monitoring.AlarmDescriptor\032\016.cont" +
-      "ext.Empty\"\000\0226\n\tGetAlarms\022\016.context.Empty" +
-      "\032\027.monitoring.AlarmIDList\"\000\022H\n\022GetAlarmD" +
-      "escriptor\022\023.monitoring.AlarmID\032\033.monitor" +
-      "ing.AlarmDescriptor\"\000\022L\n\026GetAlarmRespons" +
-      "eStream\022\023.monitoring.AlarmID\032\031.monitorin" +
-      "g.AlarmResponse\"\0000\001b\006proto3"
+      "Id\022\027\n\017kpi_description\030\002 \001(\t\022&\n\013kpi_id_li" +
+      "st\030\003 \003(\0132\021.monitoring.KpiId\0228\n\017kpi_sampl" +
+      "e_type\030\004 \001(\0162\037.kpi_sample_types.KpiSampl" +
+      "eType\022$\n\tdevice_id\030\005 \001(\0132\021.context.Devic" +
+      "eId\022(\n\013endpoint_id\030\006 \001(\0132\023.context.EndPo" +
+      "intId\022&\n\nservice_id\030\007 \001(\0132\022.context.Serv" +
+      "iceId\022\"\n\010slice_id\030\010 \001(\0132\020.context.SliceI" +
+      "d\"l\n\021MonitorKpiRequest\022!\n\006kpi_id\030\001 \001(\0132\021" +
+      ".monitoring.KpiId\022\033\n\023monitoring_window_s" +
+      "\030\002 \001(\002\022\027\n\017sampling_rate_s\030\003 \001(\002\"\323\001\n\010KpiQ" +
+      "uery\022!\n\006kpi_id\030\001 \003(\0132\021.monitoring.KpiId\022" +
+      "\033\n\023monitoring_window_s\030\002 \001(\002\022\027\n\017sampling" +
+      "_rate_s\030\003 \001(\002\022\026\n\016last_n_samples\030\004 \001(\r\022+\n" +
+      "\017start_timestamp\030\005 \001(\0132\022.context.Timesta" +
+      "mp\022)\n\rend_timestamp\030\006 \001(\0132\022.context.Time" +
+      "stamp\"&\n\005KpiId\022\035\n\006kpi_id\030\001 \001(\0132\r.context" +
+      ".Uuid\"x\n\003Kpi\022!\n\006kpi_id\030\001 \001(\0132\021.monitorin" +
+      "g.KpiId\022%\n\ttimestamp\030\002 \001(\0132\022.context.Tim" +
+      "estamp\022\'\n\tkpi_value\030\003 \001(\0132\024.monitoring.K" +
+      "piValue\"\250\001\n\rKpiValueRange\022)\n\013kpiMinValue" +
+      "\030\001 \001(\0132\024.monitoring.KpiValue\022)\n\013kpiMaxVa" +
+      "lue\030\002 \001(\0132\024.monitoring.KpiValue\022\017\n\007inRan" +
+      "ge\030\003 \001(\010\022\027\n\017includeMinValue\030\004 \001(\010\022\027\n\017inc" +
+      "ludeMaxValue\030\005 \001(\010\"\241\001\n\010KpiValue\022\022\n\010int32" +
+      "Val\030\001 \001(\005H\000\022\023\n\tuint32Val\030\002 \001(\rH\000\022\022\n\010int6" +
+      "4Val\030\003 \001(\003H\000\022\023\n\tuint64Val\030\004 \001(\004H\000\022\022\n\010flo" +
+      "atVal\030\005 \001(\002H\000\022\023\n\tstringVal\030\006 \001(\tH\000\022\021\n\007bo" +
+      "olVal\030\007 \001(\010H\000B\007\n\005value\",\n\007KpiList\022!\n\010kpi" +
+      "_list\030\001 \003(\0132\017.monitoring.Kpi\"K\n\021KpiDescr" +
+      "iptorList\0226\n\023kpi_descriptor_list\030\001 \003(\0132\031" +
+      ".monitoring.KpiDescriptor\"\362\001\n\016SubsDescri" +
+      "ptor\022+\n\007subs_id\030\001 \001(\0132\032.monitoring.Subsc" +
+      "riptionID\022!\n\006kpi_id\030\002 \001(\0132\021.monitoring.K" +
+      "piId\022\033\n\023sampling_duration_s\030\003 \001(\002\022\033\n\023sam" +
+      "pling_interval_s\030\004 \001(\002\022+\n\017start_timestam" +
+      "p\030\005 \001(\0132\022.context.Timestamp\022)\n\rend_times" +
+      "tamp\030\006 \001(\0132\022.context.Timestamp\"0\n\016Subscr" +
+      "iptionID\022\036\n\007subs_id\030\001 \001(\0132\r.context.Uuid" +
+      "\"b\n\014SubsResponse\022+\n\007subs_id\030\001 \001(\0132\032.moni" +
+      "toring.SubscriptionID\022%\n\010kpi_list\030\002 \003(\0132" +
+      "\023.monitoring.KpiList\";\n\nSubsIDList\022-\n\tsu" +
+      "bs_list\030\001 \003(\0132\032.monitoring.SubscriptionI" +
+      "D\"\337\001\n\017AlarmDescriptor\022%\n\010alarm_id\030\001 \001(\0132" +
+      "\023.monitoring.AlarmID\022\031\n\021alarm_descriptio" +
+      "n\030\002 \001(\t\022\014\n\004name\030\003 \001(\t\022!\n\006kpi_id\030\004 \003(\0132\021." +
+      "monitoring.KpiId\0222\n\017kpi_value_range\030\005 \003(" +
+      "\0132\031.monitoring.KpiValueRange\022%\n\ttimestam" +
+      "p\030\006 \001(\0132\022.context.Timestamp\"*\n\007AlarmID\022\037" +
+      "\n\010alarm_id\030\001 \001(\0132\r.context.Uuid\"|\n\021Alarm" +
+      "Subscription\022$\n\007alarmID\030\001 \001(\0132\023.monitori" +
+      "ng.AlarmID\022\036\n\026subscription_timeout_s\030\002 \001" +
+      "(\002\022!\n\031subscription_frequency_ms\030\003 \001(\002\"\224\001" +
+      "\n\rAlarmResponse\022%\n\010alarm_id\030\001 \001(\0132\023.moni" +
+      "toring.AlarmID\022\014\n\004text\030\002 \001(\t\022\'\n\tkpi_valu" +
+      "e\030\003 \001(\0132\024.monitoring.KpiValue\022%\n\ttimesta" +
+      "mp\030\004 \001(\0132\022.context.Timestamp\"6\n\013AlarmIDL" +
+      "ist\022\'\n\nalarm_list\030\001 \003(\0132\023.monitoring.Ala" +
+      "rmID2\233\t\n\021MonitoringService\0228\n\006SetKpi\022\031.m" +
+      "onitoring.KpiDescriptor\032\021.monitoring.Kpi" +
+      "Id\"\000\0220\n\tDeleteKpi\022\021.monitoring.KpiId\032\016.c" +
+      "ontext.Empty\"\000\022B\n\020GetKpiDescriptor\022\021.mon" +
+      "itoring.KpiId\032\031.monitoring.KpiDescriptor" +
+      "\"\000\022G\n\024GetKpiDescriptorList\022\016.context.Emp" +
+      "ty\032\035.monitoring.KpiDescriptorList\"\000\022/\n\nI" +
+      "ncludeKpi\022\017.monitoring.Kpi\032\016.context.Emp" +
+      "ty\"\000\022=\n\nMonitorKpi\022\035.monitoring.MonitorK" +
+      "piRequest\032\016.context.Empty\"\000\022;\n\014QueryKpiD" +
+      "ata\022\024.monitoring.KpiQuery\032\023.monitoring.K" +
+      "piList\"\000\022I\n\022SetKpiSubscription\022\032.monitor" +
+      "ing.SubsDescriptor\032\023.monitoring.KpiList\"" +
+      "\0000\001\022M\n\021GetSubsDescriptor\022\032.monitoring.Su" +
+      "bscriptionID\032\032.monitoring.SubsDescriptor" +
+      "\"\000\022<\n\020GetSubscriptions\022\016.context.Empty\032\026" +
+      ".monitoring.SubsIDList\"\000\022B\n\022DeleteSubscr" +
+      "iption\022\032.monitoring.SubscriptionID\032\016.con" +
+      "text.Empty\"\000\022A\n\013SetKpiAlarm\022\033.monitoring" +
+      ".AlarmDescriptor\032\023.monitoring.AlarmID\"\000\022" +
+      "6\n\tGetAlarms\022\016.context.Empty\032\027.monitorin" +
+      "g.AlarmIDList\"\000\022H\n\022GetAlarmDescriptor\022\023." +
+      "monitoring.AlarmID\032\033.monitoring.AlarmDes" +
+      "criptor\"\000\022V\n\026GetAlarmResponseStream\022\035.mo" +
+      "nitoring.AlarmSubscription\032\031.monitoring." +
+      "AlarmResponse\"\0000\001\0224\n\013DeleteAlarm\022\023.monit" +
+      "oring.AlarmID\032\016.context.Empty\"\000\0226\n\014GetSt" +
+      "reamKpi\022\021.monitoring.KpiId\032\017.monitoring." +
+      "Kpi\"\0000\001\0229\n\rGetInstantKpi\022\021.monitoring.Kp" +
+      "iId\032\023.monitoring.KpiList\"\000b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -20035,111 +19395,105 @@ public final class Monitoring {
     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", "SliceId", });
-    internal_static_monitoring_BundleKpiDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(1);
-    internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_monitoring_BundleKpiDescriptor_descriptor,
-        new java.lang.String[] { "KpiDescription", "KpiIdList", "KpiSampleType", "DeviceId", "EndpointId", "ServiceId", "SliceId", });
-    internal_static_monitoring_EditedKpiDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(2);
-    internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_monitoring_EditedKpiDescriptor_descriptor,
         new java.lang.String[] { "KpiId", "KpiDescription", "KpiIdList", "KpiSampleType", "DeviceId", "EndpointId", "ServiceId", "SliceId", });
     internal_static_monitoring_MonitorKpiRequest_descriptor =
-      getDescriptor().getMessageTypes().get(3);
+      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", "MonitoringWindowS", "SamplingRateS", });
     internal_static_monitoring_KpiQuery_descriptor =
-      getDescriptor().getMessageTypes().get(4);
+      getDescriptor().getMessageTypes().get(2);
     internal_static_monitoring_KpiQuery_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiQuery_descriptor,
-        new java.lang.String[] { "KpiId", "MonitoringWindowS", "SamplingRateS", "LastNSamples", "StartDate", "EndDate", });
+        new java.lang.String[] { "KpiId", "MonitoringWindowS", "SamplingRateS", "LastNSamples", "StartTimestamp", "EndTimestamp", });
     internal_static_monitoring_KpiId_descriptor =
-      getDescriptor().getMessageTypes().get(5);
+      getDescriptor().getMessageTypes().get(3);
     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(6);
+      getDescriptor().getMessageTypes().get(4);
     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_KpiValueRange_descriptor =
-      getDescriptor().getMessageTypes().get(7);
+      getDescriptor().getMessageTypes().get(5);
     internal_static_monitoring_KpiValueRange_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiValueRange_descriptor,
-        new java.lang.String[] { "KpiMinValue", "KpiMaxValue", });
+        new java.lang.String[] { "KpiMinValue", "KpiMaxValue", "InRange", "IncludeMinValue", "IncludeMaxValue", });
     internal_static_monitoring_KpiValue_descriptor =
-      getDescriptor().getMessageTypes().get(8);
+      getDescriptor().getMessageTypes().get(6);
     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", });
+        new java.lang.String[] { "Int32Val", "Uint32Val", "Int64Val", "Uint64Val", "FloatVal", "StringVal", "BoolVal", "Value", });
     internal_static_monitoring_KpiList_descriptor =
-      getDescriptor().getMessageTypes().get(9);
+      getDescriptor().getMessageTypes().get(7);
     internal_static_monitoring_KpiList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiList_descriptor,
         new java.lang.String[] { "KpiList", });
     internal_static_monitoring_KpiDescriptorList_descriptor =
-      getDescriptor().getMessageTypes().get(10);
+      getDescriptor().getMessageTypes().get(8);
     internal_static_monitoring_KpiDescriptorList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiDescriptorList_descriptor,
         new java.lang.String[] { "KpiDescriptorList", });
     internal_static_monitoring_SubsDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(11);
+      getDescriptor().getMessageTypes().get(9);
     internal_static_monitoring_SubsDescriptor_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubsDescriptor_descriptor,
-        new java.lang.String[] { "KpiId", "SamplingDurationS", "SamplingIntervalS", "StartDate", "EndDate", });
+        new java.lang.String[] { "SubsId", "KpiId", "SamplingDurationS", "SamplingIntervalS", "StartTimestamp", "EndTimestamp", });
     internal_static_monitoring_SubscriptionID_descriptor =
-      getDescriptor().getMessageTypes().get(12);
+      getDescriptor().getMessageTypes().get(10);
     internal_static_monitoring_SubscriptionID_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubscriptionID_descriptor,
         new java.lang.String[] { "SubsId", });
     internal_static_monitoring_SubsResponse_descriptor =
-      getDescriptor().getMessageTypes().get(13);
+      getDescriptor().getMessageTypes().get(11);
     internal_static_monitoring_SubsResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubsResponse_descriptor,
         new java.lang.String[] { "SubsId", "KpiList", });
     internal_static_monitoring_SubsIDList_descriptor =
-      getDescriptor().getMessageTypes().get(14);
+      getDescriptor().getMessageTypes().get(12);
     internal_static_monitoring_SubsIDList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubsIDList_descriptor,
         new java.lang.String[] { "SubsList", });
     internal_static_monitoring_AlarmDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(15);
+      getDescriptor().getMessageTypes().get(13);
     internal_static_monitoring_AlarmDescriptor_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmDescriptor_descriptor,
-        new java.lang.String[] { "AlarmDescription", "Name", "KpiId", "KpiValueRange", "Timestamp", });
+        new java.lang.String[] { "AlarmId", "AlarmDescription", "Name", "KpiId", "KpiValueRange", "Timestamp", });
     internal_static_monitoring_AlarmID_descriptor =
-      getDescriptor().getMessageTypes().get(16);
+      getDescriptor().getMessageTypes().get(14);
     internal_static_monitoring_AlarmID_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmID_descriptor,
         new java.lang.String[] { "AlarmId", });
+    internal_static_monitoring_AlarmSubscription_descriptor =
+      getDescriptor().getMessageTypes().get(15);
+    internal_static_monitoring_AlarmSubscription_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_AlarmSubscription_descriptor,
+        new java.lang.String[] { "AlarmID", "SubscriptionTimeoutS", "SubscriptionFrequencyMs", });
     internal_static_monitoring_AlarmResponse_descriptor =
-      getDescriptor().getMessageTypes().get(17);
+      getDescriptor().getMessageTypes().get(16);
     internal_static_monitoring_AlarmResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmResponse_descriptor,
-        new java.lang.String[] { "AlarmId", "Text", "KpiValue", });
+        new java.lang.String[] { "AlarmId", "Text", "KpiValue", "Timestamp", });
     internal_static_monitoring_AlarmIDList_descriptor =
-      getDescriptor().getMessageTypes().get(18);
+      getDescriptor().getMessageTypes().get(17);
     internal_static_monitoring_AlarmIDList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmIDList_descriptor,
diff --git a/src/automation/target/generated-sources/grpc/monitoring/MonitoringService.java b/src/automation/target/generated-sources/grpc/monitoring/MonitoringService.java
index f826e1167d1ed56567fc470ba70cc09003617eda..6372600680d57d0b351e7dd67b88c84f9d8e8cff 100644
--- a/src/automation/target/generated-sources/grpc/monitoring/MonitoringService.java
+++ b/src/automation/target/generated-sources/grpc/monitoring/MonitoringService.java
@@ -8,18 +8,14 @@ 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<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request);
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request);
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request);
     
-    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request);
-    
-    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request);
-    
     io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request);
     
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty 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);
@@ -30,20 +26,24 @@ public interface MonitoringService extends MutinyService {
     
     io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request);
     
-    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request);
-    
-    io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request);
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request);
     
-    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request);
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request);
     
     io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request);
     
     io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request);
+    
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request);
+    
+    
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request);
     
-    io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request);
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request);
     
-    io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request);
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request);
     
     
 
diff --git a/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java b/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
index c7f776e7bd0c56cabc7009e7b7bdb208669fb441..21f7f48acd6b6870584133dc3d665f681e78cf5e 100644
--- a/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
+++ b/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
@@ -16,25 +16,25 @@ public class MonitoringServiceBean extends MutinyMonitoringServiceGrpc.Monitorin
     }
 
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
        try {
-         return delegate.createKpi(request);
+         return delegate.setKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.editKpiDescriptor(request);
+         return delegate.deleteKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.deleteKpi(request);
+         return delegate.getKpiDescriptor(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
@@ -48,115 +48,116 @@ public class MonitoringServiceBean extends MutinyMonitoringServiceGrpc.Monitorin
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
        try {
-         return delegate.createBundleKpi(request);
+         return delegate.includeKpi(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) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
        try {
-         return delegate.getKpiDescriptor(request);
+         return delegate.monitorKpi(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) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
        try {
-         return delegate.includeKpi(request);
+         return delegate.queryKpiData(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) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
        try {
-         return delegate.monitorKpi(request);
+         return delegate.getSubsDescriptor(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
        try {
-         return delegate.queryKpiData(request);
+         return delegate.getSubscriptions(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
        try {
-         return delegate.getSubsDescriptor(request);
+         return delegate.deleteSubscription(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
        try {
-         return delegate.getSubscriptions(request);
+         return delegate.setKpiAlarm(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
        try {
-         return delegate.editKpiSubscription(request);
+         return delegate.getAlarms(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
        try {
-         return delegate.createKpiAlarm(request);
+         return delegate.getAlarmDescriptor(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
        try {
-         return delegate.editKpiAlarm(request);
+         return delegate.deleteAlarm(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.getAlarms(request);
+         return delegate.getInstantKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
+
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
        try {
-         return delegate.getAlarmDescriptor(request);
+         return delegate.setKpiSubscription(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
        try {
-         return delegate.subscribeKpi(request);
+         return delegate.getAlarmResponseStream(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.getAlarmResponseStream(request);
+         return delegate.getStreamKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
diff --git a/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java b/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
index 35c98e8ff2c240e749e602c4d097c3bef81c8203..6b6dc38645931ad94287b4151019c3b42a1c098d 100644
--- a/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
+++ b/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
@@ -21,30 +21,22 @@ public class MonitoringServiceClient implements MonitoringService, MutinyClient<
     }
 
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
-       return stub.createKpi(request);
-    }
-    @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
-       return stub.editKpiDescriptor(request);
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
+       return stub.setKpi(request);
     }
     @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
        return stub.deleteKpi(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
-       return stub.getKpiDescriptorList(request);
-    }
-    @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
-       return stub.createBundleKpi(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<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
+       return stub.getKpiDescriptorList(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
        return stub.includeKpi(request);
     }
@@ -65,16 +57,12 @@ public class MonitoringServiceClient implements MonitoringService, MutinyClient<
        return stub.getSubscriptions(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
-       return stub.editKpiSubscription(request);
-    }
-    @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-       return stub.createKpiAlarm(request);
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
+       return stub.deleteSubscription(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-       return stub.editKpiAlarm(request);
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+       return stub.setKpiAlarm(request);
     }
     @Override
     public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
@@ -84,15 +72,28 @@ public class MonitoringServiceClient implements MonitoringService, MutinyClient<
     public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
        return stub.getAlarmDescriptor(request);
     }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
+       return stub.deleteAlarm(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
+       return stub.getInstantKpi(request);
+    }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
-       return stub.subscribeKpi(request);
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+       return stub.setKpiSubscription(request);
     }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
        return stub.getAlarmResponseStream(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/automation/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java b/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
index d4ae3510a2f622b195854e4c7d197b8e3ff4d5fd..fe92a7814166b65b12db5d50bb4baaf525c59146 100644
--- a/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
@@ -15,96 +15,96 @@ public final class MonitoringServiceGrpc {
 
   // Static method descriptors that strictly reflect the proto.
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor,
-      monitoring.Monitoring.KpiId> getCreateKpiMethod;
+      monitoring.Monitoring.KpiId> getSetKpiMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "CreateKpi",
+      fullMethodName = SERVICE_NAME + '/' + "SetKpi",
       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) {
+      monitoring.Monitoring.KpiId> getSetKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiId> getSetKpiMethod;
+    if ((getSetKpiMethod = MonitoringServiceGrpc.getSetKpiMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getCreateKpiMethod = MonitoringServiceGrpc.getCreateKpiMethod) == null) {
-          MonitoringServiceGrpc.getCreateKpiMethod = getCreateKpiMethod =
+        if ((getSetKpiMethod = MonitoringServiceGrpc.getSetKpiMethod) == null) {
+          MonitoringServiceGrpc.getSetKpiMethod = getSetKpiMethod =
               io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiId>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateKpi"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetKpi"))
               .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"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SetKpi"))
               .build();
         }
       }
     }
-    return getCreateKpiMethod;
+    return getSetKpiMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.EditedKpiDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiDescriptorMethod;
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      context.ContextOuterClass.Empty> getDeleteKpiMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "EditKpiDescriptor",
-      requestType = monitoring.Monitoring.EditedKpiDescriptor.class,
+      fullMethodName = SERVICE_NAME + '/' + "DeleteKpi",
+      requestType = monitoring.Monitoring.KpiId.class,
       responseType = context.ContextOuterClass.Empty.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.EditedKpiDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiDescriptorMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.EditedKpiDescriptor, context.ContextOuterClass.Empty> getEditKpiDescriptorMethod;
-    if ((getEditKpiDescriptorMethod = MonitoringServiceGrpc.getEditKpiDescriptorMethod) == null) {
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      context.ContextOuterClass.Empty> getDeleteKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty> getDeleteKpiMethod;
+    if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getEditKpiDescriptorMethod = MonitoringServiceGrpc.getEditKpiDescriptorMethod) == null) {
-          MonitoringServiceGrpc.getEditKpiDescriptorMethod = getEditKpiDescriptorMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.EditedKpiDescriptor, context.ContextOuterClass.Empty>newBuilder()
+        if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
+          MonitoringServiceGrpc.getDeleteKpiMethod = getDeleteKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "EditKpiDescriptor"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteKpi"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.EditedKpiDescriptor.getDefaultInstance()))
+                  monitoring.Monitoring.KpiId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("EditKpiDescriptor"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteKpi"))
               .build();
         }
       }
     }
-    return getEditKpiDescriptorMethod;
+    return getDeleteKpiMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
-      context.ContextOuterClass.Empty> getDeleteKpiMethod;
+      monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "DeleteKpi",
+      fullMethodName = SERVICE_NAME + '/' + "GetKpiDescriptor",
       requestType = monitoring.Monitoring.KpiId.class,
-      responseType = context.ContextOuterClass.Empty.class,
+      responseType = monitoring.Monitoring.KpiDescriptor.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
   public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
-      context.ContextOuterClass.Empty> getDeleteKpiMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty> getDeleteKpiMethod;
-    if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
+      monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod;
+    if ((getGetKpiDescriptorMethod = MonitoringServiceGrpc.getGetKpiDescriptorMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
-          MonitoringServiceGrpc.getDeleteKpiMethod = getDeleteKpiMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty>newBuilder()
+        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, "DeleteKpi"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetKpiDescriptor"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.KpiId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteKpi"))
+                  monitoring.Monitoring.KpiDescriptor.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetKpiDescriptor"))
               .build();
         }
       }
     }
-    return getDeleteKpiMethod;
+    return getGetKpiDescriptorMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
@@ -138,68 +138,6 @@ public final class MonitoringServiceGrpc {
     return getGetKpiDescriptorListMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.BundleKpiDescriptor,
-      monitoring.Monitoring.KpiId> getCreateBundleKpiMethod;
-
-  @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "CreateBundleKpi",
-      requestType = monitoring.Monitoring.BundleKpiDescriptor.class,
-      responseType = monitoring.Monitoring.KpiId.class,
-      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.BundleKpiDescriptor,
-      monitoring.Monitoring.KpiId> getCreateBundleKpiMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.BundleKpiDescriptor, monitoring.Monitoring.KpiId> getCreateBundleKpiMethod;
-    if ((getCreateBundleKpiMethod = MonitoringServiceGrpc.getCreateBundleKpiMethod) == null) {
-      synchronized (MonitoringServiceGrpc.class) {
-        if ((getCreateBundleKpiMethod = MonitoringServiceGrpc.getCreateBundleKpiMethod) == null) {
-          MonitoringServiceGrpc.getCreateBundleKpiMethod = getCreateBundleKpiMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.BundleKpiDescriptor, monitoring.Monitoring.KpiId>newBuilder()
-              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateBundleKpi"))
-              .setSampledToLocalTracing(true)
-              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.BundleKpiDescriptor.getDefaultInstance()))
-              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.KpiId.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("CreateBundleKpi"))
-              .build();
-        }
-      }
-    }
-    return getCreateBundleKpiMethod;
-  }
-
-  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;
 
@@ -294,34 +232,34 @@ public final class MonitoringServiceGrpc {
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      monitoring.Monitoring.KpiList> getSubscribeKpiMethod;
+      monitoring.Monitoring.KpiList> getSetKpiSubscriptionMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "SubscribeKpi",
+      fullMethodName = SERVICE_NAME + '/' + "SetKpiSubscription",
       requestType = monitoring.Monitoring.SubsDescriptor.class,
       responseType = monitoring.Monitoring.KpiList.class,
       methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
   public static io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      monitoring.Monitoring.KpiList> getSubscribeKpiMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor, monitoring.Monitoring.KpiList> getSubscribeKpiMethod;
-    if ((getSubscribeKpiMethod = MonitoringServiceGrpc.getSubscribeKpiMethod) == null) {
+      monitoring.Monitoring.KpiList> getSetKpiSubscriptionMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor, monitoring.Monitoring.KpiList> getSetKpiSubscriptionMethod;
+    if ((getSetKpiSubscriptionMethod = MonitoringServiceGrpc.getSetKpiSubscriptionMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getSubscribeKpiMethod = MonitoringServiceGrpc.getSubscribeKpiMethod) == null) {
-          MonitoringServiceGrpc.getSubscribeKpiMethod = getSubscribeKpiMethod =
+        if ((getSetKpiSubscriptionMethod = MonitoringServiceGrpc.getSetKpiSubscriptionMethod) == null) {
+          MonitoringServiceGrpc.getSetKpiSubscriptionMethod = getSetKpiSubscriptionMethod =
               io.grpc.MethodDescriptor.<monitoring.Monitoring.SubsDescriptor, monitoring.Monitoring.KpiList>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SubscribeKpi"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetKpiSubscription"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.SubsDescriptor.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.KpiList.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SubscribeKpi"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SetKpiSubscription"))
               .build();
         }
       }
     }
-    return getSubscribeKpiMethod;
+    return getSetKpiSubscriptionMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID,
@@ -386,97 +324,66 @@ public final class MonitoringServiceGrpc {
     return getGetSubscriptionsMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiSubscriptionMethod;
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID,
+      context.ContextOuterClass.Empty> getDeleteSubscriptionMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "EditKpiSubscription",
-      requestType = monitoring.Monitoring.SubsDescriptor.class,
+      fullMethodName = SERVICE_NAME + '/' + "DeleteSubscription",
+      requestType = monitoring.Monitoring.SubscriptionID.class,
       responseType = context.ContextOuterClass.Empty.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiSubscriptionMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor, context.ContextOuterClass.Empty> getEditKpiSubscriptionMethod;
-    if ((getEditKpiSubscriptionMethod = MonitoringServiceGrpc.getEditKpiSubscriptionMethod) == null) {
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID,
+      context.ContextOuterClass.Empty> getDeleteSubscriptionMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID, context.ContextOuterClass.Empty> getDeleteSubscriptionMethod;
+    if ((getDeleteSubscriptionMethod = MonitoringServiceGrpc.getDeleteSubscriptionMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getEditKpiSubscriptionMethod = MonitoringServiceGrpc.getEditKpiSubscriptionMethod) == null) {
-          MonitoringServiceGrpc.getEditKpiSubscriptionMethod = getEditKpiSubscriptionMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.SubsDescriptor, context.ContextOuterClass.Empty>newBuilder()
+        if ((getDeleteSubscriptionMethod = MonitoringServiceGrpc.getDeleteSubscriptionMethod) == null) {
+          MonitoringServiceGrpc.getDeleteSubscriptionMethod = getDeleteSubscriptionMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.SubscriptionID, context.ContextOuterClass.Empty>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "EditKpiSubscription"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteSubscription"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.SubsDescriptor.getDefaultInstance()))
+                  monitoring.Monitoring.SubscriptionID.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("EditKpiSubscription"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteSubscription"))
               .build();
         }
       }
     }
-    return getEditKpiSubscriptionMethod;
+    return getDeleteSubscriptionMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      monitoring.Monitoring.AlarmID> getCreateKpiAlarmMethod;
+      monitoring.Monitoring.AlarmID> getSetKpiAlarmMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "CreateKpiAlarm",
+      fullMethodName = SERVICE_NAME + '/' + "SetKpiAlarm",
       requestType = monitoring.Monitoring.AlarmDescriptor.class,
       responseType = monitoring.Monitoring.AlarmID.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
   public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      monitoring.Monitoring.AlarmID> getCreateKpiAlarmMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor, monitoring.Monitoring.AlarmID> getCreateKpiAlarmMethod;
-    if ((getCreateKpiAlarmMethod = MonitoringServiceGrpc.getCreateKpiAlarmMethod) == null) {
+      monitoring.Monitoring.AlarmID> getSetKpiAlarmMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor, monitoring.Monitoring.AlarmID> getSetKpiAlarmMethod;
+    if ((getSetKpiAlarmMethod = MonitoringServiceGrpc.getSetKpiAlarmMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getCreateKpiAlarmMethod = MonitoringServiceGrpc.getCreateKpiAlarmMethod) == null) {
-          MonitoringServiceGrpc.getCreateKpiAlarmMethod = getCreateKpiAlarmMethod =
+        if ((getSetKpiAlarmMethod = MonitoringServiceGrpc.getSetKpiAlarmMethod) == null) {
+          MonitoringServiceGrpc.getSetKpiAlarmMethod = getSetKpiAlarmMethod =
               io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmDescriptor, monitoring.Monitoring.AlarmID>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateKpiAlarm"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetKpiAlarm"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.AlarmID.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("CreateKpiAlarm"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SetKpiAlarm"))
               .build();
         }
       }
     }
-    return getCreateKpiAlarmMethod;
-  }
-
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiAlarmMethod;
-
-  @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "EditKpiAlarm",
-      requestType = monitoring.Monitoring.AlarmDescriptor.class,
-      responseType = context.ContextOuterClass.Empty.class,
-      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiAlarmMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor, context.ContextOuterClass.Empty> getEditKpiAlarmMethod;
-    if ((getEditKpiAlarmMethod = MonitoringServiceGrpc.getEditKpiAlarmMethod) == null) {
-      synchronized (MonitoringServiceGrpc.class) {
-        if ((getEditKpiAlarmMethod = MonitoringServiceGrpc.getEditKpiAlarmMethod) == null) {
-          MonitoringServiceGrpc.getEditKpiAlarmMethod = getEditKpiAlarmMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmDescriptor, context.ContextOuterClass.Empty>newBuilder()
-              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "EditKpiAlarm"))
-              .setSampledToLocalTracing(true)
-              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()))
-              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("EditKpiAlarm"))
-              .build();
-        }
-      }
-    }
-    return getEditKpiAlarmMethod;
+    return getSetKpiAlarmMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
@@ -541,27 +448,27 @@ public final class MonitoringServiceGrpc {
     return getGetAlarmDescriptorMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmSubscription,
       monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
       fullMethodName = SERVICE_NAME + '/' + "GetAlarmResponseStream",
-      requestType = monitoring.Monitoring.AlarmID.class,
+      requestType = monitoring.Monitoring.AlarmSubscription.class,
       responseType = monitoring.Monitoring.AlarmResponse.class,
       methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmSubscription,
       monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod;
+    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmSubscription, monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod;
     if ((getGetAlarmResponseStreamMethod = MonitoringServiceGrpc.getGetAlarmResponseStreamMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
         if ((getGetAlarmResponseStreamMethod = MonitoringServiceGrpc.getGetAlarmResponseStreamMethod) == null) {
           MonitoringServiceGrpc.getGetAlarmResponseStreamMethod = getGetAlarmResponseStreamMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmResponse>newBuilder()
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmSubscription, monitoring.Monitoring.AlarmResponse>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
               .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetAlarmResponseStream"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.AlarmID.getDefaultInstance()))
+                  monitoring.Monitoring.AlarmSubscription.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.AlarmResponse.getDefaultInstance()))
               .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetAlarmResponseStream"))
@@ -572,6 +479,99 @@ public final class MonitoringServiceGrpc {
     return getGetAlarmResponseStreamMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+      context.ContextOuterClass.Empty> getDeleteAlarmMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "DeleteAlarm",
+      requestType = monitoring.Monitoring.AlarmID.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+      context.ContextOuterClass.Empty> getDeleteAlarmMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID, context.ContextOuterClass.Empty> getDeleteAlarmMethod;
+    if ((getDeleteAlarmMethod = MonitoringServiceGrpc.getDeleteAlarmMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getDeleteAlarmMethod = MonitoringServiceGrpc.getDeleteAlarmMethod) == null) {
+          MonitoringServiceGrpc.getDeleteAlarmMethod = getDeleteAlarmMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmID, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteAlarm"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.AlarmID.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteAlarm"))
+              .build();
+        }
+      }
+    }
+    return getDeleteAlarmMethod;
+  }
+
+  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.KpiList> getGetInstantKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetInstantKpi",
+      requestType = monitoring.Monitoring.KpiId.class,
+      responseType = monitoring.Monitoring.KpiList.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.KpiList> getGetInstantKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiList> 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.KpiList>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.KpiList.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetInstantKpi"))
+              .build();
+        }
+      }
+    }
+    return getGetInstantKpiMethod;
+  }
+
   /**
    * Creates a new async stub that supports all call types for the service
    */
@@ -622,23 +622,23 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void createKpi(monitoring.Monitoring.KpiDescriptor request,
+    public void setKpi(monitoring.Monitoring.KpiDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateKpiMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetKpiMethod(), responseObserver);
     }
 
     /**
      */
-    public void editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request,
+    public void deleteKpi(monitoring.Monitoring.KpiId request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEditKpiDescriptorMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteKpiMethod(), responseObserver);
     }
 
     /**
      */
-    public void deleteKpi(monitoring.Monitoring.KpiId request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteKpiMethod(), responseObserver);
+    public void getKpiDescriptor(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetKpiDescriptorMethod(), responseObserver);
     }
 
     /**
@@ -648,20 +648,6 @@ public final class MonitoringServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetKpiDescriptorListMethod(), responseObserver);
     }
 
-    /**
-     */
-    public void createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request,
-        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateBundleKpiMethod(), 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,
@@ -685,9 +671,9 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void subscribeKpi(monitoring.Monitoring.SubsDescriptor request,
+    public void setKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSubscribeKpiMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetKpiSubscriptionMethod(), responseObserver);
     }
 
     /**
@@ -706,23 +692,16 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void editKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
+    public void deleteSubscription(monitoring.Monitoring.SubscriptionID request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEditKpiSubscriptionMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteSubscriptionMethod(), responseObserver);
     }
 
     /**
      */
-    public void createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
+    public void setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateKpiAlarmMethod(), responseObserver);
-    }
-
-    /**
-     */
-    public void editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEditKpiAlarmMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetKpiAlarmMethod(), responseObserver);
     }
 
     /**
@@ -741,34 +720,55 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void getAlarmResponseStream(monitoring.Monitoring.AlarmID request,
+    public void getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse> responseObserver) {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetAlarmResponseStreamMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void deleteAlarm(monitoring.Monitoring.AlarmID request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteAlarmMethod(), 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.KpiList> 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(),
+            getSetKpiMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 monitoring.Monitoring.KpiDescriptor,
                 monitoring.Monitoring.KpiId>(
-                  this, METHODID_CREATE_KPI)))
+                  this, METHODID_SET_KPI)))
           .addMethod(
-            getEditKpiDescriptorMethod(),
+            getDeleteKpiMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                monitoring.Monitoring.EditedKpiDescriptor,
+                monitoring.Monitoring.KpiId,
                 context.ContextOuterClass.Empty>(
-                  this, METHODID_EDIT_KPI_DESCRIPTOR)))
+                  this, METHODID_DELETE_KPI)))
           .addMethod(
-            getDeleteKpiMethod(),
+            getGetKpiDescriptorMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 monitoring.Monitoring.KpiId,
-                context.ContextOuterClass.Empty>(
-                  this, METHODID_DELETE_KPI)))
+                monitoring.Monitoring.KpiDescriptor>(
+                  this, METHODID_GET_KPI_DESCRIPTOR)))
           .addMethod(
             getGetKpiDescriptorListMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -776,20 +776,6 @@ public final class MonitoringServiceGrpc {
                 context.ContextOuterClass.Empty,
                 monitoring.Monitoring.KpiDescriptorList>(
                   this, METHODID_GET_KPI_DESCRIPTOR_LIST)))
-          .addMethod(
-            getCreateBundleKpiMethod(),
-            io.grpc.stub.ServerCalls.asyncUnaryCall(
-              new MethodHandlers<
-                monitoring.Monitoring.BundleKpiDescriptor,
-                monitoring.Monitoring.KpiId>(
-                  this, METHODID_CREATE_BUNDLE_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(
@@ -812,12 +798,12 @@ public final class MonitoringServiceGrpc {
                 monitoring.Monitoring.KpiList>(
                   this, METHODID_QUERY_KPI_DATA)))
           .addMethod(
-            getSubscribeKpiMethod(),
+            getSetKpiSubscriptionMethod(),
             io.grpc.stub.ServerCalls.asyncServerStreamingCall(
               new MethodHandlers<
                 monitoring.Monitoring.SubsDescriptor,
                 monitoring.Monitoring.KpiList>(
-                  this, METHODID_SUBSCRIBE_KPI)))
+                  this, METHODID_SET_KPI_SUBSCRIPTION)))
           .addMethod(
             getGetSubsDescriptorMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -833,26 +819,19 @@ public final class MonitoringServiceGrpc {
                 monitoring.Monitoring.SubsIDList>(
                   this, METHODID_GET_SUBSCRIPTIONS)))
           .addMethod(
-            getEditKpiSubscriptionMethod(),
+            getDeleteSubscriptionMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                monitoring.Monitoring.SubsDescriptor,
+                monitoring.Monitoring.SubscriptionID,
                 context.ContextOuterClass.Empty>(
-                  this, METHODID_EDIT_KPI_SUBSCRIPTION)))
+                  this, METHODID_DELETE_SUBSCRIPTION)))
           .addMethod(
-            getCreateKpiAlarmMethod(),
+            getSetKpiAlarmMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 monitoring.Monitoring.AlarmDescriptor,
                 monitoring.Monitoring.AlarmID>(
-                  this, METHODID_CREATE_KPI_ALARM)))
-          .addMethod(
-            getEditKpiAlarmMethod(),
-            io.grpc.stub.ServerCalls.asyncUnaryCall(
-              new MethodHandlers<
-                monitoring.Monitoring.AlarmDescriptor,
-                context.ContextOuterClass.Empty>(
-                  this, METHODID_EDIT_KPI_ALARM)))
+                  this, METHODID_SET_KPI_ALARM)))
           .addMethod(
             getGetAlarmsMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -871,9 +850,30 @@ public final class MonitoringServiceGrpc {
             getGetAlarmResponseStreamMethod(),
             io.grpc.stub.ServerCalls.asyncServerStreamingCall(
               new MethodHandlers<
-                monitoring.Monitoring.AlarmID,
+                monitoring.Monitoring.AlarmSubscription,
                 monitoring.Monitoring.AlarmResponse>(
                   this, METHODID_GET_ALARM_RESPONSE_STREAM)))
+          .addMethod(
+            getDeleteAlarmMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.AlarmID,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_DELETE_ALARM)))
+          .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.KpiList>(
+                  this, METHODID_GET_INSTANT_KPI)))
           .build();
     }
   }
@@ -894,26 +894,26 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void createKpi(monitoring.Monitoring.KpiDescriptor request,
+    public void setKpi(monitoring.Monitoring.KpiDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getCreateKpiMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getSetKpiMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request,
+    public void deleteKpi(monitoring.Monitoring.KpiId request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getEditKpiDescriptorMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void deleteKpi(monitoring.Monitoring.KpiId request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+    public void getKpiDescriptor(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getGetKpiDescriptorMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
@@ -924,22 +924,6 @@ public final class MonitoringServiceGrpc {
           getChannel().newCall(getGetKpiDescriptorListMethod(), getCallOptions()), request, responseObserver);
     }
 
-    /**
-     */
-    public void createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request,
-        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
-      io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getCreateBundleKpiMethod(), 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,
@@ -966,10 +950,10 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void subscribeKpi(monitoring.Monitoring.SubsDescriptor request,
+    public void setKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList> responseObserver) {
       io.grpc.stub.ClientCalls.asyncServerStreamingCall(
-          getChannel().newCall(getSubscribeKpiMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getSetKpiSubscriptionMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
@@ -990,26 +974,18 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void editKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
+    public void deleteSubscription(monitoring.Monitoring.SubscriptionID request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getEditKpiSubscriptionMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getDeleteSubscriptionMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
+    public void setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getCreateKpiAlarmMethod(), getCallOptions()), request, responseObserver);
-    }
-
-    /**
-     */
-    public void editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getEditKpiAlarmMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getSetKpiAlarmMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
@@ -1030,11 +1006,35 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void getAlarmResponseStream(monitoring.Monitoring.AlarmID request,
+    public void getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse> responseObserver) {
       io.grpc.stub.ClientCalls.asyncServerStreamingCall(
           getChannel().newCall(getGetAlarmResponseStreamMethod(), getCallOptions()), request, responseObserver);
     }
+
+    /**
+     */
+    public void deleteAlarm(monitoring.Monitoring.AlarmID request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getDeleteAlarmMethod(), 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.KpiList> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getGetInstantKpiMethod(), getCallOptions()), request, responseObserver);
+    }
   }
 
   /**
@@ -1053,16 +1053,9 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public monitoring.Monitoring.KpiId createKpi(monitoring.Monitoring.KpiDescriptor request) {
+    public monitoring.Monitoring.KpiId setKpi(monitoring.Monitoring.KpiDescriptor request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getCreateKpiMethod(), getCallOptions(), request);
-    }
-
-    /**
-     */
-    public context.ContextOuterClass.Empty editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
-      return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getEditKpiDescriptorMethod(), getCallOptions(), request);
+          getChannel(), getSetKpiMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1074,23 +1067,16 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public monitoring.Monitoring.KpiDescriptorList getKpiDescriptorList(context.ContextOuterClass.Empty request) {
-      return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getGetKpiDescriptorListMethod(), getCallOptions(), request);
-    }
-
-    /**
-     */
-    public monitoring.Monitoring.KpiId createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
+    public monitoring.Monitoring.KpiDescriptor getKpiDescriptor(monitoring.Monitoring.KpiId request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getCreateBundleKpiMethod(), getCallOptions(), request);
+          getChannel(), getGetKpiDescriptorMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public monitoring.Monitoring.KpiDescriptor getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+    public monitoring.Monitoring.KpiDescriptorList getKpiDescriptorList(context.ContextOuterClass.Empty request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getGetKpiDescriptorMethod(), getCallOptions(), request);
+          getChannel(), getGetKpiDescriptorListMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1116,10 +1102,10 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public java.util.Iterator<monitoring.Monitoring.KpiList> subscribeKpi(
+    public java.util.Iterator<monitoring.Monitoring.KpiList> setKpiSubscription(
         monitoring.Monitoring.SubsDescriptor request) {
       return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
-          getChannel(), getSubscribeKpiMethod(), getCallOptions(), request);
+          getChannel(), getSetKpiSubscriptionMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1138,23 +1124,16 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public context.ContextOuterClass.Empty editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+    public context.ContextOuterClass.Empty deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getEditKpiSubscriptionMethod(), getCallOptions(), request);
+          getChannel(), getDeleteSubscriptionMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public monitoring.Monitoring.AlarmID createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+    public monitoring.Monitoring.AlarmID setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getCreateKpiAlarmMethod(), getCallOptions(), request);
-    }
-
-    /**
-     */
-    public context.ContextOuterClass.Empty editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-      return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getEditKpiAlarmMethod(), getCallOptions(), request);
+          getChannel(), getSetKpiAlarmMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1174,10 +1153,32 @@ public final class MonitoringServiceGrpc {
     /**
      */
     public java.util.Iterator<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(
-        monitoring.Monitoring.AlarmID request) {
+        monitoring.Monitoring.AlarmSubscription request) {
       return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
           getChannel(), getGetAlarmResponseStreamMethod(), getCallOptions(), request);
     }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty deleteAlarm(monitoring.Monitoring.AlarmID request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getDeleteAlarmMethod(), 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.KpiList getInstantKpi(monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getGetInstantKpiMethod(), getCallOptions(), request);
+    }
   }
 
   /**
@@ -1196,26 +1197,26 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> createKpi(
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> setKpi(
         monitoring.Monitoring.KpiDescriptor request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getCreateKpiMethod(), getCallOptions()), request);
+          getChannel().newCall(getSetKpiMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> editKpiDescriptor(
-        monitoring.Monitoring.EditedKpiDescriptor request) {
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteKpi(
+        monitoring.Monitoring.KpiId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getEditKpiDescriptorMethod(), getCallOptions()), request);
+          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteKpi(
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(
         monitoring.Monitoring.KpiId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request);
+          getChannel().newCall(getGetKpiDescriptorMethod(), getCallOptions()), request);
     }
 
     /**
@@ -1226,22 +1227,6 @@ public final class MonitoringServiceGrpc {
           getChannel().newCall(getGetKpiDescriptorListMethod(), getCallOptions()), request);
     }
 
-    /**
-     */
-    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> createBundleKpi(
-        monitoring.Monitoring.BundleKpiDescriptor request) {
-      return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getCreateBundleKpiMethod(), 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(
@@ -1284,26 +1269,18 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> editKpiSubscription(
-        monitoring.Monitoring.SubsDescriptor request) {
-      return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getEditKpiSubscriptionMethod(), getCallOptions()), request);
-    }
-
-    /**
-     */
-    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.AlarmID> createKpiAlarm(
-        monitoring.Monitoring.AlarmDescriptor request) {
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteSubscription(
+        monitoring.Monitoring.SubscriptionID request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getCreateKpiAlarmMethod(), getCallOptions()), request);
+          getChannel().newCall(getDeleteSubscriptionMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> editKpiAlarm(
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.AlarmID> setKpiAlarm(
         monitoring.Monitoring.AlarmDescriptor request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getEditKpiAlarmMethod(), getCallOptions()), request);
+          getChannel().newCall(getSetKpiAlarmMethod(), getCallOptions()), request);
     }
 
     /**
@@ -1321,26 +1298,42 @@ public final class MonitoringServiceGrpc {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
           getChannel().newCall(getGetAlarmDescriptorMethod(), getCallOptions()), request);
     }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteAlarm(
+        monitoring.Monitoring.AlarmID request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getDeleteAlarmMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiList> 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_EDIT_KPI_DESCRIPTOR = 1;
-  private static final int METHODID_DELETE_KPI = 2;
+  private static final int METHODID_SET_KPI = 0;
+  private static final int METHODID_DELETE_KPI = 1;
+  private static final int METHODID_GET_KPI_DESCRIPTOR = 2;
   private static final int METHODID_GET_KPI_DESCRIPTOR_LIST = 3;
-  private static final int METHODID_CREATE_BUNDLE_KPI = 4;
-  private static final int METHODID_GET_KPI_DESCRIPTOR = 5;
-  private static final int METHODID_INCLUDE_KPI = 6;
-  private static final int METHODID_MONITOR_KPI = 7;
-  private static final int METHODID_QUERY_KPI_DATA = 8;
-  private static final int METHODID_SUBSCRIBE_KPI = 9;
-  private static final int METHODID_GET_SUBS_DESCRIPTOR = 10;
-  private static final int METHODID_GET_SUBSCRIPTIONS = 11;
-  private static final int METHODID_EDIT_KPI_SUBSCRIPTION = 12;
-  private static final int METHODID_CREATE_KPI_ALARM = 13;
-  private static final int METHODID_EDIT_KPI_ALARM = 14;
-  private static final int METHODID_GET_ALARMS = 15;
-  private static final int METHODID_GET_ALARM_DESCRIPTOR = 16;
-  private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 17;
+  private static final int METHODID_INCLUDE_KPI = 4;
+  private static final int METHODID_MONITOR_KPI = 5;
+  private static final int METHODID_QUERY_KPI_DATA = 6;
+  private static final int METHODID_SET_KPI_SUBSCRIPTION = 7;
+  private static final int METHODID_GET_SUBS_DESCRIPTOR = 8;
+  private static final int METHODID_GET_SUBSCRIPTIONS = 9;
+  private static final int METHODID_DELETE_SUBSCRIPTION = 10;
+  private static final int METHODID_SET_KPI_ALARM = 11;
+  private static final int METHODID_GET_ALARMS = 12;
+  private static final int METHODID_GET_ALARM_DESCRIPTOR = 13;
+  private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 14;
+  private static final int METHODID_DELETE_ALARM = 15;
+  private static final int METHODID_GET_STREAM_KPI = 16;
+  private static final int METHODID_GET_INSTANT_KPI = 17;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -1359,30 +1352,22 @@ public final class MonitoringServiceGrpc {
     @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,
+        case METHODID_SET_KPI:
+          serviceImpl.setKpi((monitoring.Monitoring.KpiDescriptor) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId>) responseObserver);
           break;
-        case METHODID_EDIT_KPI_DESCRIPTOR:
-          serviceImpl.editKpiDescriptor((monitoring.Monitoring.EditedKpiDescriptor) request,
-              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
-          break;
         case METHODID_DELETE_KPI:
           serviceImpl.deleteKpi((monitoring.Monitoring.KpiId) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
           break;
-        case METHODID_GET_KPI_DESCRIPTOR_LIST:
-          serviceImpl.getKpiDescriptorList((context.ContextOuterClass.Empty) request,
-              (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver);
-          break;
-        case METHODID_CREATE_BUNDLE_KPI:
-          serviceImpl.createBundleKpi((monitoring.Monitoring.BundleKpiDescriptor) 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_GET_KPI_DESCRIPTOR_LIST:
+          serviceImpl.getKpiDescriptorList((context.ContextOuterClass.Empty) request,
+              (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver);
+          break;
         case METHODID_INCLUDE_KPI:
           serviceImpl.includeKpi((monitoring.Monitoring.Kpi) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
@@ -1395,8 +1380,8 @@ public final class MonitoringServiceGrpc {
           serviceImpl.queryKpiData((monitoring.Monitoring.KpiQuery) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList>) responseObserver);
           break;
-        case METHODID_SUBSCRIBE_KPI:
-          serviceImpl.subscribeKpi((monitoring.Monitoring.SubsDescriptor) request,
+        case METHODID_SET_KPI_SUBSCRIPTION:
+          serviceImpl.setKpiSubscription((monitoring.Monitoring.SubsDescriptor) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList>) responseObserver);
           break;
         case METHODID_GET_SUBS_DESCRIPTOR:
@@ -1407,18 +1392,14 @@ public final class MonitoringServiceGrpc {
           serviceImpl.getSubscriptions((context.ContextOuterClass.Empty) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.SubsIDList>) responseObserver);
           break;
-        case METHODID_EDIT_KPI_SUBSCRIPTION:
-          serviceImpl.editKpiSubscription((monitoring.Monitoring.SubsDescriptor) request,
+        case METHODID_DELETE_SUBSCRIPTION:
+          serviceImpl.deleteSubscription((monitoring.Monitoring.SubscriptionID) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
           break;
-        case METHODID_CREATE_KPI_ALARM:
-          serviceImpl.createKpiAlarm((monitoring.Monitoring.AlarmDescriptor) request,
+        case METHODID_SET_KPI_ALARM:
+          serviceImpl.setKpiAlarm((monitoring.Monitoring.AlarmDescriptor) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID>) responseObserver);
           break;
-        case METHODID_EDIT_KPI_ALARM:
-          serviceImpl.editKpiAlarm((monitoring.Monitoring.AlarmDescriptor) request,
-              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
-          break;
         case METHODID_GET_ALARMS:
           serviceImpl.getAlarms((context.ContextOuterClass.Empty) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmIDList>) responseObserver);
@@ -1428,9 +1409,21 @@ public final class MonitoringServiceGrpc {
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmDescriptor>) responseObserver);
           break;
         case METHODID_GET_ALARM_RESPONSE_STREAM:
-          serviceImpl.getAlarmResponseStream((monitoring.Monitoring.AlarmID) request,
+          serviceImpl.getAlarmResponseStream((monitoring.Monitoring.AlarmSubscription) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse>) responseObserver);
           break;
+        case METHODID_DELETE_ALARM:
+          serviceImpl.deleteAlarm((monitoring.Monitoring.AlarmID) 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.KpiList>) responseObserver);
+          break;
         default:
           throw new AssertionError();
       }
@@ -1492,24 +1485,24 @@ public final class MonitoringServiceGrpc {
         if (result == null) {
           serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
               .setSchemaDescriptor(new MonitoringServiceFileDescriptorSupplier())
-              .addMethod(getCreateKpiMethod())
-              .addMethod(getEditKpiDescriptorMethod())
+              .addMethod(getSetKpiMethod())
               .addMethod(getDeleteKpiMethod())
-              .addMethod(getGetKpiDescriptorListMethod())
-              .addMethod(getCreateBundleKpiMethod())
               .addMethod(getGetKpiDescriptorMethod())
+              .addMethod(getGetKpiDescriptorListMethod())
               .addMethod(getIncludeKpiMethod())
               .addMethod(getMonitorKpiMethod())
               .addMethod(getQueryKpiDataMethod())
-              .addMethod(getSubscribeKpiMethod())
+              .addMethod(getSetKpiSubscriptionMethod())
               .addMethod(getGetSubsDescriptorMethod())
               .addMethod(getGetSubscriptionsMethod())
-              .addMethod(getEditKpiSubscriptionMethod())
-              .addMethod(getCreateKpiAlarmMethod())
-              .addMethod(getEditKpiAlarmMethod())
+              .addMethod(getDeleteSubscriptionMethod())
+              .addMethod(getSetKpiAlarmMethod())
               .addMethod(getGetAlarmsMethod())
               .addMethod(getGetAlarmDescriptorMethod())
               .addMethod(getGetAlarmResponseStreamMethod())
+              .addMethod(getDeleteAlarmMethod())
+              .addMethod(getGetStreamKpiMethod())
+              .addMethod(getGetInstantKpiMethod())
               .build();
         }
       }
diff --git a/src/automation/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java b/src/automation/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
index 46f442b743ee176a83a416fe13711beda6baf937..d663b38c923a2b5401642db4e697e16be4720f05 100644
--- a/src/automation/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
@@ -36,13 +36,8 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        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<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::editKpiDescriptor);
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::setKpi);
         }
 
         
@@ -51,18 +46,13 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptorList);
-        }
-
-        
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::createBundleKpi);
+        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<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptor);
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptorList);
         }
 
         
@@ -91,18 +81,13 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::editKpiSubscription);
-        }
-
-        
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::createKpiAlarm);
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::deleteSubscription);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::editKpiAlarm);
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::setKpiAlarm);
         }
 
         
@@ -116,15 +101,30 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::subscribeKpi);
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::deleteAlarm);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getInstantKpi);
+        }
+
+        
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::setKpiSubscription);
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getAlarmResponseStream);
         }
 
+        
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getStreamKpi);
+        }
+
     }
 
     
@@ -143,17 +143,17 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
 
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
@@ -163,98 +163,98 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
+        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<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+        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<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+        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(),
+                            monitoring.MonitoringServiceGrpc.getSetKpiMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.KpiDescriptor,
                                             monitoring.Monitoring.KpiId>(
-                                            this, METHODID_CREATE_KPI, compression)))
+                                            this, METHODID_SET_KPI, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getEditKpiDescriptorMethod(),
+                            monitoring.MonitoringServiceGrpc.getDeleteKpiMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            monitoring.Monitoring.EditedKpiDescriptor,
+                                            monitoring.Monitoring.KpiId,
                                             context.ContextOuterClass.Empty>(
-                                            this, METHODID_EDIT_KPI_DESCRIPTOR, compression)))
+                                            this, METHODID_DELETE_KPI, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getDeleteKpiMethod(),
+                            monitoring.MonitoringServiceGrpc.getGetKpiDescriptorMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.KpiId,
-                                            context.ContextOuterClass.Empty>(
-                                            this, METHODID_DELETE_KPI, compression)))
+                                            monitoring.Monitoring.KpiDescriptor>(
+                                            this, METHODID_GET_KPI_DESCRIPTOR, compression)))
                     .addMethod(
                             monitoring.MonitoringServiceGrpc.getGetKpiDescriptorListMethod(),
                             asyncUnaryCall(
@@ -262,20 +262,6 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                                             context.ContextOuterClass.Empty,
                                             monitoring.Monitoring.KpiDescriptorList>(
                                             this, METHODID_GET_KPI_DESCRIPTOR_LIST, compression)))
-                    .addMethod(
-                            monitoring.MonitoringServiceGrpc.getCreateBundleKpiMethod(),
-                            asyncUnaryCall(
-                                    new MethodHandlers<
-                                            monitoring.Monitoring.BundleKpiDescriptor,
-                                            monitoring.Monitoring.KpiId>(
-                                            this, METHODID_CREATE_BUNDLE_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(
@@ -298,12 +284,12 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                                             monitoring.Monitoring.KpiList>(
                                             this, METHODID_QUERY_KPI_DATA, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getSubscribeKpiMethod(),
+                            monitoring.MonitoringServiceGrpc.getSetKpiSubscriptionMethod(),
                             asyncServerStreamingCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.SubsDescriptor,
                                             monitoring.Monitoring.KpiList>(
-                                            this, METHODID_SUBSCRIBE_KPI, compression)))
+                                            this, METHODID_SET_KPI_SUBSCRIPTION, compression)))
                     .addMethod(
                             monitoring.MonitoringServiceGrpc.getGetSubsDescriptorMethod(),
                             asyncUnaryCall(
@@ -319,26 +305,19 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                                             monitoring.Monitoring.SubsIDList>(
                                             this, METHODID_GET_SUBSCRIPTIONS, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getEditKpiSubscriptionMethod(),
+                            monitoring.MonitoringServiceGrpc.getDeleteSubscriptionMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            monitoring.Monitoring.SubsDescriptor,
+                                            monitoring.Monitoring.SubscriptionID,
                                             context.ContextOuterClass.Empty>(
-                                            this, METHODID_EDIT_KPI_SUBSCRIPTION, compression)))
+                                            this, METHODID_DELETE_SUBSCRIPTION, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getCreateKpiAlarmMethod(),
+                            monitoring.MonitoringServiceGrpc.getSetKpiAlarmMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.AlarmDescriptor,
                                             monitoring.Monitoring.AlarmID>(
-                                            this, METHODID_CREATE_KPI_ALARM, compression)))
-                    .addMethod(
-                            monitoring.MonitoringServiceGrpc.getEditKpiAlarmMethod(),
-                            asyncUnaryCall(
-                                    new MethodHandlers<
-                                            monitoring.Monitoring.AlarmDescriptor,
-                                            context.ContextOuterClass.Empty>(
-                                            this, METHODID_EDIT_KPI_ALARM, compression)))
+                                            this, METHODID_SET_KPI_ALARM, compression)))
                     .addMethod(
                             monitoring.MonitoringServiceGrpc.getGetAlarmsMethod(),
                             asyncUnaryCall(
@@ -357,31 +336,52 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             monitoring.MonitoringServiceGrpc.getGetAlarmResponseStreamMethod(),
                             asyncServerStreamingCall(
                                     new MethodHandlers<
-                                            monitoring.Monitoring.AlarmID,
+                                            monitoring.Monitoring.AlarmSubscription,
                                             monitoring.Monitoring.AlarmResponse>(
                                             this, METHODID_GET_ALARM_RESPONSE_STREAM, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getDeleteAlarmMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.AlarmID,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_DELETE_ALARM, 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.KpiList>(
+                                            this, METHODID_GET_INSTANT_KPI, compression)))
                     .build();
         }
     }
 
-    private static final int METHODID_CREATE_KPI = 0;
-    private static final int METHODID_EDIT_KPI_DESCRIPTOR = 1;
-    private static final int METHODID_DELETE_KPI = 2;
+    private static final int METHODID_SET_KPI = 0;
+    private static final int METHODID_DELETE_KPI = 1;
+    private static final int METHODID_GET_KPI_DESCRIPTOR = 2;
     private static final int METHODID_GET_KPI_DESCRIPTOR_LIST = 3;
-    private static final int METHODID_CREATE_BUNDLE_KPI = 4;
-    private static final int METHODID_GET_KPI_DESCRIPTOR = 5;
-    private static final int METHODID_INCLUDE_KPI = 6;
-    private static final int METHODID_MONITOR_KPI = 7;
-    private static final int METHODID_QUERY_KPI_DATA = 8;
-    private static final int METHODID_SUBSCRIBE_KPI = 9;
-    private static final int METHODID_GET_SUBS_DESCRIPTOR = 10;
-    private static final int METHODID_GET_SUBSCRIPTIONS = 11;
-    private static final int METHODID_EDIT_KPI_SUBSCRIPTION = 12;
-    private static final int METHODID_CREATE_KPI_ALARM = 13;
-    private static final int METHODID_EDIT_KPI_ALARM = 14;
-    private static final int METHODID_GET_ALARMS = 15;
-    private static final int METHODID_GET_ALARM_DESCRIPTOR = 16;
-    private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 17;
+    private static final int METHODID_INCLUDE_KPI = 4;
+    private static final int METHODID_MONITOR_KPI = 5;
+    private static final int METHODID_QUERY_KPI_DATA = 6;
+    private static final int METHODID_SET_KPI_SUBSCRIPTION = 7;
+    private static final int METHODID_GET_SUBS_DESCRIPTOR = 8;
+    private static final int METHODID_GET_SUBSCRIPTIONS = 9;
+    private static final int METHODID_DELETE_SUBSCRIPTION = 10;
+    private static final int METHODID_SET_KPI_ALARM = 11;
+    private static final int METHODID_GET_ALARMS = 12;
+    private static final int METHODID_GET_ALARM_DESCRIPTOR = 13;
+    private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 14;
+    private static final int METHODID_DELETE_ALARM = 15;
+    private static final int METHODID_GET_STREAM_KPI = 16;
+    private static final int METHODID_GET_INSTANT_KPI = 17;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -402,17 +402,11 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         @java.lang.SuppressWarnings("unchecked")
         public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
             switch (methodId) {
-                case METHODID_CREATE_KPI:
+                case METHODID_SET_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_EDIT_KPI_DESCRIPTOR:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.EditedKpiDescriptor) request,
-                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
-                            compression,
-                            serviceImpl::editKpiDescriptor);
+                            serviceImpl::setKpi);
                     break;
                 case METHODID_DELETE_KPI:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.KpiId) request,
@@ -420,24 +414,18 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::deleteKpi);
                     break;
-                case METHODID_GET_KPI_DESCRIPTOR_LIST:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Empty) request,
-                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver,
-                            compression,
-                            serviceImpl::getKpiDescriptorList);
-                    break;
-                case METHODID_CREATE_BUNDLE_KPI:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.BundleKpiDescriptor) request,
-                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId>) responseObserver,
-                            compression,
-                            serviceImpl::createBundleKpi);
-                    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_GET_KPI_DESCRIPTOR_LIST:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Empty) request,
+                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver,
+                            compression,
+                            serviceImpl::getKpiDescriptorList);
+                    break;
                 case METHODID_INCLUDE_KPI:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.Kpi) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
@@ -456,11 +444,11 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::queryKpiData);
                     break;
-                case METHODID_SUBSCRIBE_KPI:
+                case METHODID_SET_KPI_SUBSCRIPTION:
                     io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.SubsDescriptor) request,
                             (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList>) responseObserver,
                             compression,
-                            serviceImpl::subscribeKpi);
+                            serviceImpl::setKpiSubscription);
                     break;
                 case METHODID_GET_SUBS_DESCRIPTOR:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.SubscriptionID) request,
@@ -474,23 +462,17 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::getSubscriptions);
                     break;
-                case METHODID_EDIT_KPI_SUBSCRIPTION:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.SubsDescriptor) request,
+                case METHODID_DELETE_SUBSCRIPTION:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.SubscriptionID) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
                             compression,
-                            serviceImpl::editKpiSubscription);
+                            serviceImpl::deleteSubscription);
                     break;
-                case METHODID_CREATE_KPI_ALARM:
+                case METHODID_SET_KPI_ALARM:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.AlarmDescriptor) request,
                             (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID>) responseObserver,
                             compression,
-                            serviceImpl::createKpiAlarm);
-                    break;
-                case METHODID_EDIT_KPI_ALARM:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.AlarmDescriptor) request,
-                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
-                            compression,
-                            serviceImpl::editKpiAlarm);
+                            serviceImpl::setKpiAlarm);
                     break;
                 case METHODID_GET_ALARMS:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Empty) request,
@@ -505,11 +487,29 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             serviceImpl::getAlarmDescriptor);
                     break;
                 case METHODID_GET_ALARM_RESPONSE_STREAM:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.AlarmID) request,
+                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.AlarmSubscription) request,
                             (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse>) responseObserver,
                             compression,
                             serviceImpl::getAlarmResponseStream);
                     break;
+                case METHODID_DELETE_ALARM:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.AlarmID) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::deleteAlarm);
+                    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.KpiList>) responseObserver,
+                            compression,
+                            serviceImpl::getInstantKpi);
+                    break;
                 default:
                     throw new java.lang.AssertionError();
             }
diff --git a/src/automation/target/kubernetes/kubernetes.yml b/src/automation/target/kubernetes/kubernetes.yml
index f5cea3757989504c02ee45db20a1a2ef80b28f98..8bc14b935b4e4f4a18ed03f10cca0b74f480dcf0 100644
--- a/src/automation/target/kubernetes/kubernetes.yml
+++ b/src/automation/target/kubernetes/kubernetes.yml
@@ -3,20 +3,19 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: ac09ca6e8827edf1379450dc3e68dcdc35957479
-    app.quarkus.io/build-timestamp: 2022-08-02 - 07:36:43 +0000
+    app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000
   labels:
     app.kubernetes.io/name: automationservice
     app: automationservice
   name: automationservice
 spec:
   ports:
-    - name: http
-      port: 8080
-      targetPort: 8080
     - name: grpc
       port: 5050
       targetPort: 5050
+    - name: http
+      port: 8080
+      targetPort: 8080
   selector:
     app.kubernetes.io/name: automationservice
   type: ClusterIP
@@ -25,8 +24,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: ac09ca6e8827edf1379450dc3e68dcdc35957479
-    app.quarkus.io/build-timestamp: 2022-08-02 - 07:36:43 +0000
+    app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000
   labels:
     app: automationservice
     app.kubernetes.io/name: automationservice
@@ -39,8 +37,7 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: ac09ca6e8827edf1379450dc3e68dcdc35957479
-        app.quarkus.io/build-timestamp: 2022-08-02 - 07:36:43 +0000
+        app.quarkus.io/build-timestamp: 2022-09-19 - 10:48:18 +0000
       labels:
         app: automationservice
         app.kubernetes.io/name: automationservice
@@ -52,9 +49,9 @@ spec:
                 fieldRef:
                   fieldPath: metadata.namespace
             - name: CONTEXT_SERVICE_HOST
-              value: ContextService
+              value: contextservice
             - name: DEVICE_SERVICE_HOST
-              value: DeviceService
+              value: deviceservice
           image: registry.gitlab.com/teraflow-h2020/controller/automation:0.2.0
           imagePullPolicy: Always
           livenessProbe:
@@ -69,12 +66,12 @@ spec:
             timeoutSeconds: 10
           name: automationservice
           ports:
-            - containerPort: 8080
-              name: http
-              protocol: TCP
             - containerPort: 5050
               name: grpc
               protocol: TCP
+            - containerPort: 8080
+              name: http
+              protocol: TCP
           readinessProbe:
             failureThreshold: 3
             httpGet:
diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py
index 3cd53ea09816f18b7cc550569e230ea1a68f3762..162b8e96260ccfe536e3db1d5b5a81fd27ef42d6 100644
--- a/src/common/DeviceTypes.py
+++ b/src/common/DeviceTypes.py
@@ -15,13 +15,15 @@
 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'
-    PACKET_ROUTER                = 'packet-router'
-    PACKET_SWITCH                = 'packet-switch'
-    P4_SWITCH                    = 'p4-switch'
-    XR_CONSTELLATION             = 'xr-constellation'
+    EMULATED_DATACENTER       = 'emu-datacenter'
+    EMULATED_OPEN_LINE_SYSTEM = 'emu-open-line-system'
+    EMULATED_PACKET_ROUTER    = 'emu-packet-router'
+    DATACENTER                = 'datacenter'
+    MICROVAWE_RADIO_SYSTEM    = 'microwave-radio-system'
+    OPTICAL_ROADM             = 'optical-roadm'
+    OPTICAL_TRANSPONDER       = 'optical-transponder'
+    OPEN_LINE_SYSTEM          = 'open-line-system'
+    PACKET_ROUTER             = 'packet-router'
+    PACKET_SWITCH             = 'packet-switch'
+    P4_SWITCH                 = 'p4-switch'
+    XR_CONSTELLATION          = 'xr-constellation'
diff --git a/src/common/rpc_method_wrapper/ServiceExceptions.py b/src/common/rpc_method_wrapper/ServiceExceptions.py
index f4f0a64cad79c96dc069bd37e8d2c2be5f011c53..e8d5c79acca19117fca53ec216166c01d3f0781d 100644
--- a/src/common/rpc_method_wrapper/ServiceExceptions.py
+++ b/src/common/rpc_method_wrapper/ServiceExceptions.py
@@ -56,3 +56,11 @@ class OperationFailedException(ServiceException):
 
         details = 'Operation({:s}) failed'.format(str(operation))
         super().__init__(grpc.StatusCode.INTERNAL, details, extra_details=extra_details)
+
+class NotImplementedException(ServiceException):
+    def __init__(
+        self, operation : str, extra_details : Union[str, Iterable[str]] = None
+        ) -> None:
+
+        details = 'Operation({:s}) not implemented'.format(str(operation))
+        super().__init__(grpc.StatusCode.UNIMPLEMENTED, details, extra_details=extra_details)
diff --git a/src/common/tests/EventTools.py b/src/common/tests/EventTools.py
index ceff4d60e597690b29d5f1bcac894c081eb88a56..d0f82841395ea77a7c2483099458760769f8c535 100644
--- a/src/common/tests/EventTools.py
+++ b/src/common/tests/EventTools.py
@@ -15,7 +15,7 @@
 import json, logging
 from typing import Dict, List, Tuple
 from common.proto.context_pb2 import (
-    ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, LinkEvent, ServiceEvent, TopologyEvent)
+    ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, LinkEvent, ServiceEvent, SliceEvent, TopologyEvent)
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.EventsCollector import EventsCollector
 
@@ -32,6 +32,7 @@ CLASSNAME_CONTEXT_EVENT    = class_to_classname(ContextEvent)
 CLASSNAME_TOPOLOGY_EVENT   = class_to_classname(TopologyEvent)
 CLASSNAME_DEVICE_EVENT     = class_to_classname(DeviceEvent)
 CLASSNAME_LINK_EVENT       = class_to_classname(LinkEvent)
+CLASSNAME_SLICE_EVENT      = class_to_classname(SliceEvent)
 CLASSNAME_SERVICE_EVENT    = class_to_classname(ServiceEvent)
 CLASSNAME_CONNECTION_EVENT = class_to_classname(ConnectionEvent)
 
@@ -40,6 +41,7 @@ EVENT_CLASS_NAME__TO__ENTITY_ID_SELECTOR = {
     CLASSNAME_TOPOLOGY_EVENT  : lambda event: event.topology_id,
     CLASSNAME_DEVICE_EVENT    : lambda event: event.device_id,
     CLASSNAME_LINK_EVENT      : lambda event: event.link_id,
+    CLASSNAME_SLICE_EVENT     : lambda event: event.slice_id,
     CLASSNAME_SERVICE_EVENT   : lambda event: event.service_id,
     CLASSNAME_CONNECTION_EVENT: lambda event: event.connection_id,
 }
diff --git a/src/common/tools/object_factory/Constraint.py b/src/common/tools/object_factory/Constraint.py
index df290d4285330f1965608d710d9d48ca49131521..757531daf65b60c5f5b6c90ee67ef00488f91590 100644
--- a/src/common/tools/object_factory/Constraint.py
+++ b/src/common/tools/object_factory/Constraint.py
@@ -15,6 +15,19 @@
 import json
 from typing import Any, Dict, Union
 
-def json_constraint(constraint_type : str, constraint_value : Union[str, Dict[str, Any]]):
+def json_constraint_custom(constraint_type : str, constraint_value : Union[str, Dict[str, Any]]) -> Dict:
     if not isinstance(constraint_value, str): constraint_value = json.dumps(constraint_value, sort_keys=True)
     return {'custom': {'constraint_type': constraint_type, 'constraint_value': constraint_value}}
+
+def json_constraint_endpoint_location_region(endpoint_id : Dict, region : str) -> Dict:
+    return {'endpoint_location': {'endpoint_id': endpoint_id, 'location': {'region': region}}}
+
+def json_constraint_endpoint_location_gps(endpoint_id : Dict, latitude : float, longitude : float) -> Dict:
+    gps_position = {'latitude': latitude, 'longitude': longitude}
+    return {'endpoint_location': {'endpoint_id': endpoint_id, 'location': {'gps_position': gps_position}}}
+
+def json_constraint_endpoint_priority(endpoint_id : Dict, priority : int) -> Dict:
+    return {'endpoint_priority': {'endpoint_id': endpoint_id, 'priority': priority}}
+
+def json_constraint_sla_availability(num_disjoint_paths : int, all_active : bool) -> Dict:
+    return {'sla_availability': {'num_disjoint_paths': num_disjoint_paths, 'all_active': all_active}}
diff --git a/src/common/tools/object_factory/Device.py b/src/common/tools/object_factory/Device.py
index 0b597a77a58773e4e8811e801b98fa6154980cc6..5ac339a8b82f49142daa24cde64835513652e83e 100644
--- a/src/common/tools/object_factory/Device.py
+++ b/src/common/tools/object_factory/Device.py
@@ -15,12 +15,13 @@
 import copy
 from typing import Dict, List, Tuple
 from common.DeviceTypes import DeviceTypeEnum
-from common.proto.context_pb2 import DEVICEDRIVER_XR, DeviceDriverEnum, DeviceOperationalStatusEnum
+from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum
 from common.tools.object_factory.ConfigRule import json_config_rule_set
 
 DEVICE_DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
 
-DEVICE_EMUOLS_TYPE  = DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value
+DEVICE_EMUDC_TYPE   = DeviceTypeEnum.EMULATED_DATACENTER.value
+DEVICE_EMUOLS_TYPE  = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
 DEVICE_EMUPR_TYPE   = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
 DEVICE_EMU_DRIVERS  = [DeviceDriverEnum.DEVICEDRIVER_UNDEFINED]
 DEVICE_EMU_ADDRESS  = '127.0.0.1'
@@ -29,7 +30,7 @@ DEVICE_EMU_PORT     = '0'
 DEVICE_PR_TYPE      = DeviceTypeEnum.PACKET_ROUTER.value
 DEVICE_PR_DRIVERS   = [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG]
 
-DEVICE_TAPI_TYPE    = DeviceTypeEnum.OPTICAL_LINE_SYSTEM.value
+DEVICE_TAPI_TYPE    = DeviceTypeEnum.OPEN_LINE_SYSTEM.value
 DEVICE_TAPI_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API]
 
 DEVICE_XR_CONSTELLATION_TYPE    = DeviceTypeEnum.XR_CONSTELLATION.value
@@ -74,6 +75,14 @@ def json_device_emulated_tapi_disabled(
         device_uuid, DEVICE_EMUOLS_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules,
         drivers=drivers)
 
+def json_device_emulated_datacenter_disabled(
+        device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [],
+        drivers : List[Dict] = DEVICE_EMU_DRIVERS
+    ):
+    return json_device(
+        device_uuid, DEVICE_EMUDC_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules,
+        drivers=drivers)
+
 def json_device_packetrouter_disabled(
         device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [],
         drivers : List[Dict] = DEVICE_PR_DRIVERS
diff --git a/src/common/tools/object_factory/Service.py b/src/common/tools/object_factory/Service.py
index 51f75e6dbe5e430330e697da772d65703f7568c7..62f3dcbda148f1c624265ae7d76b0c17f5d36959 100644
--- a/src/common/tools/object_factory/Service.py
+++ b/src/common/tools/object_factory/Service.py
@@ -44,10 +44,20 @@ def json_service(
 
 def json_service_l3nm_planned(
         service_uuid : str, endpoint_ids : List[Dict] = [], constraints : List[Dict] = [],
-        config_rules : List[Dict] = []
+        config_rules : List[Dict] = [], context_uuid : str = DEFAULT_CONTEXT_UUID
     ):
 
     return json_service(
-        service_uuid, ServiceTypeEnum.SERVICETYPE_L3NM, context_id=json_context_id(DEFAULT_CONTEXT_UUID),
+        service_uuid, ServiceTypeEnum.SERVICETYPE_L3NM, context_id=json_context_id(context_uuid),
+        status=ServiceStatusEnum.SERVICESTATUS_PLANNED, endpoint_ids=endpoint_ids, constraints=constraints,
+        config_rules=config_rules)
+
+def json_service_tapi_planned(
+        service_uuid : str, endpoint_ids : List[Dict] = [], constraints : List[Dict] = [],
+        config_rules : List[Dict] = [], context_uuid : str = DEFAULT_CONTEXT_UUID
+    ):
+
+    return json_service(
+        service_uuid, ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE, context_id=json_context_id(context_uuid),
         status=ServiceStatusEnum.SERVICESTATUS_PLANNED, endpoint_ids=endpoint_ids, constraints=constraints,
         config_rules=config_rules)
diff --git a/src/common/tools/service/ConstraintsChecker.py b/src/common/tools/service/ConstraintsChecker.py
new file mode 100644
index 0000000000000000000000000000000000000000..864cf3ed1b45c68a4628c1196b86de6e9df0edfd
--- /dev/null
+++ b/src/common/tools/service/ConstraintsChecker.py
@@ -0,0 +1,38 @@
+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/common/tools/service/SliceCheckers.py b/src/common/tools/service/SliceCheckers.py
new file mode 100644
index 0000000000000000000000000000000000000000..bac9766b8595c64f9f8d68954707cc5f1efc68e0
--- /dev/null
+++ b/src/common/tools/service/SliceCheckers.py
@@ -0,0 +1,18 @@
+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/monitoring/Config.py b/src/common/tools/timestamp/Converters.py
similarity index 56%
rename from src/monitoring/Config.py
rename to src/common/tools/timestamp/Converters.py
index cbae00509d8196b69bc2d6bacb39bfa5918be495..46a1bcb01a83f1ff4fc2d54cd8fb606dbe7f2bcc 100644
--- a/src/monitoring/Config.py
+++ b/src/common/tools/timestamp/Converters.py
@@ -12,29 +12,15 @@
 # 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 = 7070
-GRPC_MAX_WORKERS  = 10
-GRPC_GRACE_PERIOD = 60
-GRPC_SERVICE_HOST = '127.0.0.1'
-
-# Prometheus settings
-METRICS_PORT = 9192
-
-# Dependency micro-service connection settings
-CONTEXT_SERVICE_HOST = '127.0.0.1'
-CONTEXT_GRPC_SERVICE_PORT = 1010
-
-DEVICE_SERVICE_HOST         = '127.0.0.1'
-DEVICE_GRPC_SERVICE_PORT    = 2020
-DEVICE_GRPC_MAX_WORKERS     = 10
-DEVICE_GRPC_GRACE_PERIOD    = 60
 
+import dateutil.parser
+from datetime import datetime, timezone
 
+def timestamp_string_to_float(str_timestamp : str) -> float:
+    return datetime.timestamp(dateutil.parser.isoparse(str_timestamp))
 
+def timestamp_float_to_string(flt_timestamp : float) -> str:
+    return datetime.utcfromtimestamp(flt_timestamp).isoformat() + 'Z'
 
+def timestamp_utcnow_to_float() -> float:
+    return datetime.timestamp(datetime.now(tz=timezone.utc))
diff --git a/src/pathcomp/client/__init__.py b/src/common/tools/timestamp/__init__.py
similarity index 100%
rename from src/pathcomp/client/__init__.py
rename to src/common/tools/timestamp/__init__.py
diff --git a/src/compute/service/__main__.py b/src/compute/service/__main__.py
index 345b2fdd6950ecda802e8bd1c86e1421b5c60d84..e80681e177f0f0def3dbe75d76e7e65ceaca1e87 100644
--- a/src/compute/service/__main__.py
+++ b/src/compute/service/__main__.py
@@ -39,6 +39,8 @@ def main():
     wait_for_environment_variables([
         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),
     ])
 
     signal.signal(signal.SIGINT,  signal_handler)
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 d432e5605cfebaa01c2a8faf0cbffcff110d7dbe..45724e968c95e5e66c7ff398cc61f7ea9dc3cbf0 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
@@ -17,38 +17,51 @@ DEFAULT_ADDRESS_FAMILIES = ['IPV4']
 DEFAULT_BGP_AS           = 65000
 DEFAULT_BGP_ROUTE_TARGET = '{:d}:{:d}'.format(DEFAULT_BGP_AS, 333)
 
+# TODO: improve definition of bearer mappings
+
 # Bearer mappings:
 # device_uuid:endpoint_uuid => (
-#       device_uuid, endpoint_uuid, router_id, route_distinguisher, sub_if_index, address_ip, address_prefix)
+#   device_uuid, endpoint_uuid, router_id, route_dist, sub_if_index,
+#   address_ip, address_prefix, remote_router, circuit_id)
+
 BEARER_MAPPINGS = {
-    'R1-EMU:13/1/2': ('R1-EMU', '13/1/2', '10.10.10.1', '65000:100', 400, '3.3.2.1', 24),
-    'R2-EMU:13/1/2': ('R2-EMU', '13/1/2', '12.12.12.1', '65000:120', 450, '3.4.2.1', 24),
-    'R3-EMU:13/1/2': ('R3-EMU', '13/1/2', '20.20.20.1', '65000:200', 500, '3.3.1.1', 24),
-    'R4-EMU:13/1/2': ('R4-EMU', '13/1/2', '22.22.22.1', '65000:220', 550, '3.4.1.1', 24),
+    # OFC'22
+    'R1-EMU:13/1/2': ('R1-EMU', '13/1/2', '10.10.10.1', '65000:100', 400, '3.3.2.1', 24, None, None),
+    'R2-EMU:13/1/2': ('R2-EMU', '13/1/2', '12.12.12.1', '65000:120', 450, '3.4.2.1', 24, None, None),
+    'R3-EMU:13/1/2': ('R3-EMU', '13/1/2', '20.20.20.1', '65000:200', 500, '3.3.1.1', 24, None, None),
+    'R4-EMU:13/1/2': ('R4-EMU', '13/1/2', '22.22.22.1', '65000:220', 550, '3.4.1.1', 24, None, None),
+
+    # OECC/PSC'22 - domain 1
+    'R1@D1:3/1'    : ('R1@D1', '3/1', '10.0.1.1', '65001:101', 100, '1.1.3.1', 24, None, None),
+    'R1@D1:3/2'    : ('R1@D1', '3/2', '10.0.1.1', '65001:101', 100, '1.1.3.2', 24, None, None),
+    'R1@D1:3/3'    : ('R1@D1', '3/3', '10.0.1.1', '65001:101', 100, '1.1.3.3', 24, None, None),
+    'R2@D1:3/1'    : ('R2@D1', '3/1', '10.0.1.2', '65001:102', 100, '1.2.3.1', 24, None, None),
+    'R2@D1:3/2'    : ('R2@D1', '3/2', '10.0.1.2', '65001:102', 100, '1.2.3.2', 24, None, None),
+    'R2@D1:3/3'    : ('R2@D1', '3/3', '10.0.1.2', '65001:102', 100, '1.2.3.3', 24, None, None),
+    'R3@D1:3/1'    : ('R3@D1', '3/1', '10.0.1.3', '65001:103', 100, '1.3.3.1', 24, None, None),
+    'R3@D1:3/2'    : ('R3@D1', '3/2', '10.0.1.3', '65001:103', 100, '1.3.3.2', 24, None, None),
+    'R3@D1:3/3'    : ('R3@D1', '3/3', '10.0.1.3', '65001:103', 100, '1.3.3.3', 24, None, None),
+    'R4@D1:3/1'    : ('R4@D1', '3/1', '10.0.1.4', '65001:104', 100, '1.4.3.1', 24, None, None),
+    'R4@D1:3/2'    : ('R4@D1', '3/2', '10.0.1.4', '65001:104', 100, '1.4.3.2', 24, None, None),
+    'R4@D1:3/3'    : ('R4@D1', '3/3', '10.0.1.4', '65001:104', 100, '1.4.3.3', 24, None, None),
 
-    '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),
+    # OECC/PSC'22 - domain 2
+    'R1@D2:3/1'    : ('R1@D2', '3/1', '10.0.2.1', '65002:101', 100, '2.1.3.1', 24, None, None),
+    'R1@D2:3/2'    : ('R1@D2', '3/2', '10.0.2.1', '65002:101', 100, '2.1.3.2', 24, None, None),
+    'R1@D2:3/3'    : ('R1@D2', '3/3', '10.0.2.1', '65002:101', 100, '2.1.3.3', 24, None, None),
+    'R2@D2:3/1'    : ('R2@D2', '3/1', '10.0.2.2', '65002:102', 100, '2.2.3.1', 24, None, None),
+    'R2@D2:3/2'    : ('R2@D2', '3/2', '10.0.2.2', '65002:102', 100, '2.2.3.2', 24, None, None),
+    'R2@D2:3/3'    : ('R2@D2', '3/3', '10.0.2.2', '65002:102', 100, '2.2.3.3', 24, None, None),
+    'R3@D2:3/1'    : ('R3@D2', '3/1', '10.0.2.3', '65002:103', 100, '2.3.3.1', 24, None, None),
+    'R3@D2:3/2'    : ('R3@D2', '3/2', '10.0.2.3', '65002:103', 100, '2.3.3.2', 24, None, None),
+    'R3@D2:3/3'    : ('R3@D2', '3/3', '10.0.2.3', '65002:103', 100, '2.3.3.3', 24, None, None),
+    'R4@D2:3/1'    : ('R4@D2', '3/1', '10.0.2.4', '65002:104', 100, '2.4.3.1', 24, None, None),
+    'R4@D2:3/2'    : ('R4@D2', '3/2', '10.0.2.4', '65002:104', 100, '2.4.3.2', 24, None, None),
+    'R4@D2:3/3'    : ('R4@D2', '3/3', '10.0.2.4', '65002:104', 100, '2.4.3.3', 24, None, None),
 
-    '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),
+    # ECOC'22
+    'DC1-GW:CS1-GW1': ('CS1-GW1', '10/1', '5.5.1.1', None, 0, None, None, '5.5.2.1', 111),
+    'DC1-GW:CS1-GW2': ('CS1-GW2', '10/1', '5.5.1.2', None, 0, None, None, '5.5.2.2', 222),
+    'DC2-GW:CS2-GW1': ('CS2-GW1', '10/1', '5.5.2.1', None, 0, None, None, '5.5.1.1', 111),
+    'DC2-GW:CS2-GW2': ('CS2-GW2', '10/1', '5.5.2.2', None, 0, None, None, '5.5.1.2', 222),
 }
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 c77d714a94fa8d2d4ee9cd2c3db06949665a489c..7e050289f19b93dc710185c2b29b326bbfd156d2 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
@@ -16,12 +16,11 @@ import logging
 from flask import request
 from flask.json import jsonify
 from flask_restful import Resource
-from common.Constants import DEFAULT_CONTEXT_UUID
-from common.proto.context_pb2 import ServiceId, ServiceStatusEnum, SliceStatusEnum
+from common.proto.context_pb2 import SliceStatusEnum
 from context.client.ContextClient import ContextClient
-from service.client.ServiceClient import ServiceClient
+from slice.client.SliceClient import SliceClient
 from .tools.Authentication import HTTP_AUTH
-from .tools.ContextMethods import get_service, get_slice
+from .tools.ContextMethods import get_slice
 from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR
 
 LOGGER = logging.getLogger(__name__)
@@ -32,31 +31,22 @@ class L2VPN_Service(Resource):
         LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
         LOGGER.debug('Request: {:s}'.format(str(request)))
 
-        response = jsonify({})
         try:
             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')
-                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(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
+            if target is None:
+                raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
 
-            raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
+            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 = jsonify({})
+            response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT
         except Exception as e: # pylint: disable=broad-except
-            LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(request)))
+            LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(vpn_id)))
             response = jsonify({'error': str(e)})
             response.status_code = HTTP_SERVERERROR
         return response
@@ -66,18 +56,21 @@ 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
-
         try:
-            service_client = ServiceClient()
-            service_client.DeleteService(service_id_request)
+            context_client = ContextClient()
+
+            target = get_slice(context_client, vpn_id)
+            if target is None:
+                LOGGER.warning('VPN({:s}) not found in database. Nothing done.'.format(str(vpn_id)))
+            else:
+                if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member
+                    raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
+                slice_client = SliceClient()
+                slice_client.DeleteSlice(target.slice_id)
             response = jsonify({})
             response.status_code = HTTP_NOCONTENT
         except Exception as e: # pylint: disable=broad-except
-            LOGGER.exception('Something went wrong Deleting Service {:s}'.format(str(request)))
+            LOGGER.exception('Something went wrong Deleting VPN({:s})'.format(str(vpn_id)))
             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 7b959b2895d0f0acd27058fcb5e9a571cf6553d2..f27d852f017a08cb8b854cc19568280b9de14470 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,8 +19,7 @@ from flask.json import jsonify
 from flask_restful import Resource
 from werkzeug.exceptions import UnsupportedMediaType
 from common.Constants import DEFAULT_CONTEXT_UUID
-from common.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum, SliceStatusEnum, Slice
-from service.client.ServiceClient import ServiceClient
+from common.proto.context_pb2 import SliceStatusEnum, Slice
 from slice.client.SliceClient import SliceClient
 from .schemas.vpn_service import SCHEMA_VPN_SERVICE
 from .tools.Authentication import HTTP_AUTH
@@ -44,30 +43,16 @@ class L2VPN_Services(Resource):
         vpn_services : List[Dict] = request_data['ietf-l2vpn-svc:vpn-service']
         for vpn_service in vpn_services:
             try:
-                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_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':
-                    # 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_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')
+                # 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_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')
 
                 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 8be63895b813d7411b76ddeb33902babbf4c9743..3cc823a2aa7a06de6cb591ef6d668ba7eeef5cbd 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,169 +12,113 @@
 # 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
+import logging
+from typing import Dict, Optional
 from flask import request
 from flask.json import jsonify
 from flask.wrappers import Response
 from flask_restful import Resource
 from werkzeug.exceptions import UnsupportedMediaType
-from common.proto.context_pb2 import ConfigActionEnum, Service, Slice
+from common.proto.context_pb2 import Slice
+from common.tools.grpc.ConfigRules import update_config_rule_custom
+from common.tools.grpc.Constraints import (
+    update_constraint_custom, update_constraint_endpoint_location, update_constraint_endpoint_priority,
+    update_constraint_sla_availability)
+from common.tools.grpc.EndPointIds import update_endpoint_ids
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
-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.ContextMethods import 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
+from .Constants import (
+    BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU)
 
 LOGGER = logging.getLogger(__name__)
 
-def process_site_network_access(context_client : ContextClient, site_network_access : Dict) -> Service:
+def process_site_network_access(context_client : ContextClient, site_id : str, site_network_access : Dict) -> Slice:
     vpn_id = site_network_access['vpn-attachment']['vpn-id']
-    cvlan_id = site_network_access['connection']['tagged-interface']['dot1q-vlan-tagged']['cvlan-id']
+    encapsulation_type = site_network_access['connection']['encapsulation-type']
+    cvlan_id = site_network_access['connection']['tagged-interface'][encapsulation_type]['cvlan-id']
+
     bearer_reference = site_network_access['bearer']['bearer-reference']
 
+    access_priority : Optional[int] = site_network_access.get('availability', {}).get('access-priority')
+    single_active   : bool = len(site_network_access.get('availability', {}).get('single-active', [])) > 0
+    all_active      : bool = len(site_network_access.get('availability', {}).get('all-active', [])) > 0
+
+    diversity_constraints = site_network_access.get('access-diversity', {}).get('constraints', {}).get('constraint', [])
+    raise_if_differs = True
+    diversity_constraints = {
+        constraint['constraint-type']:([
+            target[0]
+            for target in constraint['target'].items()
+            if len(target[1]) == 1
+        ][0], raise_if_differs)
+        for constraint in diversity_constraints
+    }
+
     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
+    (
+        device_uuid, endpoint_uuid, router_id, route_dist, sub_if_index,
+        address_ip, address_prefix, remote_router, circuit_id
+    ) = mapping
 
-    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)
+    target = get_slice(context_client, vpn_id)
     if target is None: raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
 
-    # pylint: disable=no-member
-    endpoint_ids = target.service_endpoint_ids if isinstance(target, Service) else target.slice_endpoint_ids
-
-    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 = endpoint_ids.add()
-        endpoint_id.device_id.device_uuid.uuid = device_uuid
-        endpoint_id.endpoint_uuid.uuid = endpoint_uuid
-
-    if isinstance(target, Slice): return target
-
-    for config_rule in target.service_config.config_rules:                  # pylint: disable=no-member
-        if config_rule.WhichOneof('config_rule') != 'custom': continue
-        if config_rule.custom.resource_key != '/settings': continue
-        json_settings = json.loads(config_rule.custom.resource_value)
-
-        if 'mtu' not in json_settings:                                      # missing, add it
-            json_settings['mtu'] = DEFAULT_MTU
-        elif json_settings['mtu'] != DEFAULT_MTU:                           # differs, raise exception
-            msg = 'Specified MTU({:s}) differs from Service MTU({:s})'
-            raise Exception(msg.format(str(json_settings['mtu']), str(DEFAULT_MTU)))
-
-        if 'address_families' not in json_settings:                         # missing, add it
-            json_settings['address_families'] = DEFAULT_ADDRESS_FAMILIES
-        elif json_settings['address_families'] != DEFAULT_ADDRESS_FAMILIES: # differs, raise exception
-            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.custom.resource_value = json.dumps(json_settings, sort_keys=True)
-        break
-    else:
-        # not found, add it
-        config_rule = target.service_config.config_rules.add()              # pylint: disable=no-member
-        config_rule.action = ConfigActionEnum.CONFIGACTION_SET
-        config_rule.custom.resource_key = '/settings'
-        config_rule.custom.resource_value = json.dumps({
-            'mtu'             : DEFAULT_MTU,
-            'address_families': DEFAULT_ADDRESS_FAMILIES,
-            'bgp_as'          : DEFAULT_BGP_AS,
-            'bgp_route_target': DEFAULT_BGP_ROUTE_TARGET,
-        }, sort_keys=True)
+    endpoint_ids = target.slice_endpoint_ids        # pylint: disable=no-member
+    config_rules = target.slice_config.config_rules # pylint: disable=no-member
+    constraints  = target.slice_constraints         # pylint: disable=no-member
+
+    endpoint_id = update_endpoint_ids(endpoint_ids, device_uuid, endpoint_uuid)
+
+    service_settings_key = '/settings'
+    update_config_rule_custom(config_rules, service_settings_key, {
+        'mtu'             : (DEFAULT_MTU,              True),
+        'address_families': (DEFAULT_ADDRESS_FAMILIES, True),
+        'bgp_as'          : (DEFAULT_BGP_AS,           True),
+        'bgp_route_target': (DEFAULT_BGP_ROUTE_TARGET, True),
+    })
 
     endpoint_settings_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
-    for config_rule in target.service_config.config_rules:                  # pylint: disable=no-member
-        if config_rule.WhichOneof('config_rule') != 'custom': continue
-        if config_rule.custom.resource_key != endpoint_settings_key: continue
-        json_settings = json.loads(config_rule.custom.resource_value)
-
-        if 'router_id' not in json_settings:                                # missing, add it
-            json_settings['router_id'] = router_id
-        elif json_settings['router_id'] != router_id:                       # differs, raise exception
-            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'] = 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(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.custom.resource_value = json.dumps(json_settings, sort_keys=True)
-        break
-    else:
-        # not found, add it
-        config_rule = target.service_config.config_rules.add()              # pylint: disable=no-member
-        config_rule.action = ConfigActionEnum.CONFIGACTION_SET
-        config_rule.custom.resource_key = endpoint_settings_key
-        config_rule.custom.resource_value = json.dumps({
-            'router_id': router_id,
-            '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)
+    field_updates = {}
+    if router_id      is not None: field_updates['router_id'          ] = (router_id,      True)
+    if route_dist     is not None: field_updates['route_distinguisher'] = (route_dist,     True)
+    if sub_if_index   is not None: field_updates['sub_interface_index'] = (sub_if_index,   True)
+    if cvlan_id       is not None: field_updates['vlan_id'            ] = (cvlan_id,       True)
+    if address_ip     is not None: field_updates['address_ip'         ] = (address_ip,     True)
+    if address_prefix is not None: field_updates['address_prefix'     ] = (address_prefix, True)
+    if remote_router  is not None: field_updates['remote_router'      ] = (remote_router,  True)
+    if circuit_id     is not None: field_updates['circuit_id'         ] = (circuit_id,     True)
+    update_config_rule_custom(config_rules, endpoint_settings_key, field_updates)
+
+    if len(diversity_constraints) > 0:
+        update_constraint_custom(constraints, 'diversity', diversity_constraints)
+
+    update_constraint_endpoint_location(constraints, endpoint_id, region=site_id)
+    if access_priority is not None: update_constraint_endpoint_priority(constraints, endpoint_id, access_priority)
+    if single_active or all_active:
+        # assume 1 disjoint path per endpoint/location included in service/slice
+        location_endpoints = {}
+        for constraint in constraints:
+            if constraint.WhichOneof('constraint') != 'endpoint_location': continue
+            str_endpoint_id = grpc_message_to_json_string(constraint.endpoint_location.endpoint_id)
+            str_location_id = grpc_message_to_json_string(constraint.endpoint_location.location)
+            location_endpoints.setdefault(str_location_id, set()).add(str_endpoint_id)
+        num_endpoints_per_location = {len(endpoints) for endpoints in location_endpoints.values()}
+        num_disjoint_paths = min(num_endpoints_per_location)
+        update_constraint_sla_availability(constraints, num_disjoint_paths, all_active)
 
     return target
 
 def process_list_site_network_access(
-        context_client : ContextClient, service_client : ServiceClient, slice_client : SliceClient,
-        request_data : Dict
+        context_client : ContextClient, slice_client : SliceClient, site_id : str, request_data : Dict
     ) -> Response:
 
     LOGGER.debug('Request: {:s}'.format(str(request_data)))
@@ -182,21 +126,14 @@ def process_list_site_network_access(
 
     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)
+        sna_request = process_site_network_access(context_client, site_id, site_network_access)
         LOGGER.debug('sna_request = {:s}'.format(grpc_message_to_json_string(sna_request)))
         try:
-            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))))
+            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')
         except Exception as e: # pylint: disable=broad-except
-            msg = 'Something went wrong Updating Service {:s}'
+            msg = 'Something went wrong Updating VPN {:s}'
             LOGGER.exception(msg.format(grpc_message_to_json_string(sna_request)))
             errors.append({'error': str(e)})
 
@@ -210,15 +147,13 @@ class L2VPN_SiteNetworkAccesses(Resource):
         if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
         LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
         context_client = ContextClient()
-        service_client = ServiceClient()
         slice_client = SliceClient()
-        return process_list_site_network_access(context_client, service_client, slice_client, request.json)
+        return process_list_site_network_access(context_client, slice_client, site_id, 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)))
         context_client = ContextClient()
-        service_client = ServiceClient()
         slice_client = SliceClient()
-        return process_list_site_network_access(context_client, service_client, slice_client, request.json)
+        return process_list_site_network_access(context_client, slice_client, site_id, request.json)
diff --git a/src/compute/tests/Constants.py b/src/compute/tests/Constants.py
index 640124b07fd8e5dc0dff0635175b1499544f1b2d..cb1331c7445888070c6c3d5ecef6136f9f149916 100644
--- a/src/compute/tests/Constants.py
+++ b/src/compute/tests/Constants.py
@@ -82,4 +82,4 @@ SERVICE_CONNECTION_POINTS_2 = [
     {'service_endpoint_id': 'ep-3',
         'service_endpoint_encapsulation_type': 'dot1q',
         'service_endpoint_encapsulation_info': {'vlan': 1234}},
-]
+]
\ No newline at end of file
diff --git a/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py b/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py
index b9639e8046593c1dbf4017cff963ceb7c51d0532..e1273b4e483a06df23d94bdf107005ce7585fb5e 100644
--- a/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py
+++ b/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py
@@ -33,6 +33,7 @@ the Layer 2 service.
 import requests
 import uuid
 import logging
+import copy
 #from osm_ro_plugin.sdnconn import SdnConnectorBase, SdnConnectorError
 from .sdnconn import SdnConnectorBase, SdnConnectorError
 
@@ -222,8 +223,29 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
                 http_code=response_service_creation.status_code,
             )
 
-        """Second step, create the connections and vpn attachments"""
+        self.logger.info('connection_points = {:s}'.format(str(connection_points)))
+
+        # Check if protected paths are requested
+        extended_connection_points = []
         for connection_point in connection_points:
+            extended_connection_points.append(connection_point)
+
+            connection_point_wan_info = self.search_mapp(connection_point)
+            service_mapping_info = connection_point_wan_info.get('service_mapping_info', {})
+            redundant_service_endpoint_ids = service_mapping_info.get('redundant')
+
+            if redundant_service_endpoint_ids is None: continue
+            if len(redundant_service_endpoint_ids) == 0: continue
+
+            for redundant_service_endpoint_id in redundant_service_endpoint_ids:
+                redundant_connection_point = copy.deepcopy(connection_point)
+                redundant_connection_point['service_endpoint_id'] = redundant_service_endpoint_id
+                extended_connection_points.append(redundant_connection_point)
+
+        self.logger.info('extended_connection_points = {:s}'.format(str(extended_connection_points)))
+
+        """Second step, create the connections and vpn attachments"""
+        for connection_point in extended_connection_points:
             connection_point_wan_info = self.search_mapp(connection_point)
             site_network_access = {}
             connection = {}
@@ -264,6 +286,23 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
             site_network_access["bearer"] = connection_point_wan_info[
                 "service_mapping_info"
             ]["bearer"]
+
+            access_priority = connection_point_wan_info["service_mapping_info"].get("priority")
+            if access_priority is not None:
+                availability = {}
+                availability["access-priority"] = access_priority
+                availability["single-active"] = [None]
+                site_network_access["availability"] = availability
+
+                constraint = {}
+                constraint['constraint-type'] = 'end-to-end-diverse'
+                constraint['target'] = {'all-other-accesses': [None]}
+
+                access_diversity = {}
+                access_diversity['constraints'] = {'constraint': []}
+                access_diversity['constraints']['constraint'].append(constraint)
+                site_network_access["access-diversity"] = access_diversity
+
             site_network_accesses = {}
             site_network_access_list = []
             site_network_access_list.append(site_network_access)
@@ -332,7 +371,7 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
                     self.delete_connectivity_service(vpn_service["vpn-id"])
 
                     raise SdnConnectorError(
-                        "Request no accepted",
+                        "Request not accepted",
                         http_code=response_endpoint_site_network_access_creation.status_code,
                     )
             except requests.exceptions.ConnectionError:
diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py
index 6e8cbac6a28c1b24d1999b0d8db1240905b10f2c..da907341f799def94694817242c106a913e03327 100644
--- a/src/context/client/ContextClient.py
+++ b/src/context/client/ContextClient.py
@@ -250,6 +250,13 @@ class ContextClient:
         LOGGER.debug('SetService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
+    @RETRY_DECORATOR
+    def UnsetService(self, request: Service) -> ServiceId:
+        LOGGER.debug('UnsetService request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.UnsetService(request)
+        LOGGER.debug('UnsetService 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(grpc_message_to_json_string(request)))
@@ -292,6 +299,13 @@ class ContextClient:
         LOGGER.debug('SetSlice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
+    @RETRY_DECORATOR
+    def UnsetSlice(self, request: Slice) -> SliceId:
+        LOGGER.debug('UnsetSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.UnsetSlice(request)
+        LOGGER.debug('UnsetSlice 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)))
diff --git a/src/context/service/__main__.py b/src/context/service/__main__.py
index 53754caf4f9d2621ed8a6fdfd325d42f77f44a4f..dfd0c8773b6a7d2dea7bafa12c12018d62b7cdb8 100644
--- a/src/context/service/__main__.py
+++ b/src/context/service/__main__.py
@@ -36,7 +36,7 @@ def main():
     global LOGGER # pylint: disable=global-statement
 
     log_level = get_log_level()
-    logging.basicConfig(level=log_level)
+    logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
     LOGGER = logging.getLogger(__name__)
 
     signal.signal(signal.SIGINT,  signal_handler)
diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py
index bb2a37467ce3ad451bd29f824a5092ec1ad43cee..a5f90788e4783edf1eba76cf6fe461aaa96476e6 100644
--- a/src/context/service/database/ConfigModel.py
+++ b/src/context/service/database/ConfigModel.py
@@ -116,7 +116,7 @@ def update_config(
     raw_config_rules : List[Tuple[ORM_ConfigActionEnum, str, str]]
 ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]:
 
-    str_config_key = key_to_str([db_parent_pk, config_name], separator=':')
+    str_config_key = key_to_str([config_name, db_parent_pk], separator=':')
     result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key)
     db_config, created = result
 
diff --git a/src/context/service/database/ConstraintModel.py b/src/context/service/database/ConstraintModel.py
index a35ec250d8a62a8a2534e9f27ddecac801db6eff..449dcedeeaf10686ece58607d3a5fa4f4bf6a070 100644
--- a/src/context/service/database/ConstraintModel.py
+++ b/src/context/service/database/ConstraintModel.py
@@ -54,24 +54,13 @@ class ConstraintCustomModel(Model): # pylint: disable=abstract-method
     def dump(self) -> Dict: # pylint: disable=arguments-differ
         return {'custom': {'constraint_type': self.constraint_type, 'constraint_value': self.constraint_value}}
 
-Union_ConstraintEndpoint = Union[
-    'ConstraintEndpointLocationGpsPositionModel', 'ConstraintEndpointLocationRegionModel',
-    'ConstraintEndpointPriorityModel'
-]
-def dump_endpoint_id(endpoint_constraint : Union_ConstraintEndpoint):
-    db_endpoints_pks = list(endpoint_constraint.references(EndPointModel))
-    num_endpoints = len(db_endpoints_pks)
-    if num_endpoints != 1:
-        raise Exception('Wrong number({:d}) of associated Endpoints with constraint'.format(num_endpoints))
-    db_endpoint = EndPointModel(endpoint_constraint.database, db_endpoints_pks[0])
-    return db_endpoint.dump_id()
-
 class ConstraintEndpointLocationRegionModel(Model): # pylint: disable=abstract-method
     endpoint_fk = ForeignKeyField(EndPointModel)
     region = StringField(required=True, allow_empty=False)
 
     def dump(self) -> Dict: # pylint: disable=arguments-differ
-        return {'endpoint_location': {'endpoint_id': dump_endpoint_id(self), 'region': self.region}}
+        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
+        return {'endpoint_location': {'endpoint_id': json_endpoint_id, 'location': {'region': self.region}}}
 
 class ConstraintEndpointLocationGpsPositionModel(Model): # pylint: disable=abstract-method
     endpoint_fk = ForeignKeyField(EndPointModel)
@@ -80,14 +69,16 @@ class ConstraintEndpointLocationGpsPositionModel(Model): # pylint: disable=abstr
 
     def dump(self) -> Dict: # pylint: disable=arguments-differ
         gps_position = {'latitude': self.latitude, 'longitude': self.longitude}
-        return {'endpoint_location': {'endpoint_id': dump_endpoint_id(self), 'gps_position': gps_position}}
+        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
+        return {'endpoint_location': {'endpoint_id': json_endpoint_id, 'location': {'gps_position': gps_position}}}
 
 class ConstraintEndpointPriorityModel(Model): # pylint: disable=abstract-method
     endpoint_fk = ForeignKeyField(EndPointModel)
-    priority = FloatField(required=True)
+    priority = IntegerField(required=True, min_value=0)
 
     def dump(self) -> Dict: # pylint: disable=arguments-differ
-        return {'endpoint_priority': {'endpoint_id': dump_endpoint_id(self), 'priority': self.priority}}
+        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
+        return {'endpoint_priority': {'endpoint_id': json_endpoint_id, 'priority': self.priority}}
 
 class ConstraintSlaAvailabilityModel(Model): # pylint: disable=abstract-method
     num_disjoint_paths = IntegerField(required=True, min_value=1)
@@ -240,7 +231,7 @@ def set_constraints(
     database : Database, db_parent_pk : str, constraints_name : str, grpc_constraints
 ) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
 
-    str_constraints_key = key_to_str([db_parent_pk, constraints_name], separator=':')
+    str_constraints_key = key_to_str([constraints_name, db_parent_pk], separator=':')
     result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
     db_constraints, created = result
 
diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py
index 4c8f957ecb70765cbd36032fca7bfacc27f9b5ae..71c97bf9ffc65942993dbdd966925f27aafad9ec 100644
--- a/src/context/service/grpc_server/ContextServiceServicerImpl.py
+++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py
@@ -61,6 +61,7 @@ METHOD_NAMES = [
     'ListLinkIds',       'ListLinks',       'GetLink',       'SetLink',       'RemoveLink',       'GetLinkEvents',
     'ListServiceIds',    'ListServices',    'GetService',    'SetService',    'RemoveService',    'GetServiceEvents',
     'ListSliceIds',      'ListSlices',      'GetSlice',      'SetSlice',      'RemoveSlice',      'GetSliceEvents',
+    'UnsetService',      'UnsetSlice',
 ]
 METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
@@ -277,8 +278,8 @@ class ContextServiceServicerImpl(ContextServiceServicer):
                         ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)])
 
             config_rules = grpc_config_rules_to_raw(request.device_config.config_rules)
-            running_config_result = update_config(self.database, device_uuid, 'running', config_rules)
-            db_running_config = running_config_result[0][0]
+            running_config_rules = update_config(self.database, device_uuid, 'device', config_rules)
+            db_running_config = running_config_rules[0][0]
 
             result : Tuple[DeviceModel, bool] = update_or_create_object(self.database, DeviceModel, device_uuid, {
                 'device_uuid'              : device_uuid,
@@ -319,7 +320,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
 
                 result : Tuple[EndPointModel, bool] = update_or_create_object(
                     self.database, EndPointModel, str_endpoint_key, endpoint_attributes)
-                db_endpoint, endpoint_updated = result
+                db_endpoint, endpoint_updated = result # pylint: disable=unused-variable
 
                 set_kpi_sample_types(self.database, db_endpoint, endpoint.kpi_sample_types)
 
@@ -483,12 +484,12 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             str_service_key = key_to_str([context_uuid, service_uuid])
 
             constraints_result = set_constraints(
-                self.database, str_service_key, 'constraints', request.service_constraints)
+                self.database, str_service_key, 'service', request.service_constraints)
             db_constraints = constraints_result[0][0]
 
             config_rules = grpc_config_rules_to_raw(request.service_config.config_rules)
-            running_config_result = update_config(self.database, str_service_key, 'running', config_rules)
-            db_running_config = running_config_result[0][0]
+            running_config_rules = update_config(self.database, str_service_key, 'service', config_rules)
+            db_running_config = running_config_rules[0][0]
 
             result : Tuple[ServiceModel, bool] = update_or_create_object(self.database, ServiceModel, str_service_key, {
                 'context_fk'            : db_context,
@@ -592,12 +593,12 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             str_slice_key = key_to_str([context_uuid, slice_uuid])
 
             constraints_result = set_constraints(
-                self.database, str_slice_key, 'constraints', request.slice_constraints)
+                self.database, str_slice_key, 'slice', request.slice_constraints)
             db_constraints = constraints_result[0][0]
 
             config_rules = grpc_config_rules_to_raw(request.slice_config.config_rules)
-            running_config_result = update_config(self.database, str_slice_key, 'running', config_rules)
-            db_running_config = running_config_result[0][0]
+            running_config_rules = update_config(self.database, str_slice_key, 'slice', config_rules)
+            db_running_config = running_config_rules[0][0]
 
             result : Tuple[SliceModel, bool] = update_or_create_object(self.database, SliceModel, str_slice_key, {
                 'context_fk'          : db_context,
@@ -656,6 +657,55 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             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 UnsetSlice(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])
+
+            if len(request.slice_constraints) > 0:
+                raise NotImplementedError('UnsetSlice: removal of constraints')
+            if len(request.slice_config.config_rules) > 0:
+                raise NotImplementedError('UnsetSlice: removal of config rules')
+            if len(request.slice_endpoint_ids) > 0:
+                raise NotImplementedError('UnsetSlice: removal of endpoints')
+
+            updated = False
+
+            for service_id in 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])
+                str_slice_service_key = key_to_str([str_slice_key, str_service_key], separator='--')
+                SliceServiceModel(self.database, str_slice_service_key).delete()
+                updated = True
+
+            for subslice_id in 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])
+                str_slice_subslice_key = key_to_str([str_slice_key, str_subslice_key], separator='--')
+                SliceSubSliceModel(self.database, str_slice_subslice_key).delete()
+                updated = True
+
+            event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
+            db_slice : SliceModel = get_object(self.database, SliceModel, str_slice_key)
+            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:
diff --git a/src/context/tests/Objects.py b/src/context/tests/Objects.py
index 519a0093ac2733125487ed9daf0c61e0821910d5..140cbff686eaf5b430f23ee987a9335ecb04c0f5 100644
--- a/src/context/tests/Objects.py
+++ b/src/context/tests/Objects.py
@@ -16,7 +16,7 @@ from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
 from common.proto.kpi_sample_types_pb2 import KpiSampleType
 from common.tools.object_factory.ConfigRule import json_config_rule_set
 from common.tools.object_factory.Connection import json_connection, json_connection_id
-from common.tools.object_factory.Constraint import json_constraint
+from common.tools.object_factory.Constraint import json_constraint_custom
 from common.tools.object_factory.Context import json_context, json_context_id
 from common.tools.object_factory.Device import json_device_id, json_device_packetrouter_disabled
 from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
@@ -129,8 +129,8 @@ SERVICE_R1_R2_EPIDS = [
     json_endpoint_id(DEVICE_R2_ID, 'EP100', topology_id=TOPOLOGY_ID),
 ]
 SERVICE_R1_R2_CONST = [
-    json_constraint('latency_ms', '15.2'),
-    json_constraint('jitter_us',  '1.2'),
+    json_constraint_custom('latency[ms]', '15.2'),
+    json_constraint_custom('jitter[us]',  '1.2'),
 ]
 SERVICE_R1_R2_RULES = [
     json_config_rule_set('svc/rsrc1/value', 'value7'),
@@ -149,8 +149,8 @@ SERVICE_R1_R3_EPIDS = [
     json_endpoint_id(DEVICE_R3_ID, 'EP100', topology_id=TOPOLOGY_ID),
 ]
 SERVICE_R1_R3_CONST = [
-    json_constraint('latency_ms', '5.8'),
-    json_constraint('jitter_us',  '0.1'),
+    json_constraint_custom('latency[ms]', '5.8'),
+    json_constraint_custom('jitter[us]',  '0.1'),
 ]
 SERVICE_R1_R3_RULES = [
     json_config_rule_set('svc/rsrc1/value', 'value7'),
@@ -169,8 +169,8 @@ SERVICE_R2_R3_EPIDS = [
     json_endpoint_id(DEVICE_R3_ID, 'EP100', topology_id=TOPOLOGY_ID),
 ]
 SERVICE_R2_R3_CONST = [
-    json_constraint('latency_ms', '23.1'),
-    json_constraint('jitter_us',  '3.4'),
+    json_constraint_custom('latency[ms]', '23.1'),
+    json_constraint_custom('jitter[us]',  '3.4'),
 ]
 SERVICE_R2_R3_RULES = [
     json_config_rule_set('svc/rsrc1/value', 'value7'),
diff --git a/src/device/requirements.in b/src/device/requirements.in
index 0902a65793813c4f22a1b27b83e89e085ca64a5a..2b9c199c86a580b72190a9d0e74a161e567abed2 100644
--- a/src/device/requirements.in
+++ b/src/device/requirements.in
@@ -5,13 +5,15 @@ Jinja2==3.0.3
 ncclient==0.6.13
 p4runtime==1.3.0
 paramiko==2.9.2
-python-dateutil==2.8.2
 python-json-logger==2.0.2
 pytz==2021.3
 redis==4.1.2
 requests==2.27.1
 requests-mock==1.9.3
 xmltodict==0.12.0
+tabulate
+ipaddress
+macaddress
 
 # pip's dependency resolver does not take into account installed packages.
 # p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one
diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py
index 6189816bcd35dd973e4a7da389f256bdb685a79f..9ffd028a67a34cfcce7a737a5817128126941759 100644
--- a/src/device/service/DeviceServiceServicerImpl.py
+++ b/src/device/service/DeviceServiceServicerImpl.py
@@ -223,7 +223,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
         running_config_rules = driver.GetConfig()
         running_config_rules = [
             (ORM_ConfigActionEnum.SET, config_rule[0], json.dumps(config_rule[1], sort_keys=True))
-            for config_rule in running_config_rules
+            for config_rule in running_config_rules if not isinstance(config_rule[1], Exception)
         ]
         #for running_config_rule in running_config_rules:
         #    LOGGER.info('[ConfigureDevice] running_config_rule: {:s}'.format(str(running_config_rule)))
diff --git a/src/device/service/MonitoringLoops.py b/src/device/service/MonitoringLoops.py
index 4d6d3f59147026c3104062cca0684ea9e3a304cf..18faed0d51d8d594368a0c80ef03539a9b0c4d4e 100644
--- a/src/device/service/MonitoringLoops.py
+++ b/src/device/service/MonitoringLoops.py
@@ -129,8 +129,8 @@ class MonitoringLoops:
             # 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 = 'floatVal'   # 'intVal'
-                kpi_value_field_cast = float        # int
+                kpi_value_field_name = 'int64Val'
+                kpi_value_field_cast = int
             elif isinstance(value, float):
                 kpi_value_field_name = 'floatVal'
                 kpi_value_field_cast = float
@@ -144,7 +144,7 @@ class MonitoringLoops:
             try:
                 self._monitoring_client.IncludeKpi(Kpi(**{
                     'kpi_id'   : {'kpi_id': {'uuid': db_kpi.kpi_uuid}},
-                    'timestamp': datetime.utcfromtimestamp(timestamp).isoformat() + 'Z',
+                    'timestamp': {'timestamp': timestamp},
                     'kpi_value': {kpi_value_field_name: kpi_value_field_cast(value)}
                 }))
             except: # pylint: disable=bare-except
diff --git a/src/device/service/__main__.py b/src/device/service/__main__.py
index 1f0adfa8f1dd8b3e307ed202967b1d5195171f11..5c9b41531e7bc579cbe5cc563f20b193f6bc5a90 100644
--- a/src/device/service/__main__.py
+++ b/src/device/service/__main__.py
@@ -34,7 +34,7 @@ def main():
     global LOGGER # pylint: disable=global-statement
 
     log_level = get_log_level()
-    logging.basicConfig(level=log_level)
+    logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
     logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
     logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
     logging.getLogger('monitoring-client').setLevel(logging.WARNING)
diff --git a/src/device/service/database/ContextModel.py b/src/device/service/database/ContextModel.py
index 0ca13269c52d02ea663e10be986ab28d12d8f144..a609e1ba9189f5359064e6628cba6c08d353770e 100644
--- a/src/device/service/database/ContextModel.py
+++ b/src/device/service/database/ContextModel.py
@@ -24,15 +24,15 @@ class ContextModel(Model):
     pk = PrimaryKeyField()
     context_uuid = StringField(required=True, allow_empty=False)
 
-#    def dump_id(self) -> Dict:
-#        return {'context_uuid': {'uuid': self.context_uuid}}
+    def dump_id(self) -> Dict:
+        return {'context_uuid': {'uuid': self.context_uuid}}
 
-#    def dump_topology_ids(self) -> List[Dict]:
-#        from .TopologyModel import TopologyModel # pylint: disable=import-outside-toplevel
-#        db_topology_pks = self.references(TopologyModel)
-#        return [TopologyModel(self.database, pk).dump_id() for pk,_ in db_topology_pks]
+    def dump_topology_ids(self) -> List[Dict]:
+        from .TopologyModel import TopologyModel # pylint: disable=import-outside-toplevel
+        db_topology_pks = self.references(TopologyModel)
+        return [TopologyModel(self.database, pk).dump_id() for pk,_ in db_topology_pks]
 
-#    def dump(self, include_topologies=True) -> Dict: # pylint: disable=arguments-differ
-#        result = {'context_id': self.dump_id()}
-#        if include_topologies: result['topology_ids'] = self.dump_topology_ids()
-#        return result
+    def dump(self, include_topologies=False) -> Dict: # pylint: disable=arguments-differ
+        result = {'context_id': self.dump_id()}
+        if include_topologies: result['topology_ids'] = self.dump_topology_ids()
+        return result
diff --git a/src/device/service/database/EndPointModel.py b/src/device/service/database/EndPointModel.py
index 84d0c97073481af162b1e66f7e35c93bc6e1eed5..3d4435737349809c527c80546ed412e621afcbdd 100644
--- a/src/device/service/database/EndPointModel.py
+++ b/src/device/service/database/EndPointModel.py
@@ -34,7 +34,6 @@ class EndPointModel(Model):
     device_fk = ForeignKeyField(DeviceModel)
     endpoint_uuid = StringField(required=True, allow_empty=False)
     endpoint_type = StringField()
-    resource_key = StringField(required=True, allow_empty=False)
 
     def dump_id(self) -> Dict:
         device_id = DeviceModel(self.database, self.device_fk).dump_id()
@@ -74,13 +73,7 @@ def set_endpoint_monitors(database : Database, db_endpoint : EndPointModel, grpc
     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, 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/database/TopologyModel.py b/src/device/service/database/TopologyModel.py
index a099c8adfd8bb64d94c8326c90094f39d7fe9b6b..f9e9c0b1a26fdf8faca7e1cbe0a64b582bdd4d5d 100644
--- a/src/device/service/database/TopologyModel.py
+++ b/src/device/service/database/TopologyModel.py
@@ -27,13 +27,13 @@ class TopologyModel(Model):
     context_fk = ForeignKeyField(ContextModel)
     topology_uuid = StringField(required=True, allow_empty=False)
 
-#    def dump_id(self) -> Dict:
-#        context_id = ContextModel(self.database, self.context_fk).dump_id()
-#        return {
-#            'context_id': context_id,
-#            'topology_uuid': {'uuid': self.topology_uuid},
-#        }
+    def dump_id(self) -> Dict:
+        context_id = ContextModel(self.database, self.context_fk).dump_id()
+        return {
+            'context_id': context_id,
+            'topology_uuid': {'uuid': self.topology_uuid},
+        }
 
-#    def dump(self) -> Dict:
-#        result = {'topology_id': self.dump_id()}
-#        return result
+    def dump(self) -> Dict:
+        result = {'topology_id': self.dump_id()}
+        return result
diff --git a/src/device/service/driver_api/_Driver.py b/src/device/service/driver_api/_Driver.py
index 7dbb9eddb238dcaae9d00b579a1851aacf53225d..371f4cccb4e002e4d232823e47e31f577d1a4285 100644
--- a/src/device/service/driver_api/_Driver.py
+++ b/src/device/service/driver_api/_Driver.py
@@ -15,16 +15,18 @@
 import threading
 from typing import Any, Iterator, List, Optional, Tuple, Union
 
-# Special resource names to request to the driver to retrieve the specified configuration/structural resources.
+# Special resource names to request to the driver to retrieve the specified
+# configuration/structural resources.
 # These resource names should be used with GetConfig() method.
-RESOURCE_ENDPOINTS         = '__endpoints__'
-RESOURCE_INTERFACES        = '__interfaces__'
+RESOURCE_ENDPOINTS = '__endpoints__'
+RESOURCE_INTERFACES = '__interfaces__'
 RESOURCE_NETWORK_INSTANCES = '__network_instances__'
-RESOURCE_ROUTING_POLICIES  = '__routing_policies__'
-RESOURCE_ACL               = '__acl__'
+RESOURCE_ROUTING_POLICIES = '__routing_policies__'
+RESOURCE_ACL = '__acl__'
+
 
 class _Driver:
-    def __init__(self, address : str, port : int, **settings) -> None:
+    def __init__(self, address: str, port: int, **settings) -> None:
         """ Initialize Driver.
             Parameters:
                 address : str
@@ -56,92 +58,122 @@ class _Driver:
         """ Retrieve initial configuration of entire device.
             Returns:
                 values : List[Tuple[str, Any]]
-                    List of tuples (resource key, resource value) for resource keys.
+                    List of tuples (resource key, resource value) for
+                    resource keys.
         """
         raise NotImplementedError()
 
-    def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]:
-        """ Retrieve running configuration of entire device, or selected resource keys.
+    def GetConfig(self, resource_keys: List[str] = []) -> \
+            List[Tuple[str, Union[Any, None, Exception]]]:
+        """ Retrieve running configuration of entire device or
+        selected resource keys.
             Parameters:
                 resource_keys : List[str]
                     List of keys pointing to the resources to be retrieved.
             Returns:
                 values : List[Tuple[str, Union[Any, None, Exception]]]
-                    List of tuples (resource key, resource value) for resource keys requested. If a resource is found,
-                    the appropriate value type must be retrieved. If a resource is not found, None must be retrieved as
-                    value for that resource. In case of Exception, the Exception must be retrieved as value.
+                    List of tuples (resource key, resource value) for
+                    resource keys requested. If a resource is found,
+                    the appropriate value type must be retrieved.
+                    If a resource is not found, None must be retrieved as
+                    value for that resource. In case of Exception,
+                    the Exception must be retrieved as value.
         """
         raise NotImplementedError()
 
-    def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+    def SetConfig(self, resources: List[Tuple[str, Any]]) -> \
+            List[Union[bool, Exception]]:
         """ Create/Update configuration for a list of resources.
             Parameters:
                 resources : List[Tuple[str, Any]]
-                    List of tuples, each containing a resource_key pointing the resource to be modified, and a
-                    resource_value containing the new value to be set.
+                    List of tuples, each containing a resource_key pointing the
+                    resource to be modified, and a resource_value containing
+                    the new value to be set.
             Returns:
                 results : List[Union[bool, Exception]]
-                    List of results for resource key changes requested. Return values must be in the same order than
-                    resource keys requested. If a resource is properly set, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                    List of results for resource key changes requested.
+                    Return values must be in the same order as the
+                    resource keys requested. If a resource is properly set,
+                    True must be retrieved; otherwise, the Exception that is
+                    raised during the processing must be retrieved.
         """
         raise NotImplementedError()
 
-    def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) -> \
+            List[Union[bool, Exception]]:
         """ Delete configuration for a list of resources.
             Parameters:
                 resources : List[Tuple[str, Any]]
-                    List of tuples, each containing a resource_key pointing the resource to be modified, and a
-                    resource_value containing possible additionally required values to locate the value to be removed.
+                    List of tuples, each containing a resource_key pointing the
+                    resource to be modified, and a resource_value containing
+                    possible additionally required values to locate
+                    the value to be removed.
             Returns:
-                results : List[bool]
-                    List of results for resource key deletions requested. Return values must be in the same order than
-                    resource keys requested. If a resource is properly deleted, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results : List[Union[bool, Exception]]
+                    List of results for resource key deletions requested.
+                    Return values must be in the same order as the resource keys
+                    requested. If a resource is properly deleted, True must be
+                    retrieved; otherwise, the Exception that is raised during
+                    the processing must be retrieved.
         """
         raise NotImplementedError()
 
-    def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
-        """ Subscribe to state information of entire device, or selected resources. Subscriptions are incremental.
+    def SubscribeState(self, subscriptions: List[Tuple[str, float, float]]) -> \
+            List[Union[bool, Exception]]:
+        """ Subscribe to state information of entire device or
+        selected resources. Subscriptions are incremental.
             Driver should keep track of requested resources.
             Parameters:
                 subscriptions : List[Tuple[str, float, float]]
-                    List of tuples, each containing a resource_key pointing the resource to be subscribed, a
-                    sampling_duration, and a sampling_interval (both in seconds with float representation) defining,
-                    respectively, for how long monitoring should last, and the desired monitoring interval for the
-                    resource specified.
+                    List of tuples, each containing a resource_key pointing the
+                    resource to be subscribed, a sampling_duration, and a
+                    sampling_interval (both in seconds with float
+                    representation) defining, respectively, for how long
+                    monitoring should last, and the desired monitoring interval
+                    for the resource specified.
             Returns:
-                results : List[bool]
-                    List of results for resource key subscriptions requested. Return values must be in the same order
-                    than resource keys requested. If a resource is properly subscribed, True must be retrieved;
-                    otherwise, the Exception that is raised during the processing must be retrieved.
+                results : List[Union[bool, Exception]]
+                    List of results for resource key subscriptions requested.
+                    Return values must be in the same order as the resource keys
+                    requested. If a resource is properly subscribed,
+                    True must be retrieved; otherwise, the Exception that is
+                    raised during the processing must be retrieved.
         """
         raise NotImplementedError()
 
-    def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
-        """ Unsubscribe from state information of entire device, or selected resources. Subscriptions are incremental.
+    def UnsubscribeState(self, subscriptions: List[Tuple[str, float, float]]) \
+            -> List[Union[bool, Exception]]:
+        """ Unsubscribe from state information of entire device
+        or selected resources. Subscriptions are incremental.
             Driver should keep track of requested resources.
             Parameters:
                 subscriptions : List[str]
-                    List of tuples, each containing a resource_key pointing the resource to be subscribed, a
-                    sampling_duration, and a sampling_interval (both in seconds with float representation) defining,
-                    respectively, for how long monitoring should last, and the desired monitoring interval for the
-                    resource specified.
+                    List of tuples, each containing a resource_key pointing the
+                    resource to be subscribed, a sampling_duration, and a
+                    sampling_interval (both in seconds with float
+                    representation) defining, respectively, for how long
+                    monitoring should last, and the desired monitoring interval
+                    for the resource specified.
             Returns:
                 results : List[Union[bool, Exception]]
-                    List of results for resource key unsubscriptions requested. Return values must be in the same order
-                    than resource keys requested. If a resource is properly unsubscribed, True must be retrieved;
-                    otherwise, the Exception that is raised during the processing must be retrieved.
+                    List of results for resource key un-subscriptions requested.
+                    Return values must be in the same order as the resource keys
+                    requested. If a resource is properly unsubscribed,
+                    True must be retrieved; otherwise, the Exception that is
+                    raised during the processing must be retrieved.
         """
         raise NotImplementedError()
 
     def GetState(
         self, blocking=False, terminate : Optional[threading.Event] = None
     ) -> Iterator[Tuple[float, str, Any]]:
-        """ Retrieve last collected values for subscribed resources. Operates as a generator, so this method should be
-            called once and will block until values are available. When values are available, it should yield each of
-            them and block again until new values are available. When the driver is destroyed, GetState() can return
-            instead of yield to terminate the loop. Terminate enables to request interruption of the generation.
+        """ Retrieve last collected values for subscribed resources.
+        Operates as a generator, so this method should be called once and will
+        block until values are available. When values are available,
+        it should yield each of them and block again until new values are
+        available. When the driver is destroyed, GetState() can return instead
+        of yield to terminate the loop.
+        Terminate enables to request interruption of the generation.
             Examples:
                 # keep looping waiting for extra samples (generator loop)
                 terminate = threading.Event()
@@ -161,20 +193,27 @@ class _Driver:
                     if i == 10: terminate.set()
             Parameters:
                 blocking : bool
-                    Select the driver behaviour. In both cases, the driver will first retrieve the samples accumulated
-                    and available in the internal queue. Then, if blocking, the driver does not terminate the loop and
-                    waits for additional samples to come, thus behaving as a generator. If non-blocking, the driver
-                    terminates the loop and returns. Non-blocking behaviour can be used for periodically polling the
-                    driver, while blocking can be used when a separate thread is in charge of collecting the samples
-                    produced by the driver.
+                    Select the driver behaviour. In both cases, the driver will
+                    first retrieve the samples accumulated and available in the
+                    internal queue. Then, if blocking, the driver does not
+                    terminate the loop and waits for additional samples to come,
+                    thus behaving as a generator. If non-blocking, the driver
+                    terminates the loop and returns. Non-blocking behaviour can
+                    be used for periodically polling the driver, while blocking
+                    can be used when a separate thread is in charge of
+                    collecting the samples produced by the driver.
                 terminate : threading.Event
-                    Signals the interruption of the GetState method as soon as possible.
+                    Signals the interruption of the GetState method as soon as
+                    possible.
             Returns:
                 results : Iterator[Tuple[float, str, Any]]
-                    Sequences of state sample. Each State sample contains a float Unix-like timestamps of the samples in
-                    seconds with up to microsecond resolution, the resource_key of the sample, and its resource_value.
-                    Only resources with an active subscription must be retrieved. Interval and duration of the sampling
-                    process are specified when creating the subscription using method SubscribeState(). Order of values
-                    yielded is arbitrary.
+                    Sequences of state sample. Each State sample contains a
+                    float Unix-like timestamps of the samples in seconds with up
+                    to microsecond resolution, the resource_key of the sample,
+                    and its resource_value.
+                    Only resources with an active subscription must be
+                    retrieved. Interval and duration of the sampling process are
+                    specified when creating the subscription using method
+                    SubscribeState(). Order of values yielded is arbitrary.
         """
         raise NotImplementedError()
diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py
index e4f9c8d54f51c93459295adb2704056b216d1867..95509f7e123760a49d2b3e891abc5c2f2839d660 100644
--- a/src/device/service/drivers/__init__.py
+++ b/src/device/service/drivers/__init__.py
@@ -12,16 +12,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import os
 from common.DeviceTypes import DeviceTypeEnum
 from ..driver_api.FilterFields import FilterFieldEnum, ORM_DeviceDriverEnum
-from .emulated.EmulatedDriver import EmulatedDriver
-from .openconfig.OpenConfigDriver import OpenConfigDriver
-from .transport_api.TransportApiDriver import TransportApiDriver
-from .xr.XrDriver import XrDriver
-from .p4.p4_driver import P4Driver
-from .microwave.IETFApiDriver import IETFApiDriver
 
-DRIVERS = [
+TRUE_VALUES = {'T', 'TRUE', 'YES', '1'}
+DEVICE_EMULATED_ONLY = os.environ.get('DEVICE_EMULATED_ONLY')
+LOAD_ALL_DEVICE_DRIVERS = (DEVICE_EMULATED_ONLY is None) or (DEVICE_EMULATED_ONLY.upper() not in TRUE_VALUES)
+
+DRIVERS = []
+
+from .emulated.EmulatedDriver import EmulatedDriver # pylint: disable=wrong-import-position
+DRIVERS.append(
     (EmulatedDriver, [
         {
             # Driver==unspecified & no device type specified => use Emulated
@@ -30,7 +32,7 @@ DRIVERS = [
         {
             # Emulated OLS/Packet Router, specifying Undefined/OpenConfig/TAPI Driver => use EmulatedDriver
             FilterFieldEnum.DEVICE_TYPE: [
-                DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM,
+                DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM,
                 DeviceTypeEnum.EMULATED_PACKET_ROUTER,
             ],
             FilterFieldEnum.DRIVER     : [
@@ -39,39 +41,58 @@ DRIVERS = [
                 ORM_DeviceDriverEnum.TRANSPORT_API
             ],
         }
-    ]),
-    (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,
-        }
-    ]),
-    (IETFApiDriver, [
-        {
-            FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.MICROVAWE_RADIO_SYSTEM,
-            FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.IETF_NETWORK_TOPOLOGY,
-        }
-    ]),
-    (XrDriver, [
-        {
-            # Close enough, it does optical switching
-            FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.XR_CONSTELLATION,
-            FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.XR,
-        }
-    ]),
-]
+    ]))
+
+if LOAD_ALL_DEVICE_DRIVERS:
+    from .openconfig.OpenConfigDriver import OpenConfigDriver # pylint: disable=wrong-import-position
+    DRIVERS.append(
+        (OpenConfigDriver, [
+            {
+                # Real Packet Router, specifying OpenConfig Driver => use OpenConfigDriver
+                FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.PACKET_ROUTER,
+                FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.OPENCONFIG,
+            }
+        ]))
+
+if LOAD_ALL_DEVICE_DRIVERS:
+    from .transport_api.TransportApiDriver import TransportApiDriver # pylint: disable=wrong-import-position
+    DRIVERS.append(
+        (TransportApiDriver, [
+            {
+                # Real OLS, specifying TAPI Driver => use TransportApiDriver
+                FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPEN_LINE_SYSTEM,
+                FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.TRANSPORT_API,
+            }
+        ]))
+
+if LOAD_ALL_DEVICE_DRIVERS:
+    from .p4.p4_driver import P4Driver # pylint: disable=wrong-import-position
+    DRIVERS.append(
+        (P4Driver, [
+            {
+                # Real P4 Switch, specifying P4 Driver => use P4Driver
+                FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.P4_SWITCH,
+                FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.P4,
+            }
+        ]))
+
+if LOAD_ALL_DEVICE_DRIVERS:
+    from .microwave.IETFApiDriver import IETFApiDriver # pylint: disable=wrong-import-position
+    DRIVERS.append(
+        (IETFApiDriver, [
+            {
+                FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.MICROVAWE_RADIO_SYSTEM,
+                FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.IETF_NETWORK_TOPOLOGY,
+            }
+        ]))
+
+if LOAD_ALL_DEVICE_DRIVERS:
+    from .xr.XrDriver import XrDriver # pylint: disable=wrong-import-position
+    DRIVERS.append(
+        (XrDriver, [
+            {
+                # Close enough, it does optical switching
+                FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.XR_CONSTELLATION,
+                FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.XR,
+            }
+        ]))
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index dd41096ec25fb74f1b1b855c98f90e09fee33194..9342e650b9fadb21fa1b65fb951a08ae6f066a3c 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -61,11 +61,13 @@ class NetconfSessionHandler:
         self.__port = int(port)
         self.__username       = settings.get('username')
         self.__password       = settings.get('password')
+        self.__vendor         = settings.get('vendor')
         self.__key_filename   = settings.get('key_filename')
         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.__commit_per_delete  = settings.get('delete_rule', False)
         self.__device_params  = settings.get('device_params', {})
         self.__manager_params = settings.get('manager_params', {})
         self.__nc_params      = settings.get('nc_params', {})
@@ -90,6 +92,12 @@ class NetconfSessionHandler:
     @property
     def use_candidate(self): return self.__candidate_supported and not self.__force_running
 
+    @property
+    def commit_per_rule(self): return self.__commit_per_delete 
+
+    @property
+    def vendor(self): return self.__vendor
+
     @RETRY_DECORATOR
     def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin
         with self.__lock:
@@ -181,8 +189,9 @@ def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples :
         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
+    netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, commit_per_rule= 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)))
@@ -195,13 +204,16 @@ def edit_config(
             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)
+            str_config_message = compose_config(
+                resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor)
             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)
+            if commit_per_rule:
+                netconf_handler.commit()
             results[i] = True
         except Exception as e: # pylint: disable=broad-except
             str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
@@ -278,12 +290,15 @@ 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')
-                    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
+                    if self.__netconf_handler.commit_per_rule:
+                           results = edit_config(self.__netconf_handler, resources, target='candidate', commit_per_rule= True)
+                    else:
+                        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
@@ -294,12 +309,15 @@ 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)
-                    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
+                    if self.__netconf_handler.commit_per_rule:
+                           results = edit_config(self.__netconf_handler, resources, target='candidate', delete=True, commit_per_rule= True)
+                    else:
+                        results = edit_config(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)
         return results
diff --git a/src/device/service/drivers/openconfig/templates/EndPoints.py b/src/device/service/drivers/openconfig/templates/EndPoints.py
index c11b1669d5b4cf3ca47986817ded28f75ae8358f..718a02d193531924bef863f5ccd2cbb999388dbd 100644
--- a/src/device/service/drivers/openconfig/templates/EndPoints.py
+++ b/src/device/service/drivers/openconfig/templates/EndPoints.py
@@ -20,7 +20,7 @@ from .Tools import add_value_from_collection, add_value_from_tag
 
 LOGGER = logging.getLogger(__name__)
 
-XPATH_PORTS = "//ocp:components/ocp:component/ocp:state[ocp:type='PORT']/.."
+XPATH_PORTS = "//ocp:components/ocp:component"
 XPATH_IFACE_COUNTER = "//oci:interfaces/oci:interface[oci:name='{:s}']/state/counters/{:s}"
 
 def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
@@ -28,6 +28,13 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
     for xml_component in xml_data.xpath(XPATH_PORTS, namespaces=NAMESPACES):
         #LOGGER.info('xml_component = {:s}'.format(str(ET.tostring(xml_component))))
 
+        component_type = xml_component.find('ocp:state/ocp:type', namespaces=NAMESPACES)
+        if component_type is None or component_type.text is None: continue
+        component_type = component_type.text
+        if component_type not in {'PORT', 'oc-platform-types:PORT'}: continue
+
+        LOGGER.info('PORT xml_component = {:s}'.format(str(ET.tostring(xml_component))))
+
         endpoint = {}
 
         component_name = xml_component.find('ocp:name', namespaces=NAMESPACES)
diff --git a/src/device/service/drivers/openconfig/templates/Interfaces.py b/src/device/service/drivers/openconfig/templates/Interfaces.py
index 33f977524c6f65655fbe17f6d2d95a7cfc223967..3f5b104f2de01137c2424e776dc60b8416088de6 100644
--- a/src/device/service/drivers/openconfig/templates/Interfaces.py
+++ b/src/device/service/drivers/openconfig/templates/Interfaces.py
@@ -37,6 +37,10 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         #interface_type = xml_interface.find('oci:config/oci:type', namespaces=NAMESPACES)
         #add_value_from_tag(interface, 'type', interface_type)
 
+        interface_type = xml_interface.find('oci:config/oci:type', namespaces=NAMESPACES)
+        interface_type.text = interface_type.text.replace('ianaift:','')
+        add_value_from_tag(interface, 'type', interface_type)
+
         interface_mtu = xml_interface.find('oci:config/oci:mtu', namespaces=NAMESPACES)
         add_value_from_tag(interface, 'mtu', interface_mtu, cast=int)
 
@@ -49,12 +53,15 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
             subinterface = {}
 
             add_value_from_tag(subinterface, 'name', interface_name)
+            add_value_from_tag(subinterface, 'mtu', interface_mtu)
+            add_value_from_tag(subinterface, 'type', interface_type)
+
 
             subinterface_index = xml_subinterface.find('oci:index', namespaces=NAMESPACES)
             if subinterface_index is None or subinterface_index.text is None: continue
             add_value_from_tag(subinterface, 'index', subinterface_index, cast=int)
 
-            vlan_id = xml_subinterface.find('ocv:vlan/ocv:config/ocv:vlan-id', namespaces=NAMESPACES)
+            vlan_id = xml_subinterface.find('ocv:vlan/ocv:match/ocv:single-tagged/ocv:config/ocv:vlan-id', namespaces=NAMESPACES)
             add_value_from_tag(subinterface, 'vlan_id', vlan_id, cast=int)
 
             # TODO: implement support for multiple IP addresses per subinterface
diff --git a/src/device/service/drivers/openconfig/templates/NetworkInstances.py b/src/device/service/drivers/openconfig/templates/NetworkInstances.py
index b091a0d206195a6c2ce94008628071cd9e30944f..8399402fa76b8b6b00829493cc8ebd28fd6018f4 100644
--- a/src/device/service/drivers/openconfig/templates/NetworkInstances.py
+++ b/src/device/service/drivers/openconfig/templates/NetworkInstances.py
@@ -27,6 +27,9 @@ 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"
 
+XPATH_NI_CPOINTS          = ".//ocni:connection-points/ocni:connection-point"
+XPATH_NI_CPOINTS_ENDPOINT = ".//ocni:endpoints/ocni:endpoint/ocni:remote/ocni:config"
+
 def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
     response = []
     for xml_network_instance in xml_data.xpath(XPATH_NETWORK_INSTANCES, namespaces=NAMESPACES):
@@ -39,10 +42,11 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         add_value_from_tag(network_instance, 'name', ni_name)
 
         ni_type = xml_network_instance.find('ocni:config/ocni:type', namespaces=NAMESPACES)
+        ni_type.text = ni_type.text.replace('oc-ni-types:','')
         add_value_from_tag(network_instance, 'type', ni_type)
 
-        #ni_router_id = xml_network_instance.find('ocni:config/ocni:router-id', namespaces=NAMESPACES)
-        #add_value_from_tag(network_instance, 'router_id', ni_router_id)
+        ni_router_id = xml_network_instance.find('ocni:config/ocni:router-id', namespaces=NAMESPACES)
+        add_value_from_tag(network_instance, 'router_id', ni_router_id)
 
         ni_route_dist = xml_network_instance.find('ocni:config/ocni:route-distinguisher', namespaces=NAMESPACES)
         add_value_from_tag(network_instance, 'route_distinguisher', ni_route_dist)
@@ -53,6 +57,20 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         if len(network_instance) == 0: continue
         response.append(('/network_instance[{:s}]'.format(network_instance['name']), network_instance))
 
+        for xml_cpoints in xml_network_instance.xpath(XPATH_NI_PROTOCOLS, namespaces=NAMESPACES):
+            cpoint = {}
+            add_value_from_tag(cpoint, 'name', ni_name)
+
+            connection_point = xml_cpoints.find('ocni:connection-point-id', namespaces=NAMESPACES)
+            add_value_from_tag(cpoint, 'connection_point', connection_point)
+
+            for xml_endpoint in xml_cpoints.xpath(XPATH_NI_CPOINTS_ENDPOINT, namespaces=NAMESPACES):
+                remote_system = xml_endpoint.find('ocni:remote-system', namespaces=NAMESPACES)
+                add_value_from_tag(cpoint, 'remote_system', remote_system)
+
+                VC_ID = xml_endpoint.find('ocni:virtual-circuit-identifier', namespaces=NAMESPACES)
+                add_value_from_tag(cpoint, 'VC_ID', VC_ID)
+
         for xml_protocol in xml_network_instance.xpath(XPATH_NI_PROTOCOLS, namespaces=NAMESPACES):
             #LOGGER.info('xml_protocol = {:s}'.format(str(ET.tostring(xml_protocol))))
 
@@ -71,6 +89,8 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
             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)
+                bgp_id = xml_protocol.find('ocni:bgp/ocni:global/ocni:config/ocni:router-id', namespaces=NAMESPACES)
+                add_value_from_tag(protocol, 'router_id', bgp_id)
 
             resource_key = '/network_instance[{:s}]/protocols[{:s}]'.format(
                 network_instance['name'], protocol['identifier'])
@@ -94,7 +114,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
             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)
+            default_import_policy = xml_table_connection.find('ocni:config/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(
@@ -125,4 +145,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
                     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
index 369732de3fe58c52a2e9ab2227899160d091ff68..068ca5430d9135e784dbe9a07f80d81472cbf5cc 100644
--- a/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
+++ b/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
@@ -74,7 +74,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         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)
+        ext_community_member = xml_bgp_ext_community_set.find('ocbp:config/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)
 
diff --git a/src/device/service/drivers/openconfig/templates/__init__.py b/src/device/service/drivers/openconfig/templates/__init__.py
index 901f5cf0291dca1bda155e20abd16db5989df7dc..5e77b25fe3206407db9427085de70b95342d370a 100644
--- a/src/device/service/drivers/openconfig/templates/__init__.py
+++ b/src/device/service/drivers/openconfig/templates/__init__.py
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 import json, logging, lxml.etree as ET, re
-from typing import Any, Dict
+from typing import Any, Dict, Optional
 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)
@@ -77,9 +77,11 @@ def parse(resource_key : str, xml_data : ET.Element):
     if parser is None: return [(resource_key, xml_data)]
     return parser(xml_data)
 
-def compose_config(resource_key : str, resource_value : str, delete : bool = False) -> str:
+def compose_config(
+    resource_key : str, resource_value : str, delete : bool = False, vendor : Optional[str] = None
+) -> str:
     template_name = '{:s}/edit_config.xml'.format(RE_REMOVE_FILTERS.sub('', resource_key))
     template = JINJA_ENV.get_template(template_name)
     data : Dict[str, Any] = json.loads(resource_value)
     operation = 'delete' if delete else 'merge'
-    return '<config>{:s}</config>'.format(template.render(**data, operation=operation).strip())
+    return '<config>{:s}</config>'.format(template.render(**data, operation=operation, vendor=vendor).strip())
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
index fac259b6fdcd3cbded93088ddc6335ea2bfe5f69..2769e8b2e9f81326332ae175f915432b7337f24c 100644
--- 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
@@ -13,6 +13,16 @@
           <config>
             <sequence-id>{{sequence_id}}</sequence-id>
           </config>
+          {% if operation is not defined or operation != 'delete' %}
+          {% if type=='ACL_L2' %}
+          <l2>
+            <config>
+              {% if source_address is defined %}<source-mac>{{source_address}}</source-mac>{% endif%}
+              {% if destination_address is defined %}<destination-mac>{{destination_address}}</destination-mac>{% endif%}
+            </config>
+          </l2>
+          {% endif%}
+          {% if type=='ACL_IPV4' %}
           <ipv4>
             <config>
               {% if source_address is defined %}<source-address>{{source_address}}</source-address>{% endif%}
@@ -29,12 +39,26 @@
               {% if tcp_flags is defined %}<tcp-flags>{{tcp_flags}}</tcp-flags>{% endif%}
             </config>
           </transport>
+         {% endif%}
+         {% if type=='ACL_IPV6' %}
+          <ipv6>
+            <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>
+          </ipv6>
+         {% endif%}
+          
           <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>
+          {% endif%}
         </acl-entry>
       </acl-entries>
     </acl-set>
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
index d987b0cc4b40298533f140f71af83c6fad884020..b070b305a505890c51f3751d2b83eb415ae4aa43 100644
--- 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
@@ -1,18 +1,21 @@
 <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 %}>
+    <interface {% if operation is defined %}{% if all is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %} {% endif %}>
       <id>{{id}}</id>
       <config>
         <id>{{id}}</id>
       </config>
+      {% if interface is defined %}
       <interface-ref>
         <config>
           <interface>{{interface}}</interface>
           {% if subinterface is defined %}<subinterface>{{subinterface}}</subinterface>{% endif%}
         </config>
       </interface-ref>
+      {% endif%}
+      {% if set_name_egress is defined %}
       <egress-acl-sets>
-        <egress-acl-set>
+        <egress-acl-set {% if operation is defined %}{% if egress is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %} {% endif %}>>
           <set-name>{{set_name_egress}}</set-name>
           <type>{{type_egress}}</type>
           <config>
@@ -21,6 +24,7 @@
           </config>
         </egress-acl-set>
       </egress-acl-sets>
+      {% endif%}
     </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
index 144a03c55477e532379541be5443063fe3aa2f10..d1f18efb26bc1316354c2bb26623cb36f7dc0be6 100644
--- 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
@@ -1,18 +1,21 @@
 <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 %}>
+    <interface {% if operation is defined %}{% if all is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %} {% endif %}>
       <id>{{id}}</id>
       <config>
         <id>{{id}}</id>
       </config>
+      {% if interface is defined %}
       <interface-ref>
         <config>
           <interface>{{interface}}</interface>
           {% if subinterface is defined %}<subinterface>{{subinterface}}</subinterface>{% endif%}
         </config>
       </interface-ref>
+      {% endif%}
+      {% if set_name_ingress is defined %}
       <ingress-acl-sets>
-        <ingress-acl-set>
+        <ingress-acl-set {% if operation is defined %}{% if ingress is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %} {% endif %}>
           <set-name>{{set_name_ingress}}</set-name>
           <type>{{type_ingress}}</type>
           <config>
@@ -21,6 +24,7 @@
           </config>
         </ingress-acl-set>
       </ingress-acl-sets>
+      {% endif%}
     </interface>
   </interfaces>
 </acl>
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 ff15d1d682ea910208237c32adcc93029fb036d8..4bc53ff1ddfbebbdcef2a0b4c37770210726676b 100644
--- a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml
+++ b/src/device/service/drivers/openconfig/templates/interface/edit_config.xml
@@ -1,14 +1,12 @@
 <interfaces xmlns="http://openconfig.net/yang/interfaces">
-    <interface{% if operation is defined and operation != 'delete' %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+    <interface{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
         <name>{{name}}</name>
+        {% if operation is defined and 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/interface/subinterface/edit_config.xml b/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml
index d266f819c41355ba8a30086415f2bba3b68f1f3d..1bdb8efbff495f04ee90dadaffaa7412332531b7 100644
--- a/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml
+++ b/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml
@@ -1,35 +1,46 @@
-<interfaces xmlns="http://openconfig.net/yang/interfaces">
+<interfaces xmlns="http://openconfig.net/yang/interfaces" 
+            xmlns:oc-ip="http://openconfig.net/yang/interfaces/ip" >
     <interface>
         <name>{{name}}</name>
-        {% if operation is not defined or operation != 'delete' %}
         <config>
             <name>{{name}}</name>
+            <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:{{type}}</type>
+            {% if mtu is defined %}<mtu>{{mtu}}</mtu>{% endif%}
+            <enabled>true</enabled>
         </config>
-        {% endif %}
         <subinterfaces>
-            <subinterface{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+            <subinterface>
                 <index>{{index}}</index>
-                {% if operation is not defined or operation != 'delete' %}
                 <config>
                     <index>{{index}}</index>
-                    <enabled>true</enabled>
+                    <description>{{description}}</description>
+                    {% if vendor=="ADVA" and vlan_id is not defined %}
+                    <untagged-allowed xmlns="http://www.advaoptical.com/cim/adva-dnos-oc-interfaces">true</untagged-allowed>
+                    {% endif%}
                 </config>
+                {% if vlan_id is defined %}
                 <vlan xmlns="http://openconfig.net/yang/vlan">
-                    <config>
-                        <vlan-id>{{vlan_id}}</vlan-id>
-                    </config>
-                </vlan>
-                <ipv4 xmlns="http://openconfig.net/yang/interfaces/ip">
-                    <addresses>
-                        <address>
-                            <ip>{{address_ip}}</ip>
+                    <match>
+                        <single-tagged>
                             <config>
-                                <ip>{{address_ip}}</ip>
-                                <prefix-length>{{address_prefix}}</prefix-length>
+                                <vlan-id>{{vlan_id}}</vlan-id>
                             </config>
-                        </address>
-                    </addresses>
-                </ipv4>
+                        </single-tagged>
+                    </match>
+                </vlan>
+                {% endif %}
+                {% if address_ip is defined %}
+                <oc-ip:ipv4>
+                    <oc-ip:addresses>
+                        <oc-ip:address>
+                            <oc-ip:ip>{{address_ip}}</oc-ip:ip>
+                            <oc-ip:config>
+                                <oc-ip:ip>{{address_ip}}</oc-ip:ip>
+                                <oc-ip:prefix-length>{{address_prefix}}</oc-ip:prefix-length>
+                            </oc-ip:config>
+                        </oc-ip:address>
+                    </oc-ip:addresses>
+                </oc-ip:ipv4>
                 {% endif %}
             </subinterface>
         </subinterfaces>
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/connection_point/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/connection_point/edit_config.xml
new file mode 100644
index 0000000000000000000000000000000000000000..60272e5fba4dd87c9bc48ef596197c2508b75e59
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/network_instance/connection_point/edit_config.xml
@@ -0,0 +1,29 @@
+<network-instances xmlns="http://openconfig.net/yang/network-instance">
+    <network-instance>
+        <name>{{name}}</name>
+        <connection-points>
+            <connection-point>
+                <connection-point-id>{{connection_point}}</connection-point-id>
+                <config>
+                    <connection-point-id>{{connection_point}}</connection-point-id>
+                </config>
+                <endpoints>
+                    <endpoint>
+                        <endpoint-id>{{connection_point}}</endpoint-id>
+                        <config>
+                            <endpoint-id>{{connection_point}}</endpoint-id>
+                            <precedence>1</precedence>
+                            <type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:REMOTE</type>
+                        </config>
+                        <remote>
+                            <config>
+                                <virtual-circuit-identifier>{{VC_ID}}</virtual-circuit-identifier>
+                                <remote-system>{{remote_system}}</remote-system>
+                            </config>
+                        </remote>
+                    </endpoint>
+                </endpoints>
+            </connection-point>
+        </connection-points>
+    </network-instance>
+</network-instances>
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 9362c09c6cfebcd1f83b05002f58eda51724b911..17b07df7233e94f16923c5da49eef2b8b5ccda82 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
@@ -5,7 +5,8 @@
         <config>
             <name>{{name}}</name>
             <type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:{{type}}</type>
-            <description>{{description}}</description>
+            {% if type=='L3VRF' %}
+            {% if description is defined %}<description>{{description}}</description>{% endif %}
             {% if router_id is defined %}<router-id>{{router_id}}</router-id>{% endif %}
             <route-distinguisher>{{route_distinguisher}}</route-distinguisher>
             <enabled>true</enabled>
@@ -13,8 +14,29 @@
         <encapsulation>
             <config>
                 <encapsulation-type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:MPLS</encapsulation-type>
+                <label-allocation-mode xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:INSTANCE_LABEL</label-allocation-mode>
             </config>
         </encapsulation>
+            {% endif %}
+            {% if type=='L2VSI' %}
+            {% if description is defined %}<description>{{description}}</description>{% endif %}
+            <enabled>true</enabled>
+            <mtu>1500</mtu>
+        </config>
+        <encapsulation>
+            <config>
+                <encapsulation-type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:MPLS</encapsulation-type>
+            </config>
+        </encapsulation>
+        <fdb>
+            <config>
+                <mac-learning>true</mac-learning>
+                <maximum-entries>1000</maximum-entries>
+                <mac-aging-time>300</mac-aging-time>
+            </config>
+        </fdb>
+            {% endif %}
+
         {% endif %}
     </network-instance>
 </network-instances>
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml
index d5c33d31a6d671216db55c0eded94dc15a56bec8..bf8c0c0770f9344fbed16f3a6b09f7fa99a978ef 100644
--- a/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml
+++ b/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml
@@ -2,15 +2,13 @@
     <network-instance>
         <name>{{name}}</name>
         <interfaces>
-            <interface{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+            <interface>
                 <id>{{id}}</id>
-                {% if operation is not defined or operation != 'delete' %}
                 <config>
                     <id>{{id}}</id>
                     <interface>{{interface}}</interface>
                     <subinterface>{{subinterface}}</subinterface>
                 </config>
-                {% endif %}
             </interface>
         </interfaces>
     </network-instance>
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
index da05d0467605e6cec0c3448cc325ff60dfc7cfc9..c9c068e480c0569cfe5f97b78b28fbe03e2595f8 100644
--- 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
@@ -3,19 +3,19 @@
         <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>
+                <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{identifier}}</identifier>
                 <name>{{protocol_name}}</name>
                 {% if operation is not defined or operation != 'delete' %}
                 <config>
-                    <identifier>{{identifier}}</identifier>
+                    <identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{identifier}}</identifier>
                     <name>{{protocol_name}}</name>
-                    <enabled>true</enabled>
                 </config>
                 {% if identifier=='BGP' %}
                 <bgp>
                     <global>
                         <config>
                             <as>{{as}}</as>
+                            <router-id>{{router_id}}</router-id>
                         </config>
                     </global>
                 </bgp>
@@ -23,5 +23,18 @@
                 {% endif %}
             </protocol>
         </protocols>
+        {% if operation is not defined or operation != 'delete' %}
+
+        <tables>
+            <table>
+                <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{identifier}}</protocol>
+                <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
+                <config>
+                    <protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{identifier}}</protocol>
+                    <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
+                </config>
+            </table>
+        </tables>
+        {% endif %}
     </network-instance>
 </network-instances>
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
index df64606ae5ab434e5e3453f7294db02bb749bdce..6843c2dcbd306b149a4168565447d11174eceadc 100644
--- 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
@@ -5,7 +5,10 @@
                 <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 %}
+                        <config>
+                            <ext-community-set-name>{{ext_community_set_name}}</ext-community-set-name>
+                            <ext-community-member>{{ext_community_member}}</ext-community-member>
+                        </config>
                     {% endif %}
                 </ext-community-set>
             </ext-community-sets>
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
index 711067f424b68da0e69913ce01f5133c5cbbfe02..eda2d99c9f6299f7345767db8bed8e8cc58284ae 100644
--- 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
@@ -1,8 +1,11 @@
-{% if operation is not defined or operation != 'delete' %}
 <routing-policy xmlns="http://openconfig.net/yang/routing-policy">
     <policy-definitions>
-        <policy-definition>
+        <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>
             <statements>
                 <statement>
                     <name>{{statement_name}}</name>
@@ -10,11 +13,13 @@
                         <name>{{statement_name}}</name>
                     </config>
                     <conditions>
+                         <config>
+                            <install-protocol-eq xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</install-protocol-eq>
+                        </config>
                         <bgp-conditions xmlns="http://openconfig.net/yang/bgp-policy">
-                            <match-ext-community-set>
+                             <config>
                                 <ext-community-set>{{ext_community_set_name}}</ext-community-set>
-                                <match-set-options>{{match_set_options}}</match-set-options>
-                            </match-ext-community-set>
+                            </config>
                         </bgp-conditions>
                     </conditions>
                     <actions>
@@ -24,7 +29,7 @@
                     </actions>
                 </statement>
             </statements>
+            {% endif %}
         </policy-definition>
     </policy-definitions>
 </routing-policy>
-{% endif %}
diff --git a/src/device/service/drivers/p4/__init__.py b/src/device/service/drivers/p4/__init__.py
index 70a33251242c51f49140e596b8208a19dd5245f7..9953c820575d42fa88351cc8de022d880ba96e6a 100644
--- a/src/device/service/drivers/p4/__init__.py
+++ b/src/device/service/drivers/p4/__init__.py
@@ -11,4 +11,3 @@
 # WITHOUT 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/device/service/drivers/p4/p4_client.py b/src/device/service/drivers/p4/p4_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..600d08880c7e8a1d6a7238e60d66a87d7167bd8c
--- /dev/null
+++ b/src/device/service/drivers/p4/p4_client.py
@@ -0,0 +1,607 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+P4Runtime client.
+"""
+
+import logging
+import queue
+import sys
+import enum
+import threading
+from functools import wraps
+from typing import NamedTuple
+import grpc
+import google.protobuf.text_format
+from google.rpc import status_pb2, code_pb2
+
+from p4.v1 import p4runtime_pb2
+from p4.v1 import p4runtime_pb2_grpc
+
+STREAM_ATTR_ARBITRATION = "arbitration"
+STREAM_ATTR_PACKET = "packet"
+STREAM_ATTR_DIGEST = "digest"
+STREAM_ATTR_IDLE_NOT = "idle_timeout_notification"
+STREAM_ATTR_UNKNOWN = "unknown"
+
+LOGGER = logging.getLogger(__name__)
+
+
+class P4RuntimeErrorFormatException(Exception):
+    """
+    P4Runtime error format exception.
+    """
+
+
+# Used to iterate over the p4.Error messages in a gRPC error Status object
+class P4RuntimeErrorIterator:
+    """
+    P4Runtime error iterator.
+
+    Attributes
+    ----------
+    grpc_error : object
+        gRPC error
+    """
+
+    def __init__(self, grpc_error):
+        assert grpc_error.code() == grpc.StatusCode.UNKNOWN
+        self.grpc_error = grpc_error
+
+        error = None
+        # The gRPC Python package does not have a convenient way to access the
+        # binary details for the error: they are treated as trailing metadata.
+        for meta in self.grpc_error.trailing_metadata():
+            if meta[0] == "grpc-status-details-bin":
+                error = status_pb2.Status()
+                error.ParseFromString(meta[1])
+                break
+        if error is None:
+            raise P4RuntimeErrorFormatException("No binary details field")
+
+        if len(error.details) == 0:
+            raise P4RuntimeErrorFormatException(
+                "Binary details field has empty Any details repeated field")
+        self.errors = error.details
+        self.idx = 0
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        while self.idx < len(self.errors):
+            p4_error = p4runtime_pb2.Error()
+            one_error_any = self.errors[self.idx]
+            if not one_error_any.Unpack(p4_error):
+                raise P4RuntimeErrorFormatException(
+                    "Cannot convert Any message to p4.Error")
+            if p4_error.canonical_code == code_pb2.OK:
+                continue
+            val = self.idx, p4_error
+            self.idx += 1
+            return val
+        raise StopIteration
+
+
+class P4RuntimeWriteException(Exception):
+    """
+    P4Runtime write exception handler.
+
+    Attributes
+    ----------
+    grpc_error : object
+        gRPC error
+    """
+
+    def __init__(self, grpc_error):
+        assert grpc_error.code() == grpc.StatusCode.UNKNOWN
+        super().__init__()
+        self.errors = []
+        try:
+            error_iterator = P4RuntimeErrorIterator(grpc_error)
+            for error_tuple in error_iterator:
+                self.errors.append(error_tuple)
+        except P4RuntimeErrorFormatException as ex:
+            raise P4RuntimeException(grpc_error) from ex
+
+    def __str__(self):
+        message = "Error(s) during Write:\n"
+        for idx, p4_error in self.errors:
+            code_name = code_pb2._CODE.values_by_number[
+                p4_error.canonical_code].name
+            message += f"\t* At index {idx}: {code_name}, " \
+                       f"'{p4_error.message}'\n"
+        return message
+
+
+class P4RuntimeException(Exception):
+    """
+    P4Runtime exception handler.
+
+    Attributes
+    ----------
+    grpc_error : object
+        gRPC error
+    """
+
+    def __init__(self, grpc_error):
+        super().__init__()
+        self.grpc_error = grpc_error
+
+    def __str__(self):
+        message = f"P4Runtime RPC error ({self.grpc_error.code().name}): " \
+                  f"{self.grpc_error.details()}"
+        return message
+
+
+def parse_p4runtime_write_error(func):
+    """
+    Parse P4Runtime write error.
+
+    :param func: function
+    :return: parsed error
+    """
+
+    @wraps(func)
+    def handle(*args, **kwargs):
+        try:
+            return func(*args, **kwargs)
+        except grpc.RpcError as ex:
+            if ex.code() != grpc.StatusCode.UNKNOWN:
+                raise ex
+            raise P4RuntimeWriteException(ex) from None
+
+    return handle
+
+
+def parse_p4runtime_error(func):
+    """
+    Parse P4Runtime error.
+
+    :param func: function
+    :return: parsed error
+    """
+
+    @wraps(func)
+    def handle(*args, **kwargs):
+        try:
+            return func(*args, **kwargs)
+        except grpc.RpcError as ex:
+            raise P4RuntimeException(ex) from None
+
+    return handle
+
+
+class SSLOptions(NamedTuple):
+    """
+    Tuple of SSL options.
+    """
+    insecure: bool
+    cacert: str = None
+    cert: str = None
+    key: str = None
+
+
+def read_pem_file(path):
+    """
+    Load and read PEM file.
+
+    :param path: path to PEM file
+    :return: file descriptor
+    """
+    try:
+        with open(path, "rb") as f_d:
+            return f_d.read()
+    except (FileNotFoundError, IOError, OSError):
+        logging.critical("Cannot read from PEM file '%s'", path)
+        sys.exit(1)
+
+
+@enum.unique
+class WriteOperation(enum.Enum):
+    """
+    Write Operations.
+    """
+    insert = 1
+    update = 2
+    delete = 3
+
+
+def select_operation(mode):
+    """
+    Select P4 operation based upon the operation mode.
+
+    :param mode: operation mode
+    :return: P4 operation protobuf object
+    """
+    if mode == WriteOperation.insert:
+        return p4runtime_pb2.Update.INSERT
+    if mode == WriteOperation.update:
+        return p4runtime_pb2.Update.UPDATE
+    if mode == WriteOperation.delete:
+        return p4runtime_pb2.Update.DELETE
+    return None
+
+
+def select_entity_type(entity, update):
+    """
+    Select P4 entity type for an update.
+
+    :param entity: P4 entity object
+    :param update: update operation
+    :return: the correct update entity or None
+    """
+    if isinstance(entity, p4runtime_pb2.TableEntry):
+        return update.entity.table_entry
+    if isinstance(entity, p4runtime_pb2.ActionProfileGroup):
+        return update.entity.action_profile_group
+    if isinstance(entity, p4runtime_pb2.ActionProfileMember):
+        return update.entity.action_profile_member
+    return None
+
+
+class P4RuntimeClient:
+    """
+    P4Runtime client.
+
+    Attributes
+    ----------
+    device_id : int
+        P4 device ID
+    grpc_address : str
+        IP address and port
+    election_id : tuple
+        Mastership election ID
+    role_name : str
+        Role name (optional)
+    ssl_options: tuple
+        SSL options" named tuple (optional)
+    """
+
+    def __init__(self, device_id, grpc_address,
+                 election_id, role_name=None, ssl_options=None):
+        self.device_id = device_id
+        self.election_id = election_id
+        self.role_name = role_name
+        if ssl_options is None:
+            self.ssl_options = SSLOptions(True)
+        else:
+            self.ssl_options = ssl_options
+        LOGGER.debug(
+            "Connecting to device %d at %s", device_id, grpc_address)
+
+        if self.ssl_options.insecure:
+            logging.debug("Using insecure channel")
+            self.channel = grpc.insecure_channel(grpc_address)
+        else:
+            # root certificates are retrieved from a default location
+            # chosen by gRPC runtime unless the user provides
+            # custom certificates.
+            root_certificates = None
+            if self.ssl_options.cacert is not None:
+                root_certificates = read_pem_file(self.ssl_options.cacert)
+            certificate_chain = None
+            if self.ssl_options.cert is not None:
+                certificate_chain = read_pem_file(self.ssl_options.cert)
+            private_key = None
+            if self.ssl_options.key is not None:
+                private_key = read_pem_file(self.ssl_options.key)
+            creds = grpc.ssl_channel_credentials(root_certificates, private_key,
+                                                 certificate_chain)
+            self.channel = grpc.secure_channel(grpc_address, creds)
+        self.stream_in_q = None
+        self.stream_out_q = None
+        self.stream = None
+        self.stream_recv_thread = None
+        self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel)
+
+        try:
+            self.set_up_stream()
+        except P4RuntimeException:
+            LOGGER.critical("Failed to connect to P4Runtime server")
+            sys.exit(1)
+        LOGGER.info("P4Runtime client is successfully invoked")
+
+    def set_up_stream(self):
+        """
+        Set up a gRPC stream.
+        """
+        self.stream_out_q = queue.Queue()
+        # queues for different messages
+        self.stream_in_q = {
+            STREAM_ATTR_ARBITRATION: queue.Queue(),
+            STREAM_ATTR_PACKET: queue.Queue(),
+            STREAM_ATTR_DIGEST: queue.Queue(),
+            STREAM_ATTR_IDLE_NOT: queue.Queue(),
+            STREAM_ATTR_UNKNOWN: queue.Queue(),
+        }
+
+        def stream_req_iterator():
+            while True:
+                stream_p = self.stream_out_q.get()
+                if stream_p is None:
+                    break
+                yield stream_p
+
+        def stream_recv_wrapper(stream):
+            @parse_p4runtime_error
+            def stream_recv():
+                for stream_p in stream:
+                    if stream_p.HasField("arbitration"):
+                        self.stream_in_q["arbitration"].put(stream_p)
+                    elif stream_p.HasField("packet"):
+                        self.stream_in_q["packet"].put(stream_p)
+                    elif stream_p.HasField("digest"):
+                        self.stream_in_q["digest"].put(stream_p)
+                    else:
+                        self.stream_in_q["unknown"].put(stream_p)
+
+            try:
+                stream_recv()
+            except P4RuntimeException as ex:
+                logging.critical("StreamChannel error, closing stream")
+                logging.critical(ex)
+                for k in self.stream_in_q:
+                    self.stream_in_q[k].put(None)
+
+        self.stream = self.stub.StreamChannel(stream_req_iterator())
+        self.stream_recv_thread = threading.Thread(
+            target=stream_recv_wrapper, args=(self.stream,))
+        self.stream_recv_thread.start()
+        self.handshake()
+
+    def handshake(self):
+        """
+        Handshake with gRPC server.
+        """
+
+        req = p4runtime_pb2.StreamMessageRequest()
+        arbitration = req.arbitration
+        arbitration.device_id = self.device_id
+        election_id = arbitration.election_id
+        election_id.high = self.election_id[0]
+        election_id.low = self.election_id[1]
+        if self.role_name is not None:
+            arbitration.role.name = self.role_name
+        self.stream_out_q.put(req)
+
+        rep = self.get_stream_packet(STREAM_ATTR_ARBITRATION, timeout=2)
+        if rep is None:
+            logging.critical("Failed to establish session with server")
+            sys.exit(1)
+        is_primary = (rep.arbitration.status.code == code_pb2.OK)
+        logging.debug("Session established, client is '%s'",
+                      "primary" if is_primary else "backup")
+        if not is_primary:
+            print("You are not the primary client,"
+                  "you only have read access to the server")
+
+    def get_stream_packet(self, type_, timeout=1):
+        """
+        Get a new message from the stream.
+
+        :param type_: stream type.
+        :param timeout: time to wait.
+        :return: message or None
+        """
+        if type_ not in self.stream_in_q:
+            print("Unknown stream type 's"'', type_)
+            return None
+        try:
+            msg = self.stream_in_q[type_].get(timeout=timeout)
+            return msg
+        except queue.Empty:  # timeout expired
+            return None
+
+    @parse_p4runtime_error
+    def get_p4info(self):
+        """
+        Retrieve P4Info content.
+
+        :return: P4Info object.
+        """
+        logging.debug("Retrieving P4Info file")
+        req = p4runtime_pb2.GetForwardingPipelineConfigRequest()
+        req.device_id = self.device_id
+        req.response_type = \
+            p4runtime_pb2.GetForwardingPipelineConfigRequest.P4INFO_AND_COOKIE
+        rep = self.stub.GetForwardingPipelineConfig(req)
+        return rep.config.p4info
+
+    @parse_p4runtime_error
+    def set_fwd_pipe_config(self, p4info_path, bin_path):
+        """
+        Configure the pipeline.
+
+        :param p4info_path: path to the P4Info file
+        :param bin_path: path to the binary file
+        :return:
+        """
+        logging.debug("Setting forwarding pipeline config")
+        req = p4runtime_pb2.SetForwardingPipelineConfigRequest()
+        req.device_id = self.device_id
+        if self.role_name is not None:
+            req.role = self.role_name
+        election_id = req.election_id
+        election_id.high = self.election_id[0]
+        election_id.low = self.election_id[1]
+        req.action = \
+            p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT
+        with open(p4info_path, "r", encoding="utf-8") as f_info:
+            with open(bin_path, "rb") as f_bin:
+                try:
+                    google.protobuf.text_format.Merge(
+                        f_info.read(), req.config.p4info)
+                except google.protobuf.text_format.ParseError:
+                    logging.error("Error when parsing P4Info")
+                    raise
+                req.config.p4_device_config = f_bin.read()
+        return self.stub.SetForwardingPipelineConfig(req)
+
+    def tear_down(self):
+        """
+        Tear connection with the gRPC server down.
+        """
+        if self.stream_out_q:
+            logging.debug("Cleaning up stream")
+            self.stream_out_q.put(None)
+        if self.stream_in_q:
+            for k in self.stream_in_q:
+                self.stream_in_q[k].put(None)
+        if self.stream_recv_thread:
+            self.stream_recv_thread.join()
+        self.channel.close()
+        # avoid a race condition if channel deleted when process terminates
+        del self.channel
+
+    @parse_p4runtime_write_error
+    def __write(self, entity, mode=WriteOperation.insert):
+        """
+        Perform a write operation.
+
+        :param entity: P4 entity to write
+        :param mode: operation mode (defaults to insert)
+        :return: void
+        """
+        if isinstance(entity, (list, tuple)):
+            for ent in entity:
+                self.__write(ent)
+            return
+        req = self.__get_new_write_request()
+        update = req.updates.add()
+        update.type = select_operation(mode)
+        msg_entity = select_entity_type(entity, update)
+        if not msg_entity:
+            msg = f"{mode.name} operation for entity {entity.__name__}" \
+                  f"not supported"
+            raise P4RuntimeWriteException(msg)
+        msg_entity.CopyFrom(entity)
+        self.__simple_write(req)
+
+    def __get_new_write_request(self):
+        """
+        Create a new write request message.
+
+        :return: write request message
+        """
+        req = p4runtime_pb2.WriteRequest()
+        req.device_id = self.device_id
+        if self.role_name is not None:
+            req.role = self.role_name
+        election_id = req.election_id
+        election_id.high = self.election_id[0]
+        election_id.low = self.election_id[1]
+        return req
+
+    @parse_p4runtime_write_error
+    def __simple_write(self, req):
+        """
+        Send a write operation into the wire.
+
+        :param req: write operation request
+        :return: void
+        """
+        try:
+            return self.stub.Write(req)
+        except grpc.RpcError as ex:
+            if ex.code() != grpc.StatusCode.UNKNOWN:
+                raise ex
+            raise P4RuntimeWriteException(ex) from ex
+
+    @parse_p4runtime_write_error
+    def insert(self, entity):
+        """
+        Perform an insert write operation.
+
+        :param entity: P4 entity to insert
+        :return: void
+        """
+        return self.__write(entity, WriteOperation.insert)
+
+    @parse_p4runtime_write_error
+    def update(self, entity):
+        """
+        Perform an update write operation.
+
+        :param entity: P4 entity to update
+        :return: void
+        """
+        return self.__write(entity, WriteOperation.update)
+
+    @parse_p4runtime_write_error
+    def delete(self, entity):
+        """
+        Perform a delete write operation.
+
+        :param entity: P4 entity to delete
+        :return: void
+        """
+        return self.__write(entity, WriteOperation.delete)
+
+    @parse_p4runtime_write_error
+    def write(self, req):
+        """
+        Write device operation.
+
+        :param req: write request message
+        :return: status
+        """
+        req.device_id = self.device_id
+        if self.role_name is not None:
+            req.role = self.role_name
+        election_id = req.election_id
+        election_id.high = self.election_id[0]
+        election_id.low = self.election_id[1]
+        return self.__simple_write(req)
+
+    @parse_p4runtime_write_error
+    def write_update(self, update):
+        """
+        Update device operation.
+
+        :param update: update request message
+        :return: status
+        """
+        req = self.__get_new_write_request()
+        req.updates.extend([update])
+        return self.__simple_write(req)
+
+    # Decorator is useless here: in case of server error,
+    # the exception is raised during the iteration (when next() is called).
+    @parse_p4runtime_error
+    def read_one(self, entity):
+        """
+        Read device operation.
+
+        :param entity: P4 entity for which the read is issued
+        :return: status
+        """
+        req = p4runtime_pb2.ReadRequest()
+        if self.role_name is not None:
+            req.role = self.role_name
+        req.device_id = self.device_id
+        req.entities.extend([entity])
+        return self.stub.Read(req)
+
+    @parse_p4runtime_error
+    def api_version(self):
+        """
+        P4Runtime API version.
+
+        :return: API version hex
+        """
+        req = p4runtime_pb2.CapabilitiesRequest()
+        rep = self.stub.Capabilities(req)
+        return rep.p4runtime_api_version
diff --git a/src/device/service/drivers/p4/p4_common.py b/src/device/service/drivers/p4/p4_common.py
new file mode 100644
index 0000000000000000000000000000000000000000..bcafedc1f613bfe1d1739d72f89803155b720155
--- /dev/null
+++ b/src/device/service/drivers/p4/p4_common.py
@@ -0,0 +1,445 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This package contains several helper functions for encoding to and decoding from
+byte strings:
+- integers
+- IPv4 address strings
+- IPv6 address strings
+- Ethernet address strings
+as well as static variables used by various P4 driver components.
+"""
+
+import logging
+import math
+import re
+import socket
+import ipaddress
+from ctypes import c_uint16, sizeof
+import macaddress
+
+from common.type_checkers.Checkers import chk_type
+try:
+    from .p4_exception import UserBadValueError
+except ImportError:
+    from p4_exception import UserBadValueError
+
+P4_ATTR_DEV_ID = "id"
+P4_ATTR_DEV_NAME = "name"
+P4_ATTR_DEV_VENDOR = "vendor"
+P4_ATTR_DEV_HW_VER = "hw_ver"
+P4_ATTR_DEV_SW_VER = "sw_ver"
+P4_ATTR_DEV_P4BIN = "p4bin"
+P4_ATTR_DEV_P4INFO = "p4info"
+P4_ATTR_DEV_TIMEOUT = "timeout"
+
+P4_VAL_DEF_VENDOR = "Unknown"
+P4_VAL_DEF_HW_VER = "BMv2 simple_switch"
+P4_VAL_DEF_SW_VER = "Stratum"
+P4_VAL_DEF_TIMEOUT = 60
+
+
+# Logger instance
+LOGGER = logging.getLogger(__name__)
+
+
+# MAC address encoding/decoding
+mac_pattern = re.compile(r"^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$")
+
+
+def matches_mac(mac_addr_string):
+    """
+    Check whether input string is a valid MAC address or not.
+
+    :param mac_addr_string: string-based MAC address
+    :return: boolean status
+    """
+    return mac_pattern.match(mac_addr_string) is not None
+
+
+def encode_mac(mac_addr_string):
+    """
+    Convert string-based MAC address into bytes.
+
+    :param mac_addr_string: string-based MAC address
+    :return: MAC address in bytes
+    """
+    return bytes(macaddress.MAC(mac_addr_string))
+
+
+def decode_mac(encoded_mac_addr):
+    """
+    Convert a MAC address in bytes into string-based MAC address.
+
+    :param encoded_mac_addr: MAC address in bytes
+    :return: string-based MAC address
+    """
+    return str(macaddress.MAC(encoded_mac_addr)).replace("-", ":").lower()
+
+
+# IP address encoding/decoding
+IPV4_LOCALHOST = "localhost"
+
+
+def matches_ipv4(ip_addr_string):
+    """
+    Check whether input string is a valid IPv4 address or not.
+
+    :param ip_addr_string: string-based IPv4 address
+    :return: boolean status
+    """
+    if ip_addr_string == IPV4_LOCALHOST:
+        return True
+    try:
+        addr = ipaddress.ip_address(ip_addr_string)
+        return isinstance(addr, ipaddress.IPv4Address)
+    except ValueError:
+        return False
+
+
+def encode_ipv4(ip_addr_string):
+    """
+    Convert string-based IPv4 address into bytes.
+
+    :param ip_addr_string: string-based IPv4 address
+    :return: IPv4 address in bytes
+    """
+    return socket.inet_aton(ip_addr_string)
+
+
+def decode_ipv4(encoded_ip_addr):
+    """
+    Convert an IPv4 address in bytes into string-based IPv4 address.
+
+    :param encoded_ip_addr: IPv4 address in bytes
+    :return: string-based IPv4 address
+    """
+    return socket.inet_ntoa(encoded_ip_addr)
+
+
+def matches_ipv6(ip_addr_string):
+    """
+    Check whether input string is a valid IPv6 address or not.
+
+    :param ip_addr_string: string-based IPv6 address
+    :return: boolean status
+    """
+    try:
+        addr = ipaddress.ip_address(ip_addr_string)
+        return isinstance(addr, ipaddress.IPv6Address)
+    except ValueError:
+        return False
+
+
+def encode_ipv6(ip_addr_string):
+    """
+    Convert string-based IPv6 address into bytes.
+
+    :param ip_addr_string: string-based IPv6 address
+    :return: IPv6 address in bytes
+    """
+    return socket.inet_pton(socket.AF_INET6, ip_addr_string)
+
+
+def decode_ipv6(encoded_ip_addr):
+    """
+    Convert an IPv6 address in bytes into string-based IPv6 address.
+
+    :param encoded_ip_addr: IPv6 address in bytes
+    :return: string-based IPv6 address
+    """
+    return str(ipaddress.ip_address(encoded_ip_addr))
+
+
+# Numerical encoding/decoding
+
+
+def limits(c_int_type):
+    """
+    Discover limits of numerical type.
+
+    :param c_int_type: numerical type
+    :return: tuple of numerical type's limits
+    """
+    signed = c_int_type(-1).value < c_int_type(0).value
+    bit_size = sizeof(c_int_type) * 8
+    signed_limit = 2 ** (bit_size - 1)
+    return (-signed_limit, signed_limit - 1) \
+        if signed else (0, 2 * signed_limit - 1)
+
+
+def valid_port(port):
+    """
+    Check whether input is a valid port number or not.
+
+    :param port: port number
+    :return: boolean status
+    """
+    lim = limits(c_uint16)
+    return lim[0] <= port <= lim[1]
+
+
+def bitwidth_to_bytes(bitwidth):
+    """
+    Convert number of bits to number of bytes.
+
+    :param bitwidth: number of bits
+    :return: number of bytes
+    """
+    return int(math.ceil(bitwidth / 8.0))
+
+
+def encode_num(number, bitwidth):
+    """
+    Convert number into bytes.
+
+    :param number: number to convert
+    :param bitwidth: number of bits
+    :return: number in bytes
+    """
+    byte_len = bitwidth_to_bytes(bitwidth)
+    return number.to_bytes(byte_len, byteorder="big")
+
+
+def decode_num(encoded_number):
+    """
+    Convert number in bytes into its numerical form.
+
+    :param encoded_number: number in bytes to convert
+    :return: numerical number form
+    """
+    return int.from_bytes(encoded_number, "big")
+
+
+# Umbrella encoder
+
+
+def encode(variable, bitwidth):
+    """
+    Tries to infer the type of `input` and encode it.
+
+    :param variable: target variable
+    :param bitwidth: size of variable in bits
+    :return: encoded bytes
+    """
+    byte_len = bitwidth_to_bytes(bitwidth)
+    if isinstance(variable, (list, tuple)) and len(variable) == 1:
+        variable = variable[0]
+
+    if isinstance(variable, int):
+        encoded_bytes = encode_num(variable, bitwidth)
+    elif isinstance(variable, str):
+        if matches_mac(variable):
+            encoded_bytes = encode_mac(variable)
+        elif matches_ipv4(variable):
+            encoded_bytes = encode_ipv4(variable)
+        elif matches_ipv6(variable):
+            encoded_bytes = encode_ipv6(variable)
+        else:
+            try:
+                value = int(variable, 0)
+            except ValueError as ex:
+                raise UserBadValueError(
+                    f"Invalid value '{variable}': "
+                    "could not cast to integer, try in hex with 0x prefix")\
+                    from ex
+            encoded_bytes = value.to_bytes(byte_len, byteorder="big")
+    else:
+        raise Exception(
+            f"Encoding objects of {type(variable)} is not supported")
+    assert len(encoded_bytes) == byte_len
+    return encoded_bytes
+
+
+# Parsers
+
+
+def get_match_field_value(match_field):
+    """
+    Retrieve the value of a certain match field by name.
+
+    :param match_field: match field
+    :return: match filed value
+    """
+    match_type = match_field.WhichOneof("field_match_type")
+    if match_type == "valid":
+        return match_field.valid.value
+    if match_type == "exact":
+        return match_field.exact.value
+    if match_type == "lpm":
+        return match_field.lpm.value, match_field.lpm.prefix_len
+    if match_type == "ternary":
+        return match_field.ternary.value, match_field.ternary.mask
+    if match_type == "range":
+        return match_field.range.low, match_field.range.high
+    raise Exception(f"Unsupported match type with type {match_type}")
+
+
+def parse_resource_string_from_json(resource, resource_str="table-name"):
+    """
+    Parse a given resource name within a JSON-based object.
+
+    :param resource: JSON-based object
+    :param resource_str: resource string to parse
+    :return: value of the parsed resource string
+    """
+    if not resource or (resource_str not in resource):
+        LOGGER.warning("JSON entry misses '%s' attribute", resource_str)
+        return None
+    chk_type(resource_str, resource[resource_str], str)
+    return resource[resource_str]
+
+
+def parse_resource_number_from_json(resource, resource_nb):
+    """
+    Parse a given resource number within a JSON-based object.
+
+    :param resource: JSON-based object
+    :param resource_nb: resource number to parse
+    :return: value of the parsed resource number
+    """
+    if not resource or (resource_nb not in resource):
+        LOGGER.warning(
+            "JSON entry misses '%s' attribute", resource_nb)
+        return None
+    chk_type(resource_nb, resource[resource_nb], int)
+    return resource[resource_nb]
+
+
+def parse_resource_integer_from_json(resource, resource_nb):
+    """
+    Parse a given integer number within a JSON-based object.
+
+    :param resource: JSON-based object
+    :param resource_nb: resource number to parse
+    :return: value of the parsed resource number
+    """
+    num = parse_resource_number_from_json(resource, resource_nb)
+    if num:
+        return int(num)
+    return -1
+
+
+def parse_resource_float_from_json(resource, resource_nb):
+    """
+    Parse a given floating point number within a JSON-based object.
+
+    :param resource: JSON-based object
+    :param resource_nb: resource number to parse
+    :return: value of the parsed resource number
+    """
+    num = parse_resource_number_from_json(resource, resource_nb)
+    if num:
+        return float(num)
+    return -1.0
+
+
+def parse_resource_bytes_from_json(resource, resource_bytes):
+    """
+    Parse given resource bytes within a JSON-based object.
+
+    :param resource: JSON-based object
+    :param resource_bytes: resource bytes to parse
+    :return: value of the parsed resource bytes
+    """
+    if not resource or (resource_bytes not in resource):
+        LOGGER.debug(
+            "JSON entry misses '%s' attribute", resource_bytes)
+        return None
+
+    if resource_bytes in resource:
+        chk_type(resource_bytes, resource[resource_bytes], bytes)
+        return resource[resource_bytes]
+    return None
+
+
+def parse_match_operations_from_json(resource):
+    """
+    Parse the match operations within a JSON-based object.
+
+    :param resource: JSON-based object
+    :return: map of match operations
+    """
+    if not resource or ("match-fields" not in resource):
+        LOGGER.warning(
+            "JSON entry misses 'match-fields' list of attributes")
+        return {}
+    chk_type("match-fields", resource["match-fields"], list)
+
+    match_map = {}
+    for mf_entry in resource["match-fields"]:
+        if ("match-field" not in mf_entry) or \
+                ("match-value" not in mf_entry):
+            LOGGER.warning(
+                "JSON entry misses 'match-field' and/or "
+                "'match-value' attributes")
+            return None
+        chk_type("match-field", mf_entry["match-field"], str)
+        chk_type("match-value", mf_entry["match-value"], str)
+        match_map[mf_entry["match-field"]] = mf_entry["match-value"]
+
+    return match_map
+
+
+def parse_action_parameters_from_json(resource):
+    """
+    Parse the action parameters within a JSON-based object.
+
+    :param resource: JSON-based object
+    :return: map of action parameters
+    """
+    if not resource or ("action-params" not in resource):
+        LOGGER.warning(
+            "JSON entry misses 'action-params' list of attributes")
+        return None
+    chk_type("action-params", resource["action-params"], list)
+
+    action_name = parse_resource_string_from_json(resource, "action-name")
+
+    action_params = {}
+    for ac_entry in resource["action-params"]:
+        if not ac_entry:
+            LOGGER.debug(
+                "Missing action parameter for action %s", action_name)
+            continue
+        chk_type("action-param", ac_entry["action-param"], str)
+        chk_type("action-value", ac_entry["action-value"], str)
+        action_params[ac_entry["action-param"]] = \
+            ac_entry["action-value"]
+
+    return action_params
+
+
+def parse_integer_list_from_json(resource, resource_list, resource_item):
+    """
+    Parse the list of integers within a JSON-based object.
+
+    :param resource: JSON-based object
+    :param resource_list: name of the resource list
+    :param resource_item: name of the resource item
+    :return: list of integers
+    """
+    if not resource or (resource_list not in resource):
+        LOGGER.warning(
+            "JSON entry misses '%s' list of attributes", resource_list)
+        return []
+    chk_type(resource_list, resource[resource_list], list)
+
+    integers_list = []
+    for item in resource[resource_list]:
+        chk_type(resource_item, item[resource_item], int)
+        integers_list.append(item[resource_item])
+
+    return integers_list
diff --git a/src/device/service/drivers/p4/p4_context.py b/src/device/service/drivers/p4/p4_context.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab01c422fe478cfe26c2f7331fc9b4653521db9f
--- /dev/null
+++ b/src/device/service/drivers/p4/p4_context.py
@@ -0,0 +1,284 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 some context around a given P4 info file.
+"""
+
+from collections import Counter
+import enum
+from functools import partialmethod
+
+
+@enum.unique
+class P4Type(enum.Enum):
+    """
+    P4 types.
+    """
+    table = 1
+    action = 2
+    action_profile = 3
+    counter = 4
+    direct_counter = 5
+    meter = 6
+    direct_meter = 7
+    controller_packet_metadata = 8
+
+
+P4Type.table.p4info_name = "tables"
+P4Type.action.p4info_name = "actions"
+P4Type.action_profile.p4info_name = "action_profiles"
+P4Type.counter.p4info_name = "counters"
+P4Type.direct_counter.p4info_name = "direct_counters"
+P4Type.meter.p4info_name = "meters"
+P4Type.direct_meter.p4info_name = "direct_meters"
+P4Type.controller_packet_metadata.p4info_name = "controller_packet_metadata"
+
+for object_type in P4Type:
+    object_type.pretty_name = object_type.name.replace('_', ' ')
+    object_type.pretty_names = object_type.pretty_name + 's'
+
+
+@enum.unique
+class P4RuntimeEntity(enum.Enum):
+    """
+    P4 runtime entities.
+    """
+    table_entry = 1
+    action_profile_member = 2
+    action_profile_group = 3
+    meter_entry = 4
+    direct_meter_entry = 5
+    counter_entry = 6
+    direct_counter_entry = 7
+    packet_replication_engine_entry = 8
+
+
+class Context:
+    """
+    P4 context.
+    """
+    def __init__(self):
+        self.p4info = None
+        self.p4info_obj_map = {}
+        self.p4info_obj_map_by_id = {}
+        self.p4info_objs_by_type = {}
+
+    def set_p4info(self, p4info):
+        """
+        Set a p4 info file.
+
+        :param p4info: p4 info file
+        :return: void
+        """
+        self.p4info = p4info
+        self._import_p4info_names()
+
+    def get_obj(self, obj_type, name):
+        """
+        Retrieve an object by type and name.
+
+        :param obj_type: P4 object type
+        :param name: P4 object name
+        :return: P4 object
+        """
+        key = (obj_type, name)
+        return self.p4info_obj_map.get(key, None)
+
+    def get_obj_id(self, obj_type, name):
+        """
+        Retrieve a P4 object's ID by type and name.
+
+        :param obj_type: P4 object type
+        :param name: P4 object name
+        :return: P4 object ID
+        """
+        obj = self.get_obj(obj_type, name)
+        if obj is None:
+            return None
+        return obj.preamble.id
+
+    def get_param(self, action_name, name):
+        """
+        Get an action parameter by action name.
+
+        :param action_name: P4 action name
+        :param name: action parameter name
+        :return: action parameter
+        """
+        action = self.get_obj(P4Type.action, action_name)
+        if action is None:
+            return None
+        for param in action.params:
+            if param.name == name:
+                return param
+        return None
+
+    def get_mf(self, table_name, name):
+        """
+        Get a table's match field by name.
+
+        :param table_name: P4 table name
+        :param name: match field name
+        :return: match field
+        """
+        table = self.get_obj(P4Type.table, table_name)
+        if table is None:
+            return None
+        for match_field in table.match_fields:
+            if match_field.name == name:
+                return match_field
+        return None
+
+    def get_param_id(self, action_name, name):
+        """
+        Get an action parameter ID by the action and parameter names.
+
+        :param action_name: P4 action name
+        :param name: action parameter name
+        :return: action parameter ID
+        """
+        param = self.get_param(action_name, name)
+        return None if param is None else param.id
+
+    def get_mf_id(self, table_name, name):
+        """
+        Get a table's match field ID by name.
+
+        :param table_name: P4 table name
+        :param name: match field name
+        :return: match field ID
+        """
+        match_field = self.get_mf(table_name, name)
+        return None if match_field is None else match_field.id
+
+    def get_param_name(self, action_name, id_):
+        """
+        Get an action parameter name by the action name and action ID.
+
+        :param action_name: P4 action name
+        :param id_: action parameter ID
+        :return: action parameter name
+        """
+        action = self.get_obj(P4Type.action, action_name)
+        if action is None:
+            return None
+        for param in action.params:
+            if param.id == id_:
+                return param.name
+        return None
+
+    def get_mf_name(self, table_name, id_):
+        """
+        Get a table's match field name by ID.
+
+        :param table_name: P4 table name
+        :param id_: match field ID
+        :return: match field name
+        """
+        table = self.get_obj(P4Type.table, table_name)
+        if table is None:
+            return None
+        for match_field in table.match_fields:
+            if match_field.id == id_:
+                return match_field.name
+        return None
+
+    def get_objs(self, obj_type):
+        """
+        Get P4 objects by type.
+
+        :param obj_type: P4 object type
+        :return: list of tuples (object name, object)
+        """
+        objects = self.p4info_objs_by_type[obj_type]
+        for name, obj in objects.items():
+            yield name, obj
+
+    def get_name_from_id(self, id_):
+        """
+        Get P4 object name by its ID.
+
+        :param id_: P4 object ID
+        :return: P4 object name
+        """
+        return self.p4info_obj_map_by_id[id_].preamble.name
+
+    def get_obj_by_id(self, id_):
+        """
+        Get P4 object by its ID.
+
+        :param id_: P4 object ID
+        :return: P4 object
+        """
+        return self.p4info_obj_map_by_id[id_]
+
+    def get_packet_metadata_name_from_id(self, ctrl_pkt_md_name, id_):
+        """
+        Get packet metadata name by ID.
+
+        :param ctrl_pkt_md_name: packet replication entity name
+        :param id_: packet metadata ID
+        :return: packet metadata name
+        """
+        ctrl_pkt_md = self.get_obj(
+            P4Type.controller_packet_metadata, ctrl_pkt_md_name)
+        if not ctrl_pkt_md:
+            return None
+        for meta in ctrl_pkt_md.metadata:
+            if meta.id == id_:
+                return meta.name
+        return None
+
+    # We accept any suffix that uniquely identifies the object
+    # among p4info objects of the same type.
+    def _import_p4info_names(self):
+        """
+        Import p4 info into memory.
+
+        :return: void
+        """
+        suffix_count = Counter()
+        for obj_type in P4Type:
+            self.p4info_objs_by_type[obj_type] = {}
+            for obj in getattr(self.p4info, obj_type.p4info_name):
+                pre = obj.preamble
+                self.p4info_obj_map_by_id[pre.id] = obj
+                self.p4info_objs_by_type[obj_type][pre.name] = obj
+                suffix = None
+                for suf in reversed(pre.name.split(".")):
+                    suffix = suf if suffix is None else suf + "." + suffix
+                    key = (obj_type, suffix)
+                    self.p4info_obj_map[key] = obj
+                    suffix_count[key] += 1
+        for key, cnt in suffix_count.items():
+            if cnt > 1:
+                del self.p4info_obj_map[key]
+
+
+# Add p4info object and object id "getters" for each object type;
+# these are just wrappers around Context.get_obj and Context.get_obj_id.
+# For example: get_table(x) and get_table_id(x) respectively call
+# get_obj(P4Type.table, x) and get_obj_id(P4Type.table, x)
+for object_type in P4Type:
+    object_name = "_".join(["get", object_type.name])
+    setattr(Context, object_name, partialmethod(
+        Context.get_obj, object_type))
+    object_name = "_".join(["get", object_type.name, "id"])
+    setattr(Context, object_name, partialmethod(
+        Context.get_obj_id, object_type))
+
+for object_type in P4Type:
+    object_name = "_".join(["get", object_type.p4info_name])
+    setattr(Context, object_name, partialmethod(Context.get_objs, object_type))
diff --git a/src/device/service/drivers/p4/p4_driver.py b/src/device/service/drivers/p4/p4_driver.py
index af05952b313d1632eacd5962cc34c4aa1b6b5a10..069c07ce40e43192b74519b2175e7e10c638cd20 100644
--- a/src/device/service/drivers/p4/p4_driver.py
+++ b/src/device/service/drivers/p4/p4_driver.py
@@ -16,13 +16,22 @@
 P4 driver plugin for the TeraFlow SDN controller.
 """
 
+import os
+import json
 import logging
 import threading
 from typing import Any, Iterator, List, Optional, Tuple, Union
-from .p4_util import P4RuntimeClient,\
+from common.type_checkers.Checkers import chk_type, chk_length, chk_string
+from .p4_common import matches_ipv4, matches_ipv6, valid_port,\
     P4_ATTR_DEV_ID, P4_ATTR_DEV_NAME, P4_ATTR_DEV_VENDOR,\
-    P4_ATTR_DEV_HW_VER, P4_ATTR_DEV_SW_VER, P4_ATTR_DEV_PIPECONF,\
-    P4_VAL_DEF_VENDOR, P4_VAL_DEF_HW_VER, P4_VAL_DEF_SW_VER, P4_VAL_DEF_PIPECONF
+    P4_ATTR_DEV_HW_VER, P4_ATTR_DEV_SW_VER,\
+    P4_ATTR_DEV_P4BIN, P4_ATTR_DEV_P4INFO, P4_ATTR_DEV_TIMEOUT,\
+    P4_VAL_DEF_VENDOR, P4_VAL_DEF_HW_VER, P4_VAL_DEF_SW_VER,\
+    P4_VAL_DEF_TIMEOUT
+from .p4_manager import P4Manager, get_api_version, KEY_TABLE,\
+    KEY_ACTION_PROFILE, KEY_COUNTER, KEY_DIR_COUNTER, KEY_METER, KEY_DIR_METER,\
+    KEY_CTL_PKT_METADATA
+from .p4_client import WriteOperation
 
 try:
     from _Driver import _Driver
@@ -53,208 +62,543 @@ class P4Driver(_Driver):
             Hardware version of the P4 device (Optional)
         sw_ver : str
             Software version of the P4 device (Optional)
-        pipeconf : str
-            P4 device table configuration (Optional)
+        p4bin : str
+            Path to P4 binary file (Optional, but must be combined with p4info)
+        p4info : str
+            Path to P4 info file (Optional, but must be combined with p4bin)
+        timeout : int
+            Device timeout in seconds (Optional)
     """
 
     def __init__(self, address: str, port: int, **settings) -> None:
         # pylint: disable=super-init-not-called
-        self.__client = None
+        self.__manager = None
         self.__address = address
         self.__port = int(port)
+        self.__endpoint = None
         self.__settings = settings
-
-        try:
-            self.__dev_id = self.__settings.get(P4_ATTR_DEV_ID)
-        except Exception as ex:
-            LOGGER.error('P4 device ID is a mandatory setting')
-            raise Exception from ex
-
-        if P4_ATTR_DEV_NAME in self.__settings:
-            self.__dev_name = self.__settings.get(P4_ATTR_DEV_NAME)
-        else:
-            self.__dev_name = str(self.__dev_id)
-            LOGGER.warning(
-                'No device name is provided. Setting default name: %s',
-                self.__dev_name)
-
-        if P4_ATTR_DEV_VENDOR in self.__settings:
-            self.__dev_vendor = self.__settings.get(P4_ATTR_DEV_VENDOR)
-        else:
-            self.__dev_vendor = P4_VAL_DEF_VENDOR
-            LOGGER.warning(
-                'No vendor is provided. Setting default vendor: %s',
-                self.__dev_vendor)
-
-        if P4_ATTR_DEV_HW_VER in self.__settings:
-            self.__dev_hw_version = self.__settings.get(P4_ATTR_DEV_HW_VER)
-        else:
-            self.__dev_hw_version = P4_VAL_DEF_HW_VER
-            LOGGER.warning(
-                'No HW version is provided. Setting default HW version: %s',
-                self.__dev_hw_version)
-
-        if P4_ATTR_DEV_SW_VER in self.__settings:
-            self.__dev_sw_version = self.__settings.get(P4_ATTR_DEV_SW_VER)
-        else:
-            self.__dev_sw_version = P4_VAL_DEF_SW_VER
-            LOGGER.warning(
-                'No SW version is provided. Setting default SW version: %s',
-                self.__dev_sw_version)
-
-        if P4_ATTR_DEV_PIPECONF in self.__settings:
-            self.__dev_pipeconf = self.__settings.get(P4_ATTR_DEV_PIPECONF)
-        else:
-            self.__dev_pipeconf = P4_VAL_DEF_PIPECONF
-            LOGGER.warning(
-                'No P4 pipeconf is provided. Setting default P4 pipeconf: %s',
-                self.__dev_pipeconf)
-
+        self.__id = None
+        self.__name = None
+        self.__vendor = P4_VAL_DEF_VENDOR
+        self.__hw_version = P4_VAL_DEF_HW_VER
+        self.__sw_version = P4_VAL_DEF_SW_VER
+        self.__p4bin_path = None
+        self.__p4info_path = None
+        self.__timeout = P4_VAL_DEF_TIMEOUT
         self.__lock = threading.Lock()
         self.__started = threading.Event()
         self.__terminate = threading.Event()
 
-        LOGGER.info('Initializing P4 device at %s:%d with settings:',
+        self.__parse_and_validate_settings()
+
+        LOGGER.info("Initializing P4 device at %s:%d with settings:",
                     self.__address, self.__port)
 
         for key, value in settings.items():
-            LOGGER.info('\t%8s = %s', key, value)
+            LOGGER.info("\t%8s = %s", key, value)
 
     def Connect(self) -> bool:
         """
-        Establishes a connection between the P4 device driver and a P4 device.
+        Establish a connection between the P4 device driver and a P4 device.
 
         :return: boolean connection status.
         """
-        LOGGER.info(
-            'Connecting to P4 device %s:%d ...',
-            self.__address, self.__port)
+        LOGGER.info("Connecting to P4 device %s ...", self.__endpoint)
 
         with self.__lock:
             # Skip if already connected
             if self.__started.is_set():
                 return True
 
-            # Instantiate a gRPC channel with the P4 device
-            grpc_address = f'{self.__address}:{self.__port}'
+            # Dynamically devise an election ID
             election_id = (1, 0)
-            self.__client = P4RuntimeClient(
-                self.__dev_id, grpc_address, election_id)
-            LOGGER.info('\tConnected!')
+
+            # Spawn a P4 manager for this device
+            self.__manager = P4Manager(
+                device_id=self.__id,
+                ip_address=self.__address,
+                port=self.__port,
+                election_id=election_id)
+            assert self.__manager
+
+            # Start the P4 manager
+            try:
+                self.__manager.start(self.__p4bin_path, self.__p4info_path)
+            except Exception as ex:  # pylint: disable=broad-except
+                raise Exception(ex) from ex
+
+            LOGGER.info("\tConnected via P4Runtime version %s",
+                        get_api_version())
             self.__started.set()
 
             return True
 
     def Disconnect(self) -> bool:
         """
-        Terminates the connection between the P4 device driver and a P4 device.
+        Terminate the connection between the P4 device driver and a P4 device.
 
         :return: boolean disconnection status.
         """
-        LOGGER.info(
-            'Disconnecting from P4 device %s:%d ...',
-            self.__address, self.__port)
+        LOGGER.info("Disconnecting from P4 device %s ...", self.__endpoint)
 
         # If not started, assume it is already disconnected
         if not self.__started.is_set():
             return True
 
-        # gRPC client must already be instantiated
-        assert self.__client
+        # P4 manager must already be instantiated
+        assert self.__manager
 
         # Trigger termination of loops and processes
         self.__terminate.set()
 
         # Trigger connection tear down with the P4Runtime server
-        self.__client.tear_down()
-        self.__client = None
+        self.__manager.stop()
+        self.__manager = None
 
-        LOGGER.info('\tDisconnected!')
+        LOGGER.info("\tDisconnected!")
 
         return True
 
     def GetInitialConfig(self) -> List[Tuple[str, Any]]:
         """
-        Retrieves the initial configuration of a P4 device.
+        Retrieve the initial configuration of a P4 device.
 
         :return: list of initial configuration items.
         """
-        LOGGER.info('P4 GetInitialConfig()')
-        return []
+        initial_conf = []
 
-    def GetConfig(self, resource_keys : List[str] = [])\
+        with self.__lock:
+            if not initial_conf:
+                LOGGER.warning("No initial configuration for P4 device %s ...",
+                               self.__endpoint)
+            return []
+
+    def GetConfig(self, resource_keys: List[str] = [])\
             -> List[Tuple[str, Union[Any, None, Exception]]]:
         """
-        Retrieves the current configuration of a P4 device.
+        Retrieve the current configuration of a P4 device.
 
-        :param resource_keys: configuration parameters to retrieve.
-        :return: list of values associated with the requested resource keys.
+        :param resource_keys: P4 resource keys to retrieve.
+        :return: list of values associated with the requested resource keys or
+        None/Exception.
         """
+        LOGGER.info(
+            "Getting configuration from P4 device %s ...", self.__endpoint)
 
-        LOGGER.info('P4 GetConfig()')
-        return []
+        # No resource keys means fetch all configuration
+        if len(resource_keys) == 0:
+            LOGGER.warning(
+                "GetConfig with no resource keys "
+                "implies getting all resource keys!")
+            resource_keys = [
+                obj_name for obj_name, _ in self.__manager.p4_objects.items()
+            ]
+
+        # Verify the input type
+        chk_type("resources", resource_keys, list)
+
+        with self.__lock:
+            return self.__get_resources(resource_keys)
 
-    def SetConfig(self, resources : List[Tuple[str, Any]])\
+    def SetConfig(self, resources: List[Tuple[str, Any]])\
             -> List[Union[bool, Exception]]:
         """
-        Submits a new configuration to a P4 device.
+        Submit a new configuration to a P4 device.
 
-        :param resources: configuration parameters to set.
-        :return: list of results for resource key changes requested.
+        :param resources: P4 resources to set.
+        :return: list of boolean results or Exceptions for resource key
+        changes requested.
         """
-        LOGGER.info('P4 SetConfig()')
-        return []
+        LOGGER.info(
+            "Setting configuration to P4 device %s ...", self.__endpoint)
 
-    def DeleteConfig(self, resources : List[Tuple[str, Any]])\
+        if not resources or len(resources) == 0:
+            LOGGER.warning(
+                "SetConfig requires a list of resources to store "
+                "into the device. Nothing is provided though.")
+            return []
+
+        assert isinstance(resources, list)
+
+        with self.__lock:
+            return self.__set_resources(resources)
+
+    def DeleteConfig(self, resources: List[Tuple[str, Any]])\
             -> List[Union[bool, Exception]]:
         """
-        Revokes P4 device configuration.
+        Revoke P4 device configuration.
 
         :param resources: list of tuples with resource keys to be deleted.
-        :return: list of results for resource key deletions requested.
+        :return: list of boolean results or Exceptions for resource key
+        deletions requested.
         """
-        LOGGER.info('P4 DeleteConfig()')
-        return []
+        LOGGER.info(
+            "Deleting configuration from P4 device %s ...", self.__endpoint)
+
+        if not resources or len(resources) == 0:
+            LOGGER.warning(
+                "DeleteConfig requires a list of resources to delete "
+                "from the device. Nothing is provided though.")
+            return []
 
-    def GetResource(self, endpoint_uuid : str) -> Optional[str]:
+        with self.__lock:
+            return self.__delete_resources(resources)
+
+    def GetResource(self, endpoint_uuid: str) -> Optional[str]:
         """
-        Retrieves a certain resource from a P4 device.
+        Retrieve a certain resource from a P4 device.
 
         :param endpoint_uuid: target endpoint UUID.
         :return: The path of the endpoint or None if not found.
         """
-        LOGGER.info('P4 GetResource()')
+        LOGGER.warning("GetResource() RPC not yet implemented by the P4 driver")
         return ""
 
-    def GetState(self, blocking=False, terminate : Optional[threading.Event] = None) -> Iterator[Tuple[str, Any]]:
+    def GetState(self,
+                 blocking=False,
+                 terminate: Optional[threading.Event] = None) -> \
+                 Iterator[Tuple[str, Any]]:
         """
-        Retrieves the state of a P4 device.
+        Retrieve the state of a P4 device.
 
         :param blocking: if non-blocking, the driver terminates the loop and
         returns.
+        :param terminate: termination flag.
         :return: sequences of state sample.
         """
-        LOGGER.info('P4 GetState()')
+        LOGGER.warning("GetState() RPC not yet implemented by the P4 driver")
         return []
 
-    def SubscribeState(self, subscriptions : List[Tuple[str, float, float]])\
+    def SubscribeState(self, subscriptions: List[Tuple[str, float, float]])\
             -> List[Union[bool, Exception]]:
         """
-        Subscribes to certain state information.
+        Subscribe to certain state information.
 
         :param subscriptions: list of tuples with resources to be subscribed.
         :return: list of results for resource subscriptions requested.
         """
-        LOGGER.info('P4 SubscribeState()')
-        return []
+        LOGGER.warning(
+            "SubscribeState() RPC not yet implemented by the P4 driver")
+        return [False for _ in subscriptions]
 
-    def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]])\
+    def UnsubscribeState(self, subscriptions: List[Tuple[str, float, float]])\
             -> List[Union[bool, Exception]]:
         """
-        Unsubscribes from certain state information.
+        Unsubscribe from certain state information.
 
         :param subscriptions: list of tuples with resources to be unsubscribed.
         :return: list of results for resource un-subscriptions requested.
         """
-        LOGGER.info('P4 UnsubscribeState()')
-        return []
+        LOGGER.warning(
+            "UnsubscribeState() RPC not yet implemented by the P4 driver")
+        return [False for _ in subscriptions]
+
+    def get_manager(self):
+        """
+        Get an instance of the P4 manager.
+
+        :return: P4 manager instance
+        """
+        return self.__manager
+
+    def __parse_and_validate_settings(self):
+        """
+        Verify that the driver inputs comply to what is expected.
+
+        :return: void or exception in case of validation error
+        """
+        # Device endpoint information
+        assert matches_ipv4(self.__address) or (matches_ipv6(self.__address)),\
+            f"{self.__address} not a valid IPv4 or IPv6 address"
+        assert valid_port(self.__port), \
+            f"{self.__port} not a valid transport port"
+        self.__endpoint = f"{self.__address}:{self.__port}"
+
+        # Device ID
+        try:
+            self.__id = self.__settings.get(P4_ATTR_DEV_ID)
+        except Exception as ex:
+            LOGGER.error("P4 device ID is a mandatory setting")
+            raise Exception from ex
+
+        # Device name
+        if P4_ATTR_DEV_NAME in self.__settings:
+            self.__name = self.__settings.get(P4_ATTR_DEV_NAME)
+        else:
+            self.__name = str(self.__id)
+            LOGGER.warning(
+                "No device name is provided. Setting default name: %s",
+                self.__name)
+
+        # Device vendor
+        if P4_ATTR_DEV_VENDOR in self.__settings:
+            self.__vendor = self.__settings.get(P4_ATTR_DEV_VENDOR)
+        else:
+            LOGGER.warning(
+                "No device vendor is provided. Setting default vendor: %s",
+                self.__vendor)
+
+        # Device hardware version
+        if P4_ATTR_DEV_HW_VER in self.__settings:
+            self.__hw_version = self.__settings.get(P4_ATTR_DEV_HW_VER)
+        else:
+            LOGGER.warning(
+                "No HW version is provided. Setting default HW version: %s",
+                self.__hw_version)
+
+        # Device software version
+        if P4_ATTR_DEV_SW_VER in self.__settings:
+            self.__sw_version = self.__settings.get(P4_ATTR_DEV_SW_VER)
+        else:
+            LOGGER.warning(
+                "No SW version is provided. Setting default SW version: %s",
+                self.__sw_version)
+
+        # Path to P4 binary file
+        if P4_ATTR_DEV_P4BIN in self.__settings:
+            self.__p4bin_path = self.__settings.get(P4_ATTR_DEV_P4BIN)
+            assert os.path.exists(self.__p4bin_path),\
+                "Invalid path to p4bin file"
+            assert P4_ATTR_DEV_P4INFO in self.__settings,\
+                "p4info and p4bin settings must be provided together"
+
+        # Path to P4 info file
+        if P4_ATTR_DEV_P4INFO in self.__settings:
+            self.__p4info_path = self.__settings.get(P4_ATTR_DEV_P4INFO)
+            assert os.path.exists(self.__p4info_path),\
+                "Invalid path to p4info file"
+            assert P4_ATTR_DEV_P4BIN in self.__settings,\
+                "p4info and p4bin settings must be provided together"
+
+        if (not self.__p4bin_path) or (not self.__p4info_path):
+            LOGGER.warning(
+                "No P4 binary and info files are provided, hence "
+                "no pipeline will be installed on the whitebox device.\n"
+                "This driver will attempt to manage whatever pipeline "
+                "is available on the target device.")
+
+        # Device timeout
+        if P4_ATTR_DEV_TIMEOUT in self.__settings:
+            self.__timeout = self.__settings.get(P4_ATTR_DEV_TIMEOUT)
+            assert self.__timeout > 0,\
+                "Device timeout must be a positive integer"
+        else:
+            LOGGER.warning(
+                "No device timeout is provided. Setting default timeout: %s",
+                self.__timeout)
+
+    def __get_resources(self, resource_keys):
+        """
+        Retrieve the current configuration of a P4 device.
+
+        :param resource_keys: P4 resource keys to retrieve.
+        :return: list of values associated with the requested resource keys or
+        None/Exception.
+        """
+        resources = []
+
+        LOGGER.debug("GetConfig() -> Keys: %s", resource_keys)
+
+        for resource_key in resource_keys:
+            entries = []
+            try:
+                if KEY_TABLE == resource_key:
+                    for table_name in self.__manager.get_table_names():
+                        t_entries = self.__manager.table_entries_to_json(
+                            table_name)
+                        if t_entries:
+                            entries.append(t_entries)
+                elif KEY_COUNTER == resource_key:
+                    for cnt_name in self.__manager.get_counter_names():
+                        c_entries = self.__manager.counter_entries_to_json(
+                            cnt_name)
+                        if c_entries:
+                            entries.append(c_entries)
+                elif KEY_DIR_COUNTER == resource_key:
+                    for d_cnt_name in self.__manager.get_direct_counter_names():
+                        dc_entries = \
+                            self.__manager.direct_counter_entries_to_json(
+                                d_cnt_name)
+                        if dc_entries:
+                            entries.append(dc_entries)
+                elif KEY_METER == resource_key:
+                    for meter_name in self.__manager.get_meter_names():
+                        m_entries = self.__manager.meter_entries_to_json(
+                            meter_name)
+                        if m_entries:
+                            entries.append(m_entries)
+                elif KEY_DIR_METER == resource_key:
+                    for d_meter_name in self.__manager.get_direct_meter_names():
+                        dm_entries = \
+                            self.__manager.direct_meter_entries_to_json(
+                                d_meter_name)
+                        if dm_entries:
+                            entries.append(dm_entries)
+                elif KEY_ACTION_PROFILE == resource_key:
+                    for ap_name in self.__manager.get_action_profile_names():
+                        ap_entries = \
+                            self.__manager.action_prof_member_entries_to_json(
+                                ap_name)
+                        if ap_entries:
+                            entries.append(ap_entries)
+                elif KEY_CTL_PKT_METADATA == resource_key:
+                    msg = f"{resource_key.capitalize()} is not a " \
+                          f"retrievable resource"
+                    raise Exception(msg)
+                else:
+                    msg = f"GetConfig failed due to invalid " \
+                          f"resource key: {resource_key}"
+                    raise Exception(msg)
+                resources.append(
+                    (resource_key, entries if entries else None)
+                )
+            except Exception as ex:  # pylint: disable=broad-except
+                resources.append((resource_key, ex))
+
+        return resources
+
+    def __set_resources(self, resources):
+        """
+        Submit a new configuration to a P4 device.
+
+        :param resources: P4 resources to set.
+        :return: list of boolean results or Exceptions for resource key
+        changes requested.
+        """
+        results = []
+
+        for i, resource in enumerate(resources):
+            str_resource_name = f"resources[#{i}]"
+            resource_key = ""
+            try:
+                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, resource_key, allow_empty=False)
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception(
+                    "Exception validating %s: %s",
+                    str_resource_name, str(resource_key))
+                results.append(e)  # store the exception if validation fails
+                continue
+
+            try:
+                resource_value = json.loads(resource_value)
+            except Exception:  # pylint: disable=broad-except
+                pass
+
+            LOGGER.debug(
+                "SetConfig() -> Key: %s - Value: %s",
+                resource_key, resource_value)
+
+            # Default operation is insert.
+            # P4 manager has internal logic to judge whether an entry
+            # to be inserted already exists, thus simply needs an update.
+            operation = WriteOperation.insert
+
+            try:
+                self.__apply_operation(resource_key, resource_value, operation)
+                results.append(True)
+            except Exception as ex:  # pylint: disable=broad-except
+                results.append(ex)
+
+        print(results)
+
+        return results
+
+    def __delete_resources(self, resources):
+        """
+        Revoke P4 device configuration.
+
+        :param resources: list of tuples with resource keys to be deleted.
+        :return: list of boolean results or Exceptions for resource key
+        deletions requested.
+        """
+        results = []
+
+        for i, resource in enumerate(resources):
+            str_resource_name = f"resources[#{i}]"
+            resource_key = ""
+            try:
+                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, resource_key, allow_empty=False)
+            except Exception as e:  # pylint: disable=broad-except
+                LOGGER.exception(
+                    "Exception validating %s: %s",
+                    str_resource_name, str(resource_key))
+                results.append(e)  # store the exception if validation fails
+                continue
+
+            try:
+                resource_value = json.loads(resource_value)
+            except Exception:  # pylint: disable=broad-except
+                pass
+
+            LOGGER.debug("DeleteConfig() -> Key: %s - Value: %s",
+                         resource_key, resource_value)
+
+            operation = WriteOperation.delete
+
+            try:
+                self.__apply_operation(resource_key, resource_value, operation)
+                results.append(True)
+            except Exception as ex:  # pylint: disable=broad-except
+                results.append(ex)
+
+        print(results)
+
+        return results
+
+    def __apply_operation(
+            self, resource_key, resource_value, operation: WriteOperation):
+        """
+        Apply a write operation to a P4 resource.
+
+        :param resource_key: P4 resource key
+        :param resource_value: P4 resource value in JSON format
+        :param operation: write operation (i.e., insert, update, delete)
+        to apply
+        :return: True if operation is successfully applied or raise Exception
+        """
+
+        # Apply settings to the various tables
+        if KEY_TABLE == resource_key:
+            self.__manager.table_entry_operation_from_json(
+                resource_value, operation)
+        elif KEY_COUNTER == resource_key:
+            self.__manager.counter_entry_operation_from_json(
+                resource_value, operation)
+        elif KEY_DIR_COUNTER == resource_key:
+            self.__manager.direct_counter_entry_operation_from_json(
+                resource_value, operation)
+        elif KEY_METER == resource_key:
+            self.__manager.meter_entry_operation_from_json(
+                resource_value, operation)
+        elif KEY_DIR_METER == resource_key:
+            self.__manager.direct_meter_entry_operation_from_json(
+                resource_value, operation)
+        elif KEY_ACTION_PROFILE == resource_key:
+            self.__manager.action_prof_member_entry_operation_from_json(
+                resource_value, operation)
+            self.__manager.action_prof_group_entry_operation_from_json(
+                resource_value, operation)
+        elif KEY_CTL_PKT_METADATA == resource_key:
+            msg = f"{resource_key.capitalize()} is not a " \
+                  f"configurable resource"
+            raise Exception(msg)
+        else:
+            msg = f"{operation} on invalid key {resource_key}"
+            LOGGER.error(msg)
+            raise Exception(msg)
+
+        LOGGER.debug("%s operation: %s", resource_key.capitalize(), operation)
+
+        return True
diff --git a/src/device/service/drivers/p4/p4_exception.py b/src/device/service/drivers/p4/p4_exception.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e3afb723b3850fd9a9b2b1c4982bf8ae31b20f7
--- /dev/null
+++ b/src/device/service/drivers/p4/p4_exception.py
@@ -0,0 +1,135 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+P4 driver exceptions.
+"""
+
+
+class UserError(Exception):
+    """
+    User error exception.
+    """
+    def __init__(self, info=""):
+        super().__init__()
+        self.info = info
+
+    def __str__(self):
+        return self.info
+
+    # TODO: find better way to get a custom traceback  # pylint: disable=W0511
+    def _render_traceback_(self):
+        return [str(self)]
+
+
+class InvalidP4InfoError(Exception):
+    """
+    Invalid P4 info exception.
+    """
+    def __init__(self, info=""):
+        super().__init__()
+        self.info = info
+
+    def __str__(self):
+        return f"Invalid P4Info message: {self.info}"
+
+    def _render_traceback_(self):
+        return [str(self)]
+
+
+class UnknownOptionName(UserError):
+    """
+    Unknown option name exception.
+    """
+    def __init__(self, option_name):
+        super().__init__()
+        self.option_name = option_name
+
+    def __str__(self):
+        return f"Unknown option name: {self.option_name}"
+
+
+class InvalidOptionValueType(UserError):
+    """
+    Invalid option value type exception.
+    """
+    def __init__(self, option, value):
+        super().__init__()
+        self.option = option
+        self.value = value
+
+    def __str__(self):
+        return f"Invalid value type for option {self.option.name}. "\
+               "Expected {self.option.value.__name__} but got "\
+               "value {self.value} with type {type(self.value).__name__}"
+
+
+class UserBadIPv4Error(UserError):
+    """
+    Invalid IPv4 address value exception.
+    """
+    def __init__(self, addr):
+        super().__init__()
+        self.addr = addr
+
+    def __str__(self):
+        return f"{self.addr}' is not a valid IPv4 address"
+
+    def _render_traceback_(self):
+        return [str(self)]
+
+
+class UserBadIPv6Error(UserError):
+    """
+    Invalid IPv6 address value exception.
+    """
+    def __init__(self, addr):
+        super().__init__()
+        self.addr = addr
+
+    def __str__(self):
+        return f"'{self.addr}' is not a valid IPv6 address"
+
+    def _render_traceback_(self):
+        return [str(self)]
+
+
+class UserBadMacError(UserError):
+    """
+    Invalid MAC address value exception.
+    """
+    def __init__(self, addr):
+        super().__init__()
+        self.addr = addr
+
+    def __str__(self):
+        return f"'{self.addr}' is not a valid MAC address"
+
+    def _render_traceback_(self):
+        return [str(self)]
+
+
+class UserBadValueError(UserError):
+    """
+    Invalid value exception.
+    """
+    def __init__(self, info=""):
+        super().__init__()
+        self.info = info
+
+    def __str__(self):
+        return self.info
+
+    def _render_traceback_(self):
+        return [str(self)]
diff --git a/src/device/service/drivers/p4/p4_global_options.py b/src/device/service/drivers/p4/p4_global_options.py
new file mode 100644
index 0000000000000000000000000000000000000000..86043b671e9316dfeff2fb12db8ab3088386382a
--- /dev/null
+++ b/src/device/service/drivers/p4/p4_global_options.py
@@ -0,0 +1,204 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+P4Runtime global options.
+"""
+
+import enum
+try:
+    from .p4_exception import UnknownOptionName, InvalidOptionValueType
+except ImportError:
+    from p4_exception import UnknownOptionName, InvalidOptionValueType
+
+
+@enum.unique
+class Options(enum.Enum):
+    """
+    P4 options.
+    """
+    canonical_bytestrings = bool
+
+
+class GlobalOptions:
+    """
+    P4 global options.
+    """
+    option_defaults = {
+        Options.canonical_bytestrings: True,
+    }
+
+    option_helpstrings = {
+        Options.canonical_bytestrings: """
+Use byte-padded legacy format for binary strings sent to the P4Runtime server,
+instead of the canonical representation. See P4Runtime specification for details.
+"""
+    }
+
+    def __init__(self):
+        self._values = {}
+        self.reset()
+        self._option_names = [option.name for option in Options]
+        self._set_docstring()
+
+    def reset(self):
+        """
+        Reset all options to their defaults.
+
+        :return: void
+        """
+        for option in Options:
+            assert option in GlobalOptions.option_defaults
+            self._values[option] = GlobalOptions.option_defaults[option]
+
+    def _supported_options_as_str(self):
+        """
+        Return a comma-separated string of supported options.
+
+        :return: string of supported options
+        """
+        return ", ".join([f"{o.name} ({o.value.__name__})" for o in Options])
+
+    def _supported_options_as_str_verbose(self):
+        """
+        Return a detailed comma-separated string of supported options.
+
+        :return: string of supported options
+        """
+        opt_str = ""
+        for option in Options:
+            opt_str += f"Option name: {option.name}\n"
+            opt_str += f"Type: {option.value.__name__}\n"
+            opt_str += f"Default value: " \
+                       f"{GlobalOptions.option_defaults[option]}\n"
+            opt_str += f"Description: " \
+                   f"{GlobalOptions.option_helpstrings.get(option, 'N/A')}\n"
+            opt_str += "\n"
+        return opt_str[:-1]
+
+    def _set_docstring(self):
+        """
+        Set the documentation for this object.
+
+        :return: void
+        """
+        self.__doc__ = f"""
+Manage global options for the P4Runtime shell.
+Supported options are: {self._supported_options_as_str()}
+To set the value of a global option, use GLOBAL_OPTIONS["<option name>"] = <option value>
+To access the current value of a global option, use GLOBAL_OPTIONS.["<option name>"]
+To reset all options to their default value, use GLOBAL_OPTIONS.reset
+
+{self._supported_options_as_str_verbose()}
+"""
+
+    def __dir__(self):
+        """
+        Return all names in this scope.
+
+        :return: list of names in scope
+        """
+        return ["reset", "set", "get"]
+
+    def set_option(self, option, value):
+        """
+        Set an option's value.
+
+        :param option: option to set
+        :param value: option value
+        :return: void
+        """
+        self._values[option] = value
+
+    def get_option(self, option):
+        """
+        Get an option's value.
+
+        :param option: option to get
+        :return: option value
+        """
+        return self._values[option]
+
+    def set(self, name, value):
+        """
+        Create an option and set its value.
+
+        :param name: option name
+        :param value: option value
+        :return: void
+        """
+        try:
+            option = Options[name]
+        except KeyError as ex:
+            raise UnknownOptionName(name) from ex
+        if not isinstance(value, option.value):
+            raise InvalidOptionValueType(option, value)
+        self.set_option(option, value)
+
+    def get(self, name):
+        """
+        Get option by name.
+
+        :param name: option name
+        :return: option
+        """
+        try:
+            option = Options[name]
+        except KeyError as ex:
+            raise UnknownOptionName(name) from ex
+        return self.get_option(option)
+
+    def __setitem__(self, name, value):
+        self.set(name, value)
+
+    def __getitem__(self, name):
+        return self.get(name)
+
+    def __str__(self):
+        return '\n'.join([f"{o.name}: {v}" for o, v in self._values.items()])
+
+
+GLOBAL_OPTIONS = GlobalOptions()
+
+
+def to_canonical_bytes(bytes_):
+    """
+    Convert to canonical bytes.
+
+    :param bytes_: byte stream
+    :return: canonical bytes
+    """
+    if len(bytes_) == 0:
+        return bytes_
+    num_zeros = 0
+    for byte in bytes_:
+        if byte != 0:
+            break
+        num_zeros += 1
+    if num_zeros == len(bytes_):
+        return bytes_[:1]
+    return bytes_[num_zeros:]
+
+
+def make_canonical_if_option_set(bytes_):
+    """
+    Convert to canonical bytes if option is set.
+
+    :param bytes_: byte stream
+    :return: canonical bytes
+    """
+
+    if GLOBAL_OPTIONS.get_option(Options.canonical_bytestrings):
+        return to_canonical_bytes(bytes_)
+    return bytes_
diff --git a/src/device/service/drivers/p4/p4_manager.py b/src/device/service/drivers/p4/p4_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc25e80b5803bfdec7d802d41c136865f4c045e3
--- /dev/null
+++ b/src/device/service/drivers/p4/p4_manager.py
@@ -0,0 +1,5987 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+P4Runtime manager.
+"""
+
+import enum
+import os
+import queue
+import time
+import logging
+from collections import Counter, OrderedDict
+from threading import Thread
+from tabulate import tabulate
+from p4.v1 import p4runtime_pb2
+from p4.config.v1 import p4info_pb2
+
+try:
+    from .p4_client import P4RuntimeClient, P4RuntimeException,\
+        P4RuntimeWriteException, WriteOperation, parse_p4runtime_error
+    from .p4_context import P4RuntimeEntity, P4Type, Context
+    from .p4_global_options import make_canonical_if_option_set
+    from .p4_common import encode,\
+        parse_resource_string_from_json, parse_resource_integer_from_json,\
+        parse_resource_bytes_from_json, parse_match_operations_from_json,\
+        parse_action_parameters_from_json, parse_integer_list_from_json
+    from .p4_exception import UserError, InvalidP4InfoError
+except ImportError:
+    from p4_client import P4RuntimeClient, P4RuntimeException,\
+        P4RuntimeWriteException, WriteOperation, parse_p4runtime_error
+    from p4_context import P4RuntimeEntity, P4Type, Context
+    from p4_global_options import make_canonical_if_option_set
+    from p4_common import encode,\
+        parse_resource_string_from_json, parse_resource_integer_from_json,\
+        parse_resource_bytes_from_json, parse_match_operations_from_json,\
+        parse_action_parameters_from_json, parse_integer_list_from_json
+    from p4_exception import UserError, InvalidP4InfoError
+
+# Logger instance
+LOGGER = logging.getLogger(__name__)
+
+# Global P4Runtime context
+CONTEXT = Context()
+
+# Global P4Runtime client
+CLIENT = None
+
+# Constant P4 entities
+KEY_TABLE = "table"
+KEY_ACTION = "action"
+KEY_ACTION_PROFILE = "action_profile"
+KEY_COUNTER = "counter"
+KEY_DIR_COUNTER = "direct_counter"
+KEY_METER = "meter"
+KEY_DIR_METER = "direct_meter"
+KEY_CTL_PKT_METADATA = "controller_packet_metadata"
+
+
+def get_context():
+    """
+    Return P4 context.
+
+    :return: context object
+    """
+    return CONTEXT
+
+
+def get_client():
+    """
+    Return P4 client.
+
+    :return: P4Runtime client object
+    """
+    return CLIENT
+
+
+def get_api_version():
+    """
+    Get the supported P4Runtime API version.
+
+    :return: API version
+    """
+    return CLIENT.api_version()
+
+
+def get_table_type(table):
+    """
+    Assess the type of P4 table based upon the matching scheme.
+
+    :param table: P4 table
+    :return: P4 table type
+    """
+    for m_f in table.match_fields:
+        if m_f.match_type == p4info_pb2.MatchField.EXACT:
+            return p4info_pb2.MatchField.EXACT
+        if m_f.match_type == p4info_pb2.MatchField.LPM:
+            return p4info_pb2.MatchField.LPM
+        if m_f.match_type == p4info_pb2.MatchField.TERNARY:
+            return p4info_pb2.MatchField.TERNARY
+        if m_f.match_type == p4info_pb2.MatchField.RANGE:
+            return p4info_pb2.MatchField.RANGE
+        if m_f.match_type == p4info_pb2.MatchField.OPTIONAL:
+            return p4info_pb2.MatchField.OPTIONAL
+    return None
+
+
+def match_type_to_str(match_type):
+    """
+    Convert table match type to string.
+
+    :param match_type: table match type object
+    :return: table match type string
+    """
+    if match_type == p4info_pb2.MatchField.EXACT:
+        return "Exact"
+    if match_type == p4info_pb2.MatchField.LPM:
+        return "LPM"
+    if match_type == p4info_pb2.MatchField.TERNARY:
+        return "Ternary"
+    if match_type == p4info_pb2.MatchField.RANGE:
+        return "Range"
+    if match_type == p4info_pb2.MatchField.OPTIONAL:
+        return "Optional"
+    return None
+
+
+def insert_table_entry_exact(
+        table_name, match_map, action_name, action_params, metadata,
+        cnt_pkt=-1, cnt_byte=-1):
+    """
+    Insert an entry into an exact match table.
+
+    :param table_name: P4 table name
+    :param match_map: Map of match operations
+    :param action_name: Action name
+    :param action_params: Map of action parameters
+    :param metadata: table metadata
+    :param cnt_pkt: packet count
+    :param cnt_byte: byte count
+    :return: inserted entry
+    """
+    assert match_map, "Table entry without match operations is not accepted"
+    assert action_name, "Table entry without action is not accepted"
+
+    table_entry = TableEntry(table_name)(action=action_name)
+
+    for match_k, match_v in match_map.items():
+        table_entry.match[match_k] = match_v
+
+    for action_k, action_v in action_params.items():
+        table_entry.action[action_k] = action_v
+
+    if metadata:
+        table_entry.metadata = metadata
+
+    if cnt_pkt > 0:
+        table_entry.counter_data.packet_count = cnt_pkt
+
+    if cnt_byte > 0:
+        table_entry.counter_data.byte_count = cnt_byte
+
+    ex_msg = ""
+    try:
+        table_entry.insert()
+        LOGGER.info("Inserted exact table entry: %s", table_entry)
+    except P4RuntimeWriteException as ex:
+        ex_msg = str(ex)
+    except P4RuntimeException as ex:
+        raise P4RuntimeException from ex
+
+    # Table entry exists, needs to be modified
+    if "ALREADY_EXISTS" in ex_msg:
+        table_entry.modify()
+        LOGGER.info("Updated exact table entry: %s", table_entry)
+
+    return table_entry
+
+
+def insert_table_entry_ternary(
+        table_name, match_map, action_name, action_params, metadata,
+        priority, cnt_pkt=-1, cnt_byte=-1):
+    """
+    Insert an entry into a ternary match table.
+
+    :param table_name: P4 table name
+    :param match_map: Map of match operations
+    :param action_name: Action name
+    :param action_params: Map of action parameters
+    :param metadata: table metadata
+    :param priority: entry priority
+    :param cnt_pkt: packet count
+    :param cnt_byte: byte count
+    :return: inserted entry
+    """
+    assert match_map, "Table entry without match operations is not accepted"
+    assert action_name, "Table entry without action is not accepted"
+
+    table_entry = TableEntry(table_name)(action=action_name)
+
+    for match_k, match_v in match_map.items():
+        table_entry.match[match_k] = match_v
+
+    for action_k, action_v in action_params.items():
+        table_entry.action[action_k] = action_v
+
+    table_entry.priority = priority
+
+    if metadata:
+        table_entry.metadata = metadata
+
+    if cnt_pkt > 0:
+        table_entry.counter_data.packet_count = cnt_pkt
+
+    if cnt_byte > 0:
+        table_entry.counter_data.byte_count = cnt_byte
+
+    ex_msg = ""
+    try:
+        table_entry.insert()
+        LOGGER.info("Inserted ternary table entry: %s", table_entry)
+    except P4RuntimeWriteException as ex:
+        ex_msg = str(ex)
+    except P4RuntimeException as ex:
+        raise P4RuntimeException from ex
+
+    # Table entry exists, needs to be modified
+    if "ALREADY_EXISTS" in ex_msg:
+        table_entry.modify()
+        LOGGER.info("Updated ternary table entry: %s", table_entry)
+
+    return table_entry
+
+
+def insert_table_entry_range(
+        table_name, match_map, action_name, action_params, metadata,
+        priority, cnt_pkt=-1, cnt_byte=-1):  # pylint: disable=unused-argument
+    """
+    Insert an entry into a range match table.
+
+    :param table_name: P4 table name
+    :param match_map: Map of match operations
+    :param action_name: Action name
+    :param action_params: Map of action parameters
+    :param metadata: table metadata
+    :param priority: entry priority
+    :param cnt_pkt: packet count
+    :param cnt_byte: byte count
+    :return: inserted entry
+    """
+    assert match_map, "Table entry without match operations is not accepted"
+    assert action_name, "Table entry without action is not accepted"
+
+    raise NotImplementedError(
+        "Range-based table insertion not implemented yet")
+
+
+def insert_table_entry_optional(
+        table_name, match_map, action_name, action_params, metadata,
+        priority, cnt_pkt=-1, cnt_byte=-1):  # pylint: disable=unused-argument
+    """
+    Insert an entry into an optional match table.
+
+    :param table_name: P4 table name
+    :param match_map: Map of match operations
+    :param action_name: Action name
+    :param action_params: Map of action parameters
+    :param metadata: table metadata
+    :param priority: entry priority
+    :param cnt_pkt: packet count
+    :param cnt_byte: byte count
+    :return: inserted entry
+    """
+    assert match_map, "Table entry without match operations is not accepted"
+    assert action_name, "Table entry without action is not accepted"
+
+    raise NotImplementedError(
+        "Optional-based table insertion not implemented yet")
+
+
+class P4Manager:
+    """
+    Class to manage the runtime entries of a P4 pipeline.
+    """
+
+    def __init__(self, device_id: int, ip_address: str, port: int,
+                 election_id: tuple, role_name=None, ssl_options=None):
+        global CLIENT
+
+        self.__id = device_id
+        self.__ip_address = ip_address
+        self.__port = int(port)
+        self.__endpoint = f"{self.__ip_address}:{self.__port}"
+        CLIENT = P4RuntimeClient(
+            self.__id, self.__endpoint, election_id, role_name, ssl_options)
+        self.__p4info = None
+
+        # Internal memory for whitebox management
+        # | -> P4 entities
+        self.p4_objects = {}
+
+        # | -> P4 entities
+        self.table_entries = {}
+        self.counter_entries = {}
+        self.direct_counter_entries = {}
+        self.meter_entries = {}
+        self.direct_meter_entries = {}
+        self.multicast_groups = {}
+        self.clone_session_entries = {}
+        self.action_profile_members = {}
+        self.action_profile_groups = {}
+
+    def start(self, p4bin_path, p4info_path):
+        """
+        Start the P4 manager. This involves:
+        (i) setting the forwarding pipeline of the target switch,
+        (ii) creating a P4 context object,
+        (iii) Discovering all the entities of the pipeline, and
+        (iv) initializing necessary data structures of the manager
+
+        :param p4bin_path: Path to the P4 binary file
+        :param p4info_path: Path to the P4 info file
+        :return: void
+        """
+
+        if not p4bin_path or not os.path.exists(p4bin_path):
+            LOGGER.warning("P4 binary file not found")
+
+        if not p4info_path or not os.path.exists(p4info_path):
+            LOGGER.warning("P4 info file not found")
+
+        # Forwarding pipeline is only set iff both files are present
+        if p4bin_path and p4info_path:
+            try:
+                CLIENT.set_fwd_pipe_config(p4info_path, p4bin_path)
+            except FileNotFoundError as ex:
+                LOGGER.critical(ex)
+                CLIENT.tear_down()
+                raise FileNotFoundError(ex) from ex
+            except P4RuntimeException as ex:
+                LOGGER.critical("Error when setting config")
+                LOGGER.critical(ex)
+                CLIENT.tear_down()
+                raise P4RuntimeException(ex) from ex
+            except Exception as ex:  # pylint: disable=broad-except
+                LOGGER.critical("Error when setting config")
+                CLIENT.tear_down()
+                raise Exception(ex) from ex
+
+        try:
+            self.__p4info = CLIENT.get_p4info()
+        except P4RuntimeException as ex:
+            LOGGER.critical("Error when retrieving P4Info")
+            LOGGER.critical(ex)
+            CLIENT.tear_down()
+            raise P4RuntimeException(ex) from ex
+
+        CONTEXT.set_p4info(self.__p4info)
+        self.__discover_objects()
+        self.__init_objects()
+        LOGGER.info("P4Runtime manager started")
+
+    def stop(self):
+        """
+        Stop the P4 manager. This involves:
+        (i) tearing the P4Runtime client down and
+        (ii) cleaning up the manager's internal memory
+
+        :return: void
+        """
+        global CLIENT
+
+        # gRPC client must already be instantiated
+        assert CLIENT
+
+        # Trigger connection tear down with the P4Runtime server
+        CLIENT.tear_down()
+        CLIENT = None
+        self.__clear()
+        LOGGER.info("P4Runtime manager stopped")
+
+    def __clear(self):
+        """
+        Reset basic members of the P4 manager.
+
+        :return: void
+        """
+        self.__id = None
+        self.__ip_address = None
+        self.__port = None
+        self.__endpoint = None
+        self.__clear_state()
+
+    def __clear_state(self):
+        """
+        Reset the manager's internal memory.
+
+        :return: void
+        """
+        self.table_entries.clear()
+        self.counter_entries.clear()
+        self.direct_counter_entries.clear()
+        self.meter_entries.clear()
+        self.direct_meter_entries.clear()
+        self.multicast_groups.clear()
+        self.clone_session_entries.clear()
+        self.action_profile_members.clear()
+        self.action_profile_groups.clear()
+        self.p4_objects.clear()
+
+    def __init_objects(self):
+        """
+        Parse the discovered P4 objects and initialize internal memory for all
+        the underlying P4 entities.
+
+        :return: void
+        """
+        global KEY_TABLE, KEY_ACTION, KEY_ACTION_PROFILE, \
+            KEY_COUNTER, KEY_DIR_COUNTER, \
+            KEY_METER, KEY_DIR_METER, \
+            KEY_CTL_PKT_METADATA
+
+        KEY_TABLE = P4Type.table.name
+        KEY_ACTION = P4Type.action.name
+        KEY_ACTION_PROFILE = P4Type.action_profile.name
+        KEY_COUNTER = P4Type.counter.name
+        KEY_DIR_COUNTER = P4Type.direct_counter.name
+        KEY_METER = P4Type.meter.name
+        KEY_DIR_METER = P4Type.direct_meter.name
+        KEY_CTL_PKT_METADATA = P4Type.controller_packet_metadata.name
+        assert (k for k in [
+            KEY_TABLE, KEY_ACTION, KEY_ACTION_PROFILE,
+            KEY_COUNTER, KEY_DIR_COUNTER,
+            KEY_METER, KEY_DIR_METER,
+            KEY_CTL_PKT_METADATA
+        ])
+
+        if not self.p4_objects:
+            LOGGER.warning(
+                "Cannot initialize internal memory without discovering "
+                "the pipeline\'s P4 objects")
+            return
+
+        # Initialize all sorts of entries
+        if KEY_TABLE in self.p4_objects:
+            for table in self.p4_objects[KEY_TABLE]:
+                self.table_entries[table.name] = []
+
+        if KEY_COUNTER in self.p4_objects:
+            for cnt in self.p4_objects[KEY_COUNTER]:
+                self.counter_entries[cnt.name] = []
+
+        if KEY_DIR_COUNTER in self.p4_objects:
+            for d_cnt in self.p4_objects[KEY_DIR_COUNTER]:
+                self.direct_counter_entries[d_cnt.name] = []
+
+        if KEY_METER in self.p4_objects:
+            for meter in self.p4_objects[KEY_METER]:
+                self.meter_entries[meter.name] = []
+
+        if KEY_DIR_METER in self.p4_objects:
+            for d_meter in self.p4_objects[KEY_DIR_METER]:
+                self.direct_meter_entries[d_meter.name] = []
+
+        if KEY_ACTION_PROFILE in self.p4_objects:
+            for act_prof in self.p4_objects[KEY_ACTION_PROFILE]:
+                self.action_profile_members[act_prof.name] = []
+                self.action_profile_groups[act_prof.name] = []
+
+    def __discover_objects(self):
+        """
+        Discover and store all P4 objects.
+
+        :return: void
+        """
+        self.__clear_state()
+
+        for obj_type in P4Type:
+            for obj in P4Objects(obj_type):
+                if obj_type.name not in self.p4_objects:
+                    self.p4_objects[obj_type.name] = []
+                self.p4_objects[obj_type.name].append(obj)
+
+    def get_table(self, table_name):
+        """
+        Get a P4 table by name.
+
+        :param table_name: P4 table name
+        :return: P4 table object
+        """
+        if KEY_TABLE not in self.p4_objects:
+            return None
+        for table in self.p4_objects[KEY_TABLE]:
+            if table.name == table_name:
+                return table
+        return None
+
+    def get_tables(self):
+        """
+        Get a list of all P4 tables.
+
+        :return: list of P4 tables or empty list
+        """
+        if KEY_TABLE not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_TABLE]
+
+    def get_action(self, action_name):
+        """
+        Get action by name.
+
+        :param action_name: name of a P4 action
+        :return: action object or None
+        """
+        if KEY_ACTION not in self.p4_objects:
+            return None
+        for action in self.p4_objects[KEY_ACTION]:
+            if action.name == action_name:
+                return action
+        return None
+
+    def get_actions(self):
+        """
+        Get a list of all P4 actions.
+
+        :return: list of P4 actions or empty list
+        """
+        if KEY_ACTION not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_ACTION]
+
+    def get_action_profile(self, action_prof_name):
+        """
+        Get action profile by name.
+
+        :param action_prof_name: name of the action profile
+        :return: action profile object or None
+        """
+        if KEY_ACTION_PROFILE not in self.p4_objects:
+            return None
+        for action_prof in self.p4_objects[KEY_ACTION_PROFILE]:
+            if action_prof.name == action_prof_name:
+                return action_prof
+        return None
+
+    def get_action_profiles(self):
+        """
+        Get a list of all P4 action profiles.
+
+        :return: list of P4 action profiles or empty list
+        """
+        if KEY_ACTION_PROFILE not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_ACTION_PROFILE]
+
+    def get_counter(self, cnt_name):
+        """
+        Get counter by name.
+
+        :param cnt_name: name of a P4 counter
+        :return: counter object or None
+        """
+        if KEY_COUNTER not in self.p4_objects:
+            return None
+        for cnt in self.p4_objects[KEY_COUNTER]:
+            if cnt.name == cnt_name:
+                return cnt
+        return None
+
+    def get_counters(self):
+        """
+        Get a list of all P4 counters.
+
+        :return: list of P4 counters or empty list
+        """
+        if KEY_COUNTER not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_COUNTER]
+
+    def get_direct_counter(self, dir_cnt_name):
+        """
+        Get direct counter by name.
+
+        :param dir_cnt_name: name of a direct P4 counter
+        :return: direct counter object or None
+        """
+        if KEY_DIR_COUNTER not in self.p4_objects:
+            return None
+        for d_cnt in self.p4_objects[KEY_DIR_COUNTER]:
+            if d_cnt.name == dir_cnt_name:
+                return d_cnt
+        return None
+
+    def get_direct_counters(self):
+        """
+        Get a list of all direct P4 counters.
+
+        :return: list of direct P4 counters or empty list
+        """
+        if KEY_DIR_COUNTER not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_DIR_COUNTER]
+
+    def get_meter(self, meter_name):
+        """
+        Get meter by name.
+
+        :param meter_name: name of a P4 meter
+        :return: meter object or None
+        """
+        if KEY_METER not in self.p4_objects:
+            return None
+        for meter in self.p4_objects[KEY_METER]:
+            if meter.name == meter_name:
+                return meter
+        return None
+
+    def get_meters(self):
+        """
+        Get a list of all P4 meters.
+
+        :return: list of P4 meters or empty list
+        """
+        if KEY_METER not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_METER]
+
+    def get_direct_meter(self, dir_meter_name):
+        """
+        Get direct meter by name.
+
+        :param dir_meter_name: name of a direct P4 meter
+        :return: direct meter object or None
+        """
+        if KEY_DIR_METER not in self.p4_objects:
+            return None
+        for d_meter in self.p4_objects[KEY_DIR_METER]:
+            if d_meter.name == dir_meter_name:
+                return d_meter
+        return None
+
+    def get_direct_meters(self):
+        """
+        Get a list of all direct P4 meters.
+
+        :return: list of direct P4 meters or empty list
+        """
+        if KEY_DIR_METER not in self.p4_objects:
+            return []
+        return self.p4_objects[KEY_DIR_METER]
+
+    def get_ctl_pkt_metadata(self, ctl_pkt_meta_name):
+        """
+        Get a packet replication object by name.
+
+        :param ctl_pkt_meta_name: name of a P4 packet replication object
+        :return: P4 packet replication object or None
+        """
+        if KEY_CTL_PKT_METADATA not in self.p4_objects:
+            return None
+        for pkt_meta in self.p4_objects[KEY_CTL_PKT_METADATA]:
+            if ctl_pkt_meta_name == pkt_meta.name:
+                return pkt_meta
+        return None
+
+    def get_resource_keys(self):
+        """
+        Retrieve the available P4 resource keys.
+
+        :return: list of P4 resource keys
+        """
+        return list(self.p4_objects.keys())
+
+    def count_active_entries(self):
+        """
+        Count the number of active entries across all supported P4 entities.
+
+        :return: active number of entries
+        """
+        tot_cnt = \
+            self.count_table_entries_all() + \
+            self.count_counter_entries_all() + \
+            self.count_direct_counter_entries_all() + \
+            self.count_meter_entries_all() + \
+            self.count_direct_meter_entries_all() + \
+            self.count_action_prof_member_entries_all() + \
+            self.count_action_prof_group_entries_all()
+
+        return tot_cnt
+
+    ############################################################################
+    # Table methods
+    ############################################################################
+    def get_table_names(self):
+        """
+        Retrieve a list of P4 table names.
+
+        :return: list of P4 table names
+        """
+        if KEY_TABLE not in self.p4_objects:
+            return []
+        return list(table.name for table in self.p4_objects[KEY_TABLE])
+
+    def get_table_entries(self, table_name, action_name=None):
+        """
+        Get a list of P4 table entries by table name and optionally by action.
+
+        :param table_name: name of a P4 table
+        :param action_name: action name
+        :return: list of P4 table entries or None
+        """
+        if table_name not in self.table_entries:
+            return None
+        self.table_entries[table_name].clear()
+        self.table_entries[table_name] = []
+
+        try:
+            for count, table_entry in enumerate(
+                    TableEntry(table_name)(action=action_name).read()):
+                LOGGER.debug(
+                    "Table %s - Entry %d\n%s", table_name, count, table_entry)
+                self.table_entries[table_name].append(table_entry)
+            return self.table_entries[table_name]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return []
+
+    def table_entries_to_json(self, table_name):
+        """
+        Encode all entries of a P4 table into a JSON object.
+
+        :param table_name: name of a P4 table
+        :return: JSON object with table entries
+        """
+        if (KEY_TABLE not in self.p4_objects) or \
+                not self.p4_objects[KEY_TABLE]:
+            LOGGER.warning("No table entries to retrieve\n")
+            return {}
+
+        table_res = {}
+
+        for table in self.p4_objects[KEY_TABLE]:
+            if not table.name == table_name:
+                continue
+
+            entries = self.get_table_entries(table.name)
+            if len(entries) == 0:
+                continue
+
+            table_res["table-name"] = table_name
+
+            for ent in entries:
+                entry_match_field = "\n".join(ent.match.fields())
+                entry_match_type = match_type_to_str(
+                    ent.match.match_type(entry_match_field))
+
+                table_res["id"] = ent.id
+                table_res["match-fields"] = []
+                for match_field in ent.match.fields():
+                    table_res["match-fields"].append(
+                        {
+                            "match-field": match_field,
+                            "match-value": ent.match.value(match_field),
+                            "match-type": entry_match_type
+                        }
+                    )
+                table_res["actions"] = []
+                table_res["actions"].append(
+                    {
+                        "action-id": ent.action.id(),
+                        "action": ent.action.alias()
+                    }
+                )
+                table_res["priority"] = ent.priority
+                table_res["is-default"] = ent.is_default
+                table_res["idle-timeout"] = ent.idle_timeout_ns
+                if ent.metadata:
+                    table_res["metadata"] = ent.metadata
+
+        return table_res
+
+    def count_table_entries(self, table_name, action_name=None):
+        """
+        Count the number of entries in a P4 table.
+
+        :param table_name: name of a P4 table
+        :param action_name: action name
+        :return: number of P4 table entries or negative integer
+        upon missing table
+        """
+        entries = self.get_table_entries(table_name, action_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_table_entries_all(self):
+        """
+        Count all entries in a P4 table.
+
+        :return: number of P4 table entries
+        """
+        total_cnt = 0
+        for table_name in self.get_table_names():
+            cnt = self.count_table_entries(table_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def table_entry_operation_from_json(
+            self, json_resource, operation: WriteOperation):
+        """
+        Parse a JSON-based table entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based table entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+
+        table_name = parse_resource_string_from_json(
+            json_resource, "table-name")
+        match_map = parse_match_operations_from_json(json_resource)
+        action_name = parse_resource_string_from_json(
+            json_resource, "action-name")
+        action_params = parse_action_parameters_from_json(json_resource)
+        priority = parse_resource_integer_from_json(json_resource, "priority")
+        metadata = parse_resource_bytes_from_json(json_resource, "metadata")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            LOGGER.debug("Table entry to insert/update: %s", json_resource)
+            return self.insert_table_entry(
+                table_name=table_name,
+                match_map=match_map,
+                action_name=action_name,
+                action_params=action_params,
+                priority=priority,
+                metadata=metadata if metadata else None
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug("Table entry to delete: %s", json_resource)
+            return self.delete_table_entry(
+                table_name=table_name,
+                match_map=match_map,
+                action_name=action_name,
+                action_params=action_params,
+                priority=priority
+            )
+        return None
+
+    def insert_table_entry(self, table_name,
+                           match_map, action_name, action_params,
+                           priority, metadata=None, cnt_pkt=-1, cnt_byte=-1):
+        """
+        Insert an entry into a P4 table.
+        This method has internal logic to discriminate among:
+        (i) Exact matches,
+        (ii) Ternary matches,
+        (iii) LPM matches,
+        (iv) Range matches, and
+        (v) Optional matches
+
+        :param table_name: name of a P4 table
+        :param match_map: map of match operations
+        :param action_name: action name
+        :param action_params: map of action parameters
+        :param priority: entry priority
+        :param metadata: entry metadata
+        :param cnt_pkt: packet count
+        :param cnt_byte: byte count
+        :return: inserted entry
+        """
+        table = self.get_table(table_name)
+        assert table, \
+            "P4 pipeline does not implement table " + table_name
+
+        if not get_table_type(table):
+            msg = f"Table {table_name} is undefined, cannot insert entry"
+            LOGGER.error(msg)
+            raise UserError(msg)
+
+        # Exact match is supported
+        if get_table_type(table) == p4info_pb2.MatchField.EXACT:
+            if priority != 0:
+                msg = f"Table {table_name} is non-ternary, priority must be 0"
+                LOGGER.error(msg)
+                raise UserError(msg)
+            return insert_table_entry_exact(
+                table_name, match_map, action_name, action_params, metadata,
+                cnt_pkt, cnt_byte)
+
+        # Ternary and LPM matches are supported
+        if get_table_type(table) in \
+                [p4info_pb2.MatchField.TERNARY, p4info_pb2.MatchField.LPM]:
+            if priority == 0:
+                msg = f"Table {table_name} is ternary, priority must be != 0"
+                LOGGER.error(msg)
+                raise UserError(msg)
+            return insert_table_entry_ternary(
+                table_name, match_map, action_name, action_params, metadata,
+                priority, cnt_pkt, cnt_byte)
+
+        # TODO: Cover RANGE match  # pylint: disable=W0511
+        if get_table_type(table) == p4info_pb2.MatchField.RANGE:
+            return insert_table_entry_range(
+                table_name, match_map, action_name, action_params, metadata,
+                priority, cnt_pkt, cnt_byte)
+
+        # TODO: Cover OPTIONAL match  # pylint: disable=W0511
+        if get_table_type(table) == p4info_pb2.MatchField.OPTIONAL:
+            return insert_table_entry_optional(
+                table_name, match_map, action_name, action_params, metadata,
+                priority, cnt_pkt, cnt_byte)
+
+        return None
+
+    def delete_table_entry(self, table_name,
+                           match_map, action_name, action_params, priority=0):
+        """
+        Delete an entry from a P4 table.
+
+        :param table_name: name of a P4 table
+        :param match_map: map of match operations
+        :param action_name: action name
+        :param action_params: map of action parameters
+        :param priority: entry priority
+        :return: deleted entry
+        """
+        table = self.get_table(table_name)
+        assert table, \
+            "P4 pipeline does not implement table " + table_name
+
+        if not get_table_type(table):
+            msg = f"Table {table_name} is undefined, cannot delete entry"
+            LOGGER.error(msg)
+            raise UserError(msg)
+
+        table_entry = TableEntry(table_name)(action=action_name)
+
+        for match_k, match_v in match_map.items():
+            table_entry.match[match_k] = match_v
+
+        for action_k, action_v in action_params.items():
+            table_entry.action[action_k] = action_v
+
+        if get_table_type(table) == p4info_pb2.MatchField.EXACT:
+            if priority != 0:
+                msg = f"Table {table_name} is non-ternary, priority must be 0"
+                LOGGER.error(msg)
+                raise UserError(msg)
+
+        if get_table_type(table) in \
+                [p4info_pb2.MatchField.TERNARY, p4info_pb2.MatchField.LPM]:
+            if priority == 0:
+                msg = f"Table {table_name} is ternary, priority must be != 0"
+                LOGGER.error(msg)
+                raise UserError(msg)
+
+        # TODO: Ensure correctness of RANGE & OPTIONAL  # pylint: disable=W0511
+        if get_table_type(table) in \
+                [p4info_pb2.MatchField.RANGE, p4info_pb2.MatchField.OPTIONAL]:
+            raise NotImplementedError(
+                "Range and optional-based table deletion not implemented yet")
+
+        table_entry.priority = priority
+
+        table_entry.delete()
+        LOGGER.info("Deleted entry %s from table: %s", table_entry, table_name)
+
+        return table_entry
+
+    def delete_table_entries(self, table_name):
+        """
+        Delete all entries of a P4 table.
+
+        :param table_name: name of a P4 table
+        :return: void
+        """
+        table = self.get_table(table_name)
+        assert table, \
+            "P4 pipeline does not implement table " + table_name
+
+        if not get_table_type(table):
+            msg = f"Table {table_name} is undefined, cannot delete entry"
+            LOGGER.error(msg)
+            raise UserError(msg)
+
+        TableEntry(table_name).read(function=lambda x: x.delete())
+        LOGGER.info("Deleted all entries from table: %s", table_name)
+
+    def print_table_entries_spec(self, table_name):
+        """
+        Print the specification of a P4 table.
+        Specification covers:
+        (i) match id,
+        (ii) match field name (e.g., ip_proto),
+        (iii) match type (e.g., exact, ternary, etc.),
+        (iv) match bitwidth
+        (v) action id, and
+        (vi) action name
+
+        :param table_name: name of a P4 table
+        :return: void
+        """
+        if (KEY_TABLE not in self.p4_objects) or \
+                not self.p4_objects[KEY_TABLE]:
+            LOGGER.warning("No table specification to print\n")
+            return
+
+        for table in self.p4_objects[KEY_TABLE]:
+            if not table.name == table_name:
+                continue
+
+            entry = []
+
+            for i, match_field in enumerate(table.match_fields):
+                table_name = table.name if i == 0 else ""
+                match_field_id = match_field.id
+                match_field_name = match_field.name
+                match_type_str = match_type_to_str(match_field.match_type)
+                match_field_bitwidth = match_field.bitwidth
+
+                entry.append(
+                    [
+                        table_name, str(match_field_id), match_field_name,
+                        match_type_str, str(match_field_bitwidth)
+                    ]
+                )
+
+            print(
+                tabulate(
+                    entry,
+                    headers=[
+                        KEY_TABLE, "match id", "match field",
+                        "match type", "match width"
+                    ],
+                    stralign="right",
+                    tablefmt="pretty"
+                )
+            )
+
+            entry.clear()
+
+            for i, action in enumerate(table.action_refs):
+                table_name = table.name if i == 0 else ""
+                action_id = action.id
+                action_name = CONTEXT.get_name_from_id(action.id)
+                entry.append([table_name, str(action_id), action_name])
+
+            print(
+                tabulate(
+                    entry,
+                    headers=[KEY_TABLE, "action id", "action name"],
+                    stralign="right",
+                    tablefmt="pretty"
+                )
+            )
+            print("\n")
+            entry.clear()
+
+    def print_table_entries_summary(self):
+        """
+        Print a summary of a P4 table state.
+        Summary covers:
+        (i) table name,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_TABLE not in self.p4_objects) or \
+                not self.p4_objects[KEY_TABLE]:
+            LOGGER.warning("No tables to print\n")
+            return
+
+        entry = []
+
+        for table in self.p4_objects[KEY_TABLE]:
+            table_name = table.name
+            entries = self.get_table_entries(table_name)
+            entries_nb = len(entries)
+            entry_ids_str = "\n".join(str(e.id) for e in entries) \
+                if entries_nb > 0 else "-"
+
+            entry.append([table_name, entries_nb, entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=[KEY_TABLE, "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    def print_table_entries(self, table_name):
+        """
+        Print all entries of a P4 table.
+
+        :param table_name: name of a P4 table
+        :return: void
+        """
+        if (KEY_TABLE not in self.p4_objects) or \
+                not self.p4_objects[KEY_TABLE]:
+            LOGGER.warning("No table entries to print\n")
+            return
+
+        for table in self.p4_objects[KEY_TABLE]:
+            if not table.name == table_name:
+                continue
+
+            entry = []
+
+            entries = self.get_table_entries(table.name)
+            for ent in entries:
+                entry_id = ent.id
+                mfs = ent.match.fields()
+                entry_match_field = "\n".join(mfs)
+                entry_match_value = "\n".join(
+                    ent.match.value(match_field) for match_field in mfs
+                )
+                entry_match_type = match_type_to_str(
+                    ent.match.match_type(entry_match_field))
+                entry_action_id = ent.action.id()
+                entry_action = ent.action.alias()
+                entry_priority = ent.priority
+                entry_is_default = ent.is_default
+                entry_idle_timeout_ns = ent.idle_timeout_ns
+                entry_metadata = ent.metadata
+
+                entry.append(
+                    [
+                        table_name, str(entry_id),
+                        entry_match_field, entry_match_value, entry_match_type,
+                        str(entry_action_id), entry_action,
+                        str(entry_priority), str(entry_is_default),
+                        str(entry_idle_timeout_ns), str(entry_metadata)
+                    ]
+                )
+
+            if not entry:
+                entry.append([table_name] + ["-"] * 10)
+
+            print(
+                tabulate(
+                    entry,
+                    headers=[
+                        KEY_TABLE, "table id",
+                        "match field", "match value", "match type",
+                        "action id", "action", "priority", "is default",
+                        "idle timeout (ns)", "metadata"
+                    ],
+                    stralign="right",
+                    tablefmt="pretty",
+                )
+            )
+            print("\n")
+
+    ############################################################################
+
+    ############################################################################
+    # Counter methods
+    ############################################################################
+    def get_counter_names(self):
+        """
+        Retrieve a list of P4 counter names.
+
+        :return: list of P4 counter names
+        """
+        if KEY_COUNTER not in self.p4_objects:
+            return []
+        return list(cnt.name for cnt in self.p4_objects[KEY_COUNTER])
+
+    def get_counter_entries(self, cnt_name):
+        """
+        Get a list of P4 counters by name.
+
+        :param cnt_name: name of a P4 counter
+        :return: list of P4 counters or None
+        """
+        if cnt_name not in self.counter_entries:
+            return None
+        self.counter_entries[cnt_name].clear()
+        self.counter_entries[cnt_name] = []
+
+        try:
+            for count, cnt_entry in enumerate(CounterEntry(cnt_name).read()):
+                LOGGER.debug(
+                    "Counter %s - Entry %d\n%s", cnt_name, count, cnt_entry)
+                self.counter_entries[cnt_name].append(cnt_entry)
+            return self.counter_entries[cnt_name]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return []
+
+    def counter_entries_to_json(self, cnt_name):
+        """
+        Encode all counter entries into a JSON object.
+
+        :param cnt_name: counter name
+        :return: JSON object with counter entries
+        """
+        if (KEY_COUNTER not in self.p4_objects) or \
+                not self.p4_objects[KEY_COUNTER]:
+            LOGGER.warning("No counter entries to retrieve\n")
+            return {}
+
+        cnt_res = {}
+
+        for cnt in self.p4_objects[KEY_COUNTER]:
+            if not cnt.name == cnt_name:
+                continue
+
+            entries = self.get_counter_entries(cnt.name)
+            if len(entries) == 0:
+                continue
+
+            cnt_res["counter-name"] = cnt_name
+
+            for ent in entries:
+                cnt_res["index"] = ent.index
+                cnt_res["packet-count"] = ent.packet_count
+                cnt_res["byte-count"] = ent.byte_count
+
+        return cnt_res
+
+    def count_counter_entries(self, cnt_name):
+        """
+        Count the number of P4 counter entries by counter name.
+
+        :param cnt_name: name of a P4 counter
+        :return: number of P4 counters or negative integer
+        upon missing counter
+        """
+        entries = self.get_counter_entries(cnt_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_counter_entries_all(self):
+        """
+        Count all entries of a P4 counter.
+
+        :return: number of P4 counter entries
+        """
+        total_cnt = 0
+        for cnt_name in self.get_counter_names():
+            cnt = self.count_counter_entries(cnt_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def counter_entry_operation_from_json(self,
+                                          json_resource,
+                                          operation: WriteOperation):
+        """
+        Parse a JSON-based counter entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based counter entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        cnt_name = parse_resource_string_from_json(
+            json_resource, "counter-name")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            index = parse_resource_integer_from_json(
+                json_resource, "index")
+            cnt_pkt = parse_resource_integer_from_json(
+                json_resource, "packet-count")
+            cnt_byte = parse_resource_integer_from_json(
+                json_resource, "byte-count")
+
+            LOGGER.debug("Counter entry to insert/update: %s", json_resource)
+            return self.insert_counter_entry(
+                cnt_name=cnt_name,
+                index=index,
+                cnt_pkt=cnt_pkt,
+                cnt_byte=cnt_byte
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug("Counter entry to delete: %s", json_resource)
+            return self.clear_counter_entry(
+                cnt_name=cnt_name
+            )
+        return None
+
+    def insert_counter_entry(self, cnt_name, index=None,
+                             cnt_pkt=-1, cnt_byte=-1):
+        """
+        Insert a P4 counter entry.
+
+        :param cnt_name: name of a P4 counter
+        :param index: counter index
+        :param cnt_pkt: packet count
+        :param cnt_byte: byte count
+        :return: inserted entry
+        """
+        cnt = self.get_counter(cnt_name)
+        assert cnt, \
+            "P4 pipeline does not implement counter " + cnt_name
+
+        cnt_entry = CounterEntry(cnt_name)
+
+        if index:
+            cnt_entry.index = index
+
+        if cnt_pkt > 0:
+            cnt_entry.packet_count = cnt_pkt
+
+        if cnt_byte > 0:
+            cnt_entry.byte_count = cnt_byte
+
+        cnt_entry.modify()
+        LOGGER.info("Updated counter entry: %s", cnt_entry)
+
+        return cnt_entry
+
+    def clear_counter_entry(self, cnt_name):
+        """
+        Clear the counters of a counter entry by name.
+
+        :param cnt_name: name of a P4 counter
+        :return: cleared entry
+        """
+        cnt = self.get_counter(cnt_name)
+        assert cnt, \
+            "P4 pipeline does not implement counter " + cnt_name
+
+        cnt_entry = CounterEntry(cnt_name)
+        cnt_entry.clear_data()
+        LOGGER.info("Cleared data of counter entry: %s", cnt_entry)
+
+        return cnt_entry
+
+    def print_counter_entries_summary(self):
+        """
+        Print a summary of a P4 counter state.
+        Summary covers:
+        (i) counter name,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_COUNTER not in self.p4_objects) or \
+                not self.p4_objects[KEY_COUNTER]:
+            LOGGER.warning("No counters to print\n")
+            return
+
+        entry = []
+
+        for cnt in self.p4_objects[KEY_COUNTER]:
+            entries = self.get_counter_entries(cnt.name)
+            entries_nb = len(entries)
+            entry_ids_str = ",".join(str(e.id) for e in entries) \
+                if entries_nb > 0 else "-"
+            entry.append([cnt.name, str(entries_nb), entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=[KEY_COUNTER, "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    ############################################################################
+
+    ############################################################################
+    # Direct counter methods
+    ############################################################################
+    def get_direct_counter_names(self):
+        """
+        Retrieve a list of direct P4 counter names.
+
+        :return: list of direct P4 counter names
+        """
+        if KEY_DIR_COUNTER not in self.p4_objects:
+            return []
+        return list(d_cnt.name for d_cnt in self.p4_objects[KEY_DIR_COUNTER])
+
+    def get_direct_counter_entries(self, d_cnt_name):
+        """
+        Get a list of direct P4 counters by name.
+
+        :param d_cnt_name: name of a direct P4 counter
+        :return: list of direct P4 counters or None
+        """
+        if d_cnt_name not in self.direct_counter_entries:
+            return None
+        self.direct_counter_entries[d_cnt_name].clear()
+        self.direct_counter_entries[d_cnt_name] = []
+
+        try:
+            for count, d_cnt_entry in enumerate(
+                    DirectCounterEntry(d_cnt_name).read()):
+                LOGGER.debug(
+                    "Direct counter %s - Entry %d\n%s",
+                    d_cnt_name, count, d_cnt_entry)
+                self.direct_counter_entries[d_cnt_name].append(d_cnt_entry)
+            return self.direct_counter_entries[d_cnt_name]
+        except P4RuntimeException as ex:
+            LOGGER.error("Failed to get direct counter %s entries: %s",
+                         d_cnt_name, str(ex))
+            return []
+
+    def direct_counter_entries_to_json(self, d_cnt_name):
+        """
+        Encode all direct counter entries into a JSON object.
+
+        :param d_cnt_name: direct counter name
+        :return: JSON object with direct counter entries
+        """
+        if (KEY_DIR_COUNTER not in self.p4_objects) or \
+                not self.p4_objects[KEY_DIR_COUNTER]:
+            LOGGER.warning("No direct counter entries to retrieve\n")
+            return {}
+
+        d_cnt_res = {}
+
+        for d_cnt in self.p4_objects[KEY_DIR_COUNTER]:
+            if not d_cnt.name == d_cnt_name:
+                continue
+
+            entries = self.get_direct_counter_entries(d_cnt.name)
+            if len(entries) == 0:
+                continue
+
+            d_cnt_res["direct-counter-name"] = d_cnt_name
+
+            for ent in entries:
+                d_cnt_res["match-fields"] = []
+                for k, v in ent.table_entry.match.items():
+                    d_cnt_res["match-fields"].append(
+                        {
+                            "match-field": k,
+                            "match-value": v
+                        }
+                    )
+                d_cnt_res["priority"] = ent.priority
+                d_cnt_res["packet-count"] = ent.packet_count
+                d_cnt_res["byte-count"] = ent.byte_count
+
+        return d_cnt_res
+
+    def count_direct_counter_entries(self, d_cnt_name):
+        """
+        Count the number of direct P4 counter entries by counter name.
+
+        :param d_cnt_name: name of a direct P4 counter
+        :return: number of direct P4 counters or negative integer
+        upon missing direct counter
+        """
+        entries = self.get_direct_counter_entries(d_cnt_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_direct_counter_entries_all(self):
+        """
+        Count all entries of a direct P4 counter.
+
+        :return: number of direct P4 counter entries
+        """
+        total_cnt = 0
+        for d_cnt_name in self.get_direct_counter_names():
+            cnt = self.count_direct_counter_entries(d_cnt_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def direct_counter_entry_operation_from_json(self,
+                                                 json_resource,
+                                                 operation: WriteOperation):
+        """
+        Parse a JSON-based direct counter entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based direct counter entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        d_cnt_name = parse_resource_string_from_json(
+            json_resource, "direct-counter-name")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            match_map = parse_match_operations_from_json(json_resource)
+            priority = parse_resource_integer_from_json(
+                json_resource, "priority")
+            cnt_pkt = parse_resource_integer_from_json(
+                json_resource, "packet-count")
+            cnt_byte = parse_resource_integer_from_json(
+                json_resource, "byte-count")
+
+            LOGGER.debug(
+                "Direct counter entry to insert/update: %s", json_resource)
+            return self.insert_direct_counter_entry(
+                d_cnt_name=d_cnt_name,
+                match_map=match_map,
+                priority=priority,
+                cnt_pkt=cnt_pkt,
+                cnt_byte=cnt_byte
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug("Direct counter entry to delete: %s", json_resource)
+            return self.clear_direct_counter_entry(
+                d_cnt_name=d_cnt_name
+            )
+        return None
+
+    def insert_direct_counter_entry(self, d_cnt_name, match_map,
+                                    priority, cnt_pkt=-1, cnt_byte=-1):
+        """
+        Insert a direct P4 counter entry.
+
+        :param d_cnt_name: name of a direct P4 counter
+        :param match_map: map of match operations
+        :param priority: entry priority
+        :param cnt_pkt: packet count
+        :param cnt_byte: byte count
+        :return: inserted entry
+        """
+        d_cnt = self.get_direct_counter(d_cnt_name)
+        assert d_cnt, \
+            "P4 pipeline does not implement direct counter " + d_cnt_name
+
+        assert match_map,\
+            "Direct counter entry without match operations is not accepted"
+
+        d_cnt_entry = DirectCounterEntry(d_cnt_name)
+
+        for match_k, match_v in match_map.items():
+            d_cnt_entry.table_entry.match[match_k] = match_v
+
+        d_cnt_entry.table_entry.priority = priority
+
+        if cnt_pkt > 0:
+            d_cnt_entry.packet_count = cnt_pkt
+
+        if cnt_byte > 0:
+            d_cnt_entry.byte_count = cnt_byte
+
+        d_cnt_entry.modify()
+        LOGGER.info("Updated direct counter entry: %s", d_cnt_entry)
+
+        return d_cnt_entry
+
+    def clear_direct_counter_entry(self, d_cnt_name):
+        """
+        Clear the counters of a direct counter entry by name.
+
+        :param d_cnt_name: name of a direct P4 counter
+        :return: cleared entry
+        """
+        d_cnt = self.get_direct_counter(d_cnt_name)
+        assert d_cnt, \
+            "P4 pipeline does not implement direct counter " + d_cnt_name
+
+        d_cnt_entry = DirectCounterEntry(d_cnt_name)
+        d_cnt_entry.clear_data()
+        LOGGER.info("Cleared direct counter entry: %s", d_cnt_entry)
+
+        return d_cnt_entry
+
+    def print_direct_counter_entries_summary(self):
+        """
+        Print a summary of a direct P4 counter state.
+        Summary covers:
+        (i) direct counter name,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_DIR_COUNTER not in self.p4_objects) or \
+                not self.p4_objects[KEY_DIR_COUNTER]:
+            LOGGER.warning("No direct counters to print\n")
+            return
+
+        entry = []
+
+        for d_cnt in self.p4_objects[KEY_DIR_COUNTER]:
+            entries = self.get_direct_counter_entries(d_cnt.name)
+            entries_nb = len(entries)
+            entry_ids_str = ",".join(str(e.id) for e in entries) \
+                if entries_nb > 0 else "-"
+            entry.append([d_cnt.name, str(entries_nb), entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=[KEY_DIR_COUNTER, "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    ############################################################################
+
+    ############################################################################
+    # Meter methods
+    ############################################################################
+    def get_meter_names(self):
+        """
+        Retrieve a list of P4 meter names.
+
+        :return: list of P4 meter names
+        """
+        if KEY_METER not in self.p4_objects:
+            return []
+        return list(meter.name for meter in self.p4_objects[KEY_METER])
+
+    def get_meter_entries(self, meter_name):
+        """
+        Get a list of P4 meters by name.
+
+        :param meter_name: name of a P4 meter
+        :return: list of P4 meters or None
+        """
+        if meter_name not in self.meter_entries:
+            return None
+        self.meter_entries[meter_name].clear()
+        self.meter_entries[meter_name] = []
+
+        try:
+            for count, meter_entry in enumerate(MeterEntry(meter_name).read()):
+                LOGGER.debug(
+                    "Meter %s - Entry %d\n%s", meter_name, count, meter_entry)
+                self.meter_entries[meter_name].append(meter_entry)
+            return self.meter_entries[meter_name]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return []
+
+    def meter_entries_to_json(self, meter_name):
+        """
+        Encode all meter entries into a JSON object.
+
+        :param meter_name: meter name
+        :return: JSON object with meter entries
+        """
+        if (KEY_METER not in self.p4_objects) or \
+                not self.p4_objects[KEY_METER]:
+            LOGGER.warning("No meter entries to retrieve\n")
+            return {}
+
+        meter_res = {}
+
+        for meter in self.p4_objects[KEY_METER]:
+            if not meter.name == meter_name:
+                continue
+
+            entries = self.get_meter_entries(meter.name)
+            if len(entries) == 0:
+                continue
+
+            meter_res["meter-name"] = meter_name
+
+            for ent in entries:
+                meter_res["index"] = ent.index
+                meter_res["cir"] = ent.cir
+                meter_res["cburst"] = ent.cburst
+                meter_res["pir"] = ent.pir
+                meter_res["pburst"] = ent.pburst
+
+        return meter_res
+
+    def count_meter_entries(self, meter_name):
+        """
+        Count the number of P4 meter entries by meter name.
+
+        :param meter_name: name of a P4 meter
+        :return: number of P4 meters or negative integer
+        upon missing meter
+        """
+        entries = self.get_meter_entries(meter_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_meter_entries_all(self):
+        """
+        Count all entries of a P4 meter.
+
+        :return: number of direct P4 meter entries
+        """
+        total_cnt = 0
+        for meter_name in self.get_meter_names():
+            cnt = self.count_meter_entries(meter_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def meter_entry_operation_from_json(self,
+                                        json_resource,
+                                        operation: WriteOperation):
+        """
+        Parse a JSON-based meter entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based meter entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        meter_name = parse_resource_string_from_json(
+            json_resource, "meter-name")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            index = parse_resource_integer_from_json(
+                json_resource, "index")
+            cir = parse_resource_integer_from_json(
+                json_resource, "committed-information-rate")
+            cburst = parse_resource_integer_from_json(
+                json_resource, "committed-burst-size")
+            pir = parse_resource_integer_from_json(
+                json_resource, "peak-information-rate")
+            pburst = parse_resource_integer_from_json(
+                json_resource, "peak-burst-size")
+
+            LOGGER.debug("Meter entry to insert/update: %s", json_resource)
+            return self.insert_meter_entry(
+                meter_name=meter_name,
+                index=index,
+                cir=cir,
+                cburst=cburst,
+                pir=pir,
+                pburst=pburst
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug("Meter entry to delete: %s", json_resource)
+            return self.clear_meter_entry(
+                meter_name=meter_name
+            )
+        return None
+
+    def insert_meter_entry(self, meter_name, index=None,
+                           cir=-1, cburst=-1, pir=-1, pburst=-1):
+        """
+        Insert a P4 meter entry.
+
+        :param meter_name: name of a P4 meter
+        :param index: P4 meter index
+        :param cir: meter's committed information rate
+        :param cburst: meter's committed burst size
+        :param pir: meter's peak information rate
+        :param pburst: meter's peak burst size
+        :return: inserted entry
+        """
+        meter = self.get_meter(meter_name)
+        assert meter, \
+            "P4 pipeline does not implement meter " + meter_name
+
+        meter_entry = MeterEntry(meter_name)
+
+        if index:
+            meter_entry.index = index
+
+        if cir > 0:
+            meter_entry.cir = cir
+
+        if cburst > 0:
+            meter_entry.cburst = cburst
+
+        if pir > 0:
+            meter_entry.pir = pir
+
+        if pburst > 0:
+            meter_entry.pburst = pburst
+
+        meter_entry.modify()
+        LOGGER.info("Updated meter entry: %s", meter_entry)
+
+        return meter_entry
+
+    def clear_meter_entry(self, meter_name):
+        """
+        Clear the rates and sizes of a meter entry by name.
+
+        :param meter_name: name of a P4 meter
+        :return: cleared entry
+        """
+        meter = self.get_meter(meter_name)
+        assert meter, \
+            "P4 pipeline does not implement meter " + meter_name
+
+        meter_entry = MeterEntry(meter_name)
+        meter_entry.clear_config()
+        LOGGER.info("Cleared meter entry: %s", meter_entry)
+
+        return meter_entry
+
+    def print_meter_entries_summary(self):
+        """
+        Print a summary of a P4 meter state.
+        Summary covers:
+        (i) meter name,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_METER not in self.p4_objects) or \
+                not self.p4_objects[KEY_METER]:
+            LOGGER.warning("No meters to print\n")
+            return
+
+        entry = []
+
+        for meter in self.p4_objects[KEY_METER]:
+            entries = self.get_meter_entries(meter.name)
+            entries_nb = len(entries)
+            entry_ids_str = ",".join(str(e.id) for e in entries) \
+                if entries_nb > 0 else "-"
+            entry.append([meter.name, str(entries_nb), entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=[KEY_METER, "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    ############################################################################
+
+    ############################################################################
+    # Direct meter methods
+    ############################################################################
+    def get_direct_meter_names(self):
+        """
+        Retrieve a list of direct P4 meter names.
+
+        :return: list of direct P4 meter names
+        """
+        if KEY_DIR_METER not in self.p4_objects:
+            return []
+        return list(d_meter.name for d_meter in self.p4_objects[KEY_DIR_METER])
+
+    def get_direct_meter_entries(self, d_meter_name):
+        """
+        Get a list of direct P4 meters by name.
+
+        :param d_meter_name: name of a direct P4 meter
+        :return: list of direct P4 meters or None
+        """
+        if d_meter_name not in self.direct_meter_entries:
+            return None
+        self.direct_meter_entries[d_meter_name].clear()
+        self.direct_meter_entries[d_meter_name] = []
+
+        try:
+            for count, d_meter_entry in enumerate(
+                    MeterEntry(d_meter_name).read()):
+                LOGGER.debug(
+                    "Direct meter %s - Entry %d\n%s",
+                    d_meter_name, count, d_meter_entry)
+                self.direct_meter_entries[d_meter_name].append(d_meter_entry)
+            return self.direct_meter_entries[d_meter_name]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return []
+
+    def direct_meter_entries_to_json(self, d_meter_name):
+        """
+        Encode all direct meter entries into a JSON object.
+
+        :param d_meter_name: direct meter name
+        :return: JSON object with direct meter entries
+        """
+        if (KEY_DIR_METER not in self.p4_objects) or \
+                not self.p4_objects[KEY_DIR_METER]:
+            LOGGER.warning("No direct meter entries to retrieve\n")
+            return {}
+
+        d_meter_res = {}
+
+        for d_meter in self.p4_objects[KEY_DIR_METER]:
+            if not d_meter.name == d_meter_name:
+                continue
+
+            entries = self.get_direct_meter_entries(d_meter.name)
+            if len(entries) == 0:
+                continue
+
+            d_meter_res["direct-meter-name"] = d_meter_name
+
+            for ent in entries:
+                d_meter_res["match-fields"] = []
+                for k, v in ent.table_entry.match.items():
+                    d_meter_res["match-fields"].append(
+                        {
+                            "match-field": k,
+                            "match-value": v
+                        }
+                    )
+                d_meter_res["cir"] = ent.cir
+                d_meter_res["cburst"] = ent.cburst
+                d_meter_res["pir"] = ent.pir
+                d_meter_res["pburst"] = ent.pburst
+
+        return d_meter_res
+
+    def count_direct_meter_entries(self, d_meter_name):
+        """
+        Count the number of direct P4 meter entries by meter name.
+
+        :param d_meter_name: name of a direct P4 meter
+        :return: number of direct P4 meters or negative integer
+        upon missing direct meter
+        """
+        entries = self.get_direct_meter_entries(d_meter_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_direct_meter_entries_all(self):
+        """
+        Count all entries of a direct P4 meter.
+
+        :return: number of direct P4 meter entries
+        """
+        total_cnt = 0
+        for d_meter_name in self.get_direct_meter_names():
+            cnt = self.count_direct_meter_entries(d_meter_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def direct_meter_entry_operation_from_json(self,
+                                               json_resource,
+                                               operation: WriteOperation):
+        """
+        Parse a JSON-based direct meter entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based direct meter entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        d_meter_name = parse_resource_string_from_json(
+            json_resource, "direct-meter-name")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            match_map = parse_match_operations_from_json(json_resource)
+            cir = parse_resource_integer_from_json(
+                json_resource, "committed-information-rate")
+            cburst = parse_resource_integer_from_json(
+                json_resource, "committed-burst-size")
+            pir = parse_resource_integer_from_json(
+                json_resource, "peak-information-rate")
+            pburst = parse_resource_integer_from_json(
+                json_resource, "peak-burst-size")
+
+            LOGGER.debug(
+                "Direct meter entry to insert/update: %s", json_resource)
+            return self.insert_direct_meter_entry(
+                d_meter_name=d_meter_name,
+                match_map=match_map,
+                cir=cir,
+                cburst=cburst,
+                pir=pir,
+                pburst=pburst
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug("Direct meter entry to delete: %s", json_resource)
+            return self.clear_direct_meter_entry(
+                d_meter_name=d_meter_name
+            )
+        return None
+
+    def insert_direct_meter_entry(self, d_meter_name, match_map,
+                                  cir=-1, cburst=-1, pir=-1, pburst=-1):
+        """
+        Insert a direct P4 meter entry.
+
+        :param d_meter_name: name of a direct P4 meter
+        :param match_map: map of P4 table match operations
+        :param cir: meter's committed information rate
+        :param cburst: meter's committed burst size
+        :param pir: meter's peak information rate
+        :param pburst: meter's peak burst size
+        :return: inserted entry
+        """
+        d_meter = self.get_direct_meter(d_meter_name)
+        assert d_meter, \
+            "P4 pipeline does not implement direct meter " + d_meter_name
+
+        assert match_map,\
+            "Direct meter entry without match operations is not accepted"
+
+        d_meter_entry = DirectMeterEntry(d_meter_name)
+
+        for match_k, match_v in match_map.items():
+            d_meter_entry.table_entry.match[match_k] = match_v
+
+        if cir > 0:
+            d_meter_entry.cir = cir
+
+        if cburst > 0:
+            d_meter_entry.cburst = cburst
+
+        if pir > 0:
+            d_meter_entry.pir = pir
+
+        if pburst > 0:
+            d_meter_entry.pburst = pburst
+
+        d_meter_entry.modify()
+        LOGGER.info("Updated direct meter entry: %s", d_meter_entry)
+
+        return d_meter_entry
+
+    def clear_direct_meter_entry(self, d_meter_name):
+        """
+        Clear the rates and sizes of a direct meter entry by name.
+
+        :param d_meter_name: name of a direct P4 meter
+        :return: cleared entry
+        """
+        d_meter = self.get_direct_meter(d_meter_name)
+        assert d_meter, \
+            "P4 pipeline does not implement direct meter " + d_meter_name
+
+        d_meter_entry = DirectMeterEntry(d_meter_name)
+        d_meter_entry.clear_config()
+        LOGGER.info("Cleared direct meter entry: %s", d_meter_entry)
+
+        return d_meter_entry
+
+    def print_direct_meter_entries_summary(self):
+        """
+        Print a summary of a direct P4 meter state.
+        Summary covers:
+        (i) direct meter name,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_DIR_METER not in self.p4_objects) or \
+                not self.p4_objects[KEY_DIR_METER]:
+            LOGGER.warning("No direct meters to print\n")
+            return
+
+        entry = []
+
+        for d_meter in self.p4_objects[KEY_DIR_METER]:
+            entries = self.get_direct_meter_entries(d_meter.name)
+            entries_nb = len(entries)
+            entry_ids_str = ",".join(str(e.id) for e in entries) \
+                if entries_nb > 0 else "-"
+            entry.append([d_meter.name, str(entries_nb), entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=[KEY_DIR_METER, "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    ############################################################################
+
+    ############################################################################
+    # Action profile member
+    ############################################################################
+    def get_action_profile_names(self):
+        """
+        Retrieve a list of action profile names.
+
+        :return: list of action profile names
+        """
+        if KEY_ACTION_PROFILE not in self.p4_objects:
+            return []
+        return list(ap_name for ap_name in self.p4_objects[KEY_ACTION_PROFILE])
+
+    def get_action_prof_member_entries(self, ap_name):
+        """
+        Get a list of action profile members by name.
+
+        :param ap_name: name of a P4 action profile
+        :return: list of P4 action profile members
+        """
+        if ap_name not in self.action_profile_members:
+            return None
+        self.action_profile_members[ap_name].clear()
+        self.action_profile_members[ap_name] = []
+
+        try:
+            for count, ap_entry in enumerate(
+                    ActionProfileMember(ap_name).read()):
+                LOGGER.debug(
+                    "Action profile member %s - Entry %d\n%s",
+                    ap_name, count, ap_entry)
+                self.action_profile_members[ap_name].append(ap_entry)
+            return self.action_profile_members[ap_name]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return []
+
+    def action_prof_member_entries_to_json(self, ap_name):
+        """
+        Encode all action profile members into a JSON object.
+
+        :param ap_name: name of a P4 action profile
+        :return: JSON object with action profile member entries
+        """
+        if (KEY_ACTION_PROFILE not in self.p4_objects) or \
+                not self.p4_objects[KEY_ACTION_PROFILE]:
+            LOGGER.warning("No action profile member entries to retrieve\n")
+            return {}
+
+        ap_res = {}
+
+        for act_p in self.p4_objects[KEY_ACTION_PROFILE]:
+            if not act_p.name == ap_name:
+                continue
+
+            ap_res["action-profile-name"] = ap_name
+
+            entries = self.get_action_prof_member_entries(ap_name)
+            for ent in entries:
+                action = ent.action
+                action_name = CONTEXT.get_name_from_id(action.id)
+                ap_res["action"] = action_name
+                ap_res["action-params"] = []
+                for k, v in action.items():
+                    ap_res["action-params"].append(
+                        {
+                            "param": k,
+                            "value": v
+                        }
+                    )
+
+                ap_res["member-id"] = ent.member_id
+
+        return ap_res
+
+    def count_action_prof_member_entries(self, ap_name):
+        """
+        Count the number of action profile members by name.
+
+        :param ap_name: name of a P4 action profile
+        :return: number of action profile members or negative integer
+        upon missing member
+        """
+        entries = self.get_action_prof_member_entries(ap_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_action_prof_member_entries_all(self):
+        """
+        Count all action profile member entries.
+
+        :return: number of action profile member entries
+        """
+        total_cnt = 0
+        for ap_name in self.get_action_profile_names():
+            cnt = self.count_action_prof_member_entries(ap_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def action_prof_member_entry_operation_from_json(self,
+                                                     json_resource,
+                                                     operation: WriteOperation):
+        """
+        Parse a JSON-based action profile member entry and insert/update/delete
+        it into/from the switch.
+
+        :param json_resource: JSON-based action profile member entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        ap_name = parse_resource_string_from_json(
+            json_resource, "action-profile-name")
+        member_id = parse_resource_integer_from_json(json_resource, "member-id")
+        action_name = parse_resource_string_from_json(
+            json_resource, "action-name")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            action_params = parse_action_parameters_from_json(json_resource)
+
+            LOGGER.debug(
+                "Action profile member entry to insert/update: %s",
+                json_resource)
+            return self.insert_action_prof_member_entry(
+                ap_name=ap_name,
+                member_id=member_id,
+                action_name=action_name,
+                action_params=action_params
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug(
+                "Action profile member entry to delete: %s", json_resource)
+            return self.delete_action_prof_member_entry(
+                ap_name=ap_name,
+                member_id=member_id,
+                action_name=action_name
+            )
+        return None
+
+    def insert_action_prof_member_entry(self, ap_name, member_id,
+                                        action_name, action_params):
+        """
+        Insert a P4 action profile member entry.
+
+        :param ap_name: name of a P4 action profile
+        :param member_id: action profile member id
+        :param action_name: P4 action name
+        :param action_params: map of P4 action parameters
+        :return: inserted entry
+        """
+        act_p = self.get_action_profile(ap_name)
+        assert act_p, \
+            "P4 pipeline does not implement action profile " + ap_name
+
+        ap_member_entry = ActionProfileMember(ap_name)(
+            member_id=member_id, action=action_name)
+
+        for action_k, action_v in action_params.items():
+            ap_member_entry.action[action_k] = action_v
+
+        ex_msg = ""
+        try:
+            ap_member_entry.insert()
+            LOGGER.info(
+                "Inserted action profile member entry: %s", ap_member_entry)
+        except P4RuntimeWriteException as ex:
+            ex_msg = str(ex)
+        except P4RuntimeException as ex:
+            raise P4RuntimeException from ex
+
+        # Entry exists, needs to be modified
+        if "ALREADY_EXISTS" in ex_msg:
+            ap_member_entry.modify()
+            LOGGER.info(
+                "Updated action profile member entry: %s", ap_member_entry)
+
+        return ap_member_entry
+
+    def delete_action_prof_member_entry(self, ap_name, member_id, action_name):
+        """
+        Delete a P4 action profile member entry.
+
+        :param ap_name: name of a P4 action profile
+        :param member_id: action profile member id
+        :param action_name: P4 action name
+        :return: deleted entry
+        """
+        act_p = self.get_action_profile(ap_name)
+        assert act_p, \
+            "P4 pipeline does not implement action profile " + ap_name
+
+        ap_member_entry = ActionProfileMember(ap_name)(
+            member_id=member_id, action=action_name)
+        ap_member_entry.delete()
+        LOGGER.info("Deleted action profile member entry: %s", ap_member_entry)
+
+        return ap_member_entry
+
+    def print_action_prof_members_summary(self):
+        """
+        Print a summary of a P4 action profile member state.
+        Summary covers:
+        (i) action profile member id,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_ACTION_PROFILE not in self.p4_objects) or \
+                not self.p4_objects[KEY_ACTION_PROFILE]:
+            LOGGER.warning("No action profile members to print\n")
+            return
+
+        entry = []
+
+        for ap_name in self.p4_objects[KEY_ACTION_PROFILE]:
+            entries = self.get_action_prof_member_entries(ap_name)
+            entries_nb = len(entries)
+            entry_ids_str = ",".join(str(e.member_id) for e in entries) \
+                if entries_nb > 0 else "-"
+            entry.append([ap_name, str(entries_nb), entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=["action profile member", "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    def print_action_prof_member_entries(self, ap_name):
+        """
+        Print all entries of a P4 action profile member.
+
+        :param ap_name: name of a P4 action profile
+        :return: void
+        """
+        if (KEY_ACTION_PROFILE not in self.p4_objects) or \
+                not self.p4_objects[KEY_ACTION_PROFILE]:
+            LOGGER.warning("No action profile member entries to print\n")
+            return
+
+        for act_p in self.p4_objects[KEY_ACTION_PROFILE]:
+            if not act_p.name == ap_name:
+                continue
+
+            entry = []
+
+            entries = self.get_action_prof_member_entries(ap_name)
+            for ent in entries:
+                member_id = ent.member_id
+                action = ent.action
+                action_name = CONTEXT.get_name_from_id(action.id)
+
+                entry.append([ap_name, str(member_id), action_name])
+
+            if not entry:
+                entry.append([ap_name] + ["-"] * 2)
+
+            print(
+                tabulate(
+                    entry,
+                    headers=["action profile member", "member id", "action"],
+                    stralign="right",
+                    tablefmt="pretty"
+                )
+            )
+            print("\n")
+
+    ############################################################################
+    # Action profile group
+    ############################################################################
+    def get_action_prof_group_entries(self, ap_name):
+        """
+        Get a list of action profile groups by name.
+
+        :param ap_name: name of a P4 action profile
+        :return: list of P4 action profile groups
+        """
+        if ap_name not in self.action_profile_groups:
+            return None
+        self.action_profile_groups[ap_name].clear()
+        self.action_profile_groups[ap_name] = []
+
+        try:
+            for count, ap_entry in enumerate(
+                    ActionProfileGroup(ap_name).read()):
+                LOGGER.debug("Action profile group %s - Entry %d\n%s",
+                             ap_name, count, ap_entry)
+                self.action_profile_groups[ap_name].append(ap_entry)
+            return self.action_profile_groups[ap_name]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return []
+
+    def count_action_prof_group_entries(self, ap_name):
+        """
+        Count the number of action profile groups by name.
+
+        :param ap_name: name of a P4 action profile
+        :return: number of action profile groups or negative integer
+        upon missing group
+        """
+        entries = self.get_action_prof_group_entries(ap_name)
+        if entries is None:
+            return -1
+        return len(entries)
+
+    def count_action_prof_group_entries_all(self):
+        """
+        Count all action profile group entries.
+
+        :return: number of action profile group entries
+        """
+        total_cnt = 0
+        for ap_name in self.get_action_profile_names():
+            cnt = self.count_action_prof_group_entries(ap_name)
+            if cnt < 0:
+                continue
+            total_cnt += cnt
+        return total_cnt
+
+    def action_prof_group_entries_to_json(self, ap_name):
+        """
+        Encode all action profile groups into a JSON object.
+
+        :param ap_name: name of a P4 action profile
+        :return: JSON object with action profile group entries
+        """
+        if (KEY_ACTION_PROFILE not in self.p4_objects) or \
+                not self.p4_objects[KEY_ACTION_PROFILE]:
+            LOGGER.warning("No action profile group entries to retrieve\n")
+            return {}
+
+        ap_res = {}
+
+        for act_p in self.p4_objects[KEY_ACTION_PROFILE]:
+            if not act_p.name == ap_name:
+                continue
+
+            ap_res["action-profile-name"] = ap_name
+
+            entries = self.get_action_prof_group_entries(ap_name)
+            for ent in entries:
+                ap_res["group-id"] = ent.group_id
+                ap_res["members"] = []
+                for mem in ent.members:
+                    ap_res["members"].append(
+                        {
+                            "member": mem
+                        }
+                    )
+
+        return ap_res
+
+    def action_prof_group_entry_operation_from_json(self,
+                                                    json_resource,
+                                                    operation: WriteOperation):
+        """
+        Parse a JSON-based action profile group entry and insert/update/delete
+        it into/from the switch.
+
+        :param json_resource: JSON-based action profile group entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        ap_name = parse_resource_string_from_json(
+            json_resource, "action-profile-name")
+        group_id = parse_resource_integer_from_json(json_resource, "group-id")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            members = parse_integer_list_from_json(
+                json_resource, "members", "member")
+
+            LOGGER.debug(
+                "Action profile group entry to insert/update: %s",
+                json_resource)
+            return self.insert_action_prof_group_entry(
+                ap_name=ap_name,
+                group_id=group_id,
+                members=members
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug(
+                "Action profile group entry to delete: %s", json_resource)
+            return self.delete_action_prof_group_entry(
+                ap_name=ap_name,
+                group_id=group_id
+            )
+        return None
+
+    def insert_action_prof_group_entry(self, ap_name, group_id, members=None):
+        """
+        Insert a P4 action profile group entry.
+
+        :param ap_name: name of a P4 action profile
+        :param group_id: action profile group id
+        :param members: list of associated action profile members
+        :return: inserted entry
+        """
+        ap = self.get_action_profile(ap_name)
+        assert ap, \
+            "P4 pipeline does not implement action profile " + ap_name
+
+        ap_group_entry = ActionProfileGroup(ap_name)(group_id=group_id)
+
+        if members:
+            for m in members:
+                ap_group_entry.add(member_id=m)
+
+        ex_msg = ""
+        try:
+            ap_group_entry.insert()
+            LOGGER.info(
+                "Inserted action profile group entry: %s", ap_group_entry)
+        except P4RuntimeWriteException as ex:
+            ex_msg = str(ex)
+        except P4RuntimeException as ex:
+            raise P4RuntimeException from ex
+
+        # Entry exists, needs to be modified
+        if "ALREADY_EXISTS" in ex_msg:
+            ap_group_entry.modify()
+            LOGGER.info(
+                "Updated action profile group entry: %s", ap_group_entry)
+
+        return ap_group_entry
+
+    def delete_action_prof_group_entry(self, ap_name, group_id):
+        """
+        Delete a P4 action profile group entry.
+
+        :param ap_name: name of a P4 action profile
+        :param group_id: action profile group id
+        :return: deleted entry
+        """
+        ap = self.get_action_profile(ap_name)
+        assert ap, \
+            "P4 pipeline does not implement action profile " + ap_name
+
+        ap_group_entry = ActionProfileGroup(ap_name)(group_id=group_id)
+        ap_group_entry.delete()
+        LOGGER.info("Deleted action profile group entry: %s", ap_group_entry)
+
+        return ap_group_entry
+
+    def clear_action_prof_group_entry(self, ap_name, group_id):
+        """
+        Clean a P4 action profile group entry.
+
+        :param ap_name: name of a P4 action profile
+        :param group_id: action profile group id
+        :return: cleaned entry
+        """
+        ap = self.get_action_profile(ap_name)
+        assert ap, \
+            "P4 pipeline does not implement action profile " + ap_name
+
+        ap_group_entry = ActionProfileGroup(ap_name)(group_id=group_id)
+        ap_group_entry.clear()
+        LOGGER.info("Cleared action profile group entry: %s", ap_group_entry)
+
+        return ap_group_entry
+
+    def print_action_prof_groups_summary(self):
+        """
+        Print a summary of a P4 action profile group state.
+        Summary covers:
+        (i) action profile group id,
+        (ii) number of entries in the table, and
+        (iii) a string of \n-separated entry IDs.
+
+        :return: void
+        """
+        if (KEY_ACTION_PROFILE not in self.p4_objects) or \
+                not self.p4_objects[KEY_ACTION_PROFILE]:
+            LOGGER.warning("No action profile groups to print\n")
+            return
+
+        entry = []
+
+        for ap_name in self.p4_objects[KEY_ACTION_PROFILE]:
+            entries = self.get_action_prof_group_entries(ap_name)
+            entries_nb = len(entries)
+            entry_ids_str = ",".join(str(e.group_id) for e in entries) \
+                if entries_nb > 0 else "-"
+            entry.append([ap_name, str(entries_nb), entry_ids_str])
+
+        print(
+            tabulate(
+                entry,
+                headers=["action profile group", "# of entries", "entry ids"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    def print_action_prof_group_entries(self, ap_name):
+        """
+        Print all entries of a P4 action profile group.
+
+        :param ap_name: name of a P4 action profile
+        :return: void
+        """
+        if (KEY_ACTION_PROFILE not in self.p4_objects) or \
+                not self.p4_objects[KEY_ACTION_PROFILE]:
+            LOGGER.warning("No action profile group entries to print\n")
+            return
+
+        for ap in self.p4_objects[KEY_ACTION_PROFILE]:
+            if not ap.name == ap_name:
+                continue
+
+            entry = []
+
+            entries = self.get_action_prof_group_entries(ap_name)
+            for e in entries:
+                group_id = e.group_id
+                members_str = "\n".join(m for m in e.members)
+                entry.append([ap_name, str(group_id), members_str])
+
+            if not entry:
+                entry.append([ap_name] + ["-"] * 2)
+
+            print(
+                tabulate(
+                    entry,
+                    headers=[
+                        "action profile group", "group id", "members"
+                    ],
+                    stralign="right",
+                    tablefmt="pretty"
+                )
+            )
+            print("\n")
+
+    ############################################################################
+    # Packet replication method 1: Multicast group
+    ############################################################################
+    def get_multicast_group_entry(self, group_id):
+        """
+        Get a multicast group entry by group id.
+
+        :param group_id: id of a multicast group
+        :return: multicast group entry or none
+        """
+        if group_id not in self.multicast_groups:
+            return None
+        self.multicast_groups[group_id] = None
+
+        try:
+            mcast_group = MulticastGroupEntry(group_id).read()
+            LOGGER.debug("Multicast group %d\n%s", group_id, mcast_group)
+            self.multicast_groups[group_id] = mcast_group
+            return self.multicast_groups[group_id]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return None
+
+    def count_multicast_groups(self):
+        """
+        Count the number of multicast groups.
+
+        :return: number of multicast groups
+        """
+        return len(self.multicast_groups.keys())
+
+    def multicast_group_entries_to_json(self):
+        """
+        Encode all multicast groups into a JSON object.
+
+        :return: JSON object with multicast group entries
+        """
+        if not self.multicast_groups:
+            LOGGER.warning("No multicast group entries to retrieve\n")
+            return {}
+
+        mcast_list_res = []
+
+        for mcast_group in self.multicast_groups.values():
+            mcast_res = {}
+            mcast_res["group-id"] = mcast_group.group_id
+
+            mcast_res["egress-ports"] = []
+            mcast_res["instances"] = []
+            for r in mcast_group.replicas:
+                mcast_res["egress-ports"].append(
+                    {
+                        "egress-port": r.egress_port
+                    }
+                )
+                mcast_res["instances"].append(
+                    {
+                        "instance": r.instance
+                    }
+                )
+            mcast_list_res.append(mcast_res)
+
+        return mcast_list_res
+
+    def multicast_group_entry_operation_from_json(self,
+                                                  json_resource,
+                                                  operation: WriteOperation):
+        """
+        Parse a JSON-based multicast group entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based multicast group entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        group_id = parse_resource_integer_from_json(json_resource, "group-id")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            ports = parse_integer_list_from_json(
+                json_resource, "ports", "port")
+
+            LOGGER.debug(
+                "Multicast group entry to insert/update: %s", json_resource)
+            return self.insert_multicast_group_entry(
+                group_id=group_id,
+                ports=ports
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug("Multicast group entry to delete: %s", json_resource)
+            return self.delete_multicast_group_entry(
+                group_id=group_id
+            )
+        return None
+
+    def insert_multicast_group_entry(self, group_id, ports):
+        """
+        Insert a new multicast group.
+
+        :param group_id: id of a multicast group
+        :param ports: list of egress ports to multicast
+        :return: inserted multicast group
+        """
+        assert group_id > 0, \
+            "Multicast group " + group_id + " must be > 0"
+        assert ports, \
+            "No multicast group ports are provided"
+
+        mcast_group = MulticastGroupEntry(group_id)
+        for p in ports:
+            mcast_group.add(p, 1)
+
+        ex_msg = ""
+        try:
+            mcast_group.insert()
+            LOGGER.info("Inserted multicast group entry: %s", mcast_group)
+        except P4RuntimeWriteException as ex:
+            ex_msg = str(ex)
+        except P4RuntimeException as ex:
+            raise P4RuntimeException from ex
+
+        # Entry exists, needs to be modified
+        if "ALREADY_EXISTS" in ex_msg:
+            mcast_group.modify()
+            LOGGER.info("Updated multicast group entry: %s", mcast_group)
+
+        self.multicast_groups[group_id] = mcast_group
+
+        return mcast_group
+
+    def delete_multicast_group_entry(self, group_id):
+        """
+        Delete a multicast group by id.
+
+        :param group_id: id of a multicast group
+        :return: deleted multicast group
+        """
+        assert group_id > 0, \
+            "Multicast group " + group_id + " must be > 0"
+
+        mcast_group = MulticastGroupEntry(group_id)
+        mcast_group.delete()
+
+        if group_id in self.multicast_groups:
+            del self.multicast_groups[group_id]
+        LOGGER.info(
+            "Deleted multicast group %d", group_id)
+
+        return mcast_group
+
+    def delete_multicast_group_entries(self):
+        """
+        Delete all multicast groups.
+
+        :return: void
+        """
+        for mcast_group in MulticastGroupEntry().read():
+            gid = mcast_group.group_id
+            mcast_group.delete()
+            del self.multicast_groups[gid]
+
+        assert self.count_multicast_groups() == 0, \
+            "Failed to purge all multicast groups"
+        LOGGER.info("Deleted all multicast groups")
+
+    def print_multicast_groups_summary(self):
+        """
+        Print a summary of a P4 multicast group state.
+        Summary covers:
+        (i) multicast group id,
+        (ii) a string of \n-separated egress ports, and
+        (iii) a string of \n-separated replica instances.
+
+        :return: void
+        """
+        entry = []
+
+        for mcast_group in self.multicast_groups.values():
+            ports_str = "\n".join(
+                str(r.egress_port) for r in mcast_group.replicas)
+            inst_str = "\n".join(
+                str(r.instance) for r in mcast_group.replicas)
+            entry.append([str(mcast_group.group_id), ports_str, inst_str])
+
+        if not entry:
+            entry.append(3 * ["-"])
+
+        print(
+            tabulate(
+                entry,
+                headers=["multicast group id", "egress ports", "instances"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    ############################################################################
+    # Packet replication method 2: Clone session
+    ############################################################################
+    def get_clone_session_entry(self, session_id):
+        """
+        Get a clone session entry by session id.
+
+        :param session_id: id of a clone session
+        :return: clone session entry or none
+        """
+        if session_id not in self.clone_session_entries:
+            return None
+        self.clone_session_entries[session_id] = None
+
+        try:
+            session = CloneSessionEntry(session_id).read()
+            LOGGER.debug("Clone session %d\n%s", session_id, session)
+            self.clone_session_entries[session_id] = session
+            return self.clone_session_entries[session_id]
+        except P4RuntimeException as ex:
+            LOGGER.error(ex)
+            return None
+
+    def count_clone_session_entries(self):
+        """
+        Count the number of clone sessions.
+
+        :return: number of clone sessions
+        """
+        return len(self.clone_session_entries.keys())
+
+    def clone_session_entries_to_json(self):
+        """
+        Encode all clone sessions into a JSON object.
+
+        :return: JSON object with clone session entries
+        """
+        if not self.clone_session_entries:
+            LOGGER.warning("No clone session entries to retrieve\n")
+            return {}
+
+        session_list_res = []
+
+        for session in self.clone_session_entries.values():
+            session_res = {}
+            session_res["session-id"] = session.session_id
+
+            session_res["egress-ports"] = []
+            session_res["instances"] = []
+            for r in session.replicas:
+                session_res["egress-ports"].append(
+                    {
+                        "egress-port": r.egress_port
+                    }
+                )
+                session_res["instances"].append(
+                    {
+                        "instance": r.instance
+                    }
+                )
+            session_list_res.append(session_res)
+
+        return session_list_res
+
+    def clone_session_entry_operation_from_json(self,
+                                                json_resource,
+                                                operation: WriteOperation):
+        """
+        Parse a JSON-based clone session entry and insert/update/delete it
+        into/from the switch.
+
+        :param json_resource: JSON-based clone session entry
+        :param operation: Write operation (i.e., insert, modify, delete)
+        to perform.
+        :return: inserted entry or None in case of parsing error
+        """
+        session_id = parse_resource_integer_from_json(
+            json_resource, "session-id")
+
+        if operation in [WriteOperation.insert, WriteOperation.update]:
+            ports = parse_integer_list_from_json(
+                json_resource, "ports", "port")
+
+            LOGGER.debug(
+                "Clone session entry to insert/update: %s", json_resource)
+            return self.insert_clone_session_entry(
+                session_id=session_id,
+                ports=ports
+            )
+        if operation == WriteOperation.delete:
+            LOGGER.debug(
+                "Clone session entry to delete: %s", json_resource)
+            return self.delete_clone_session_entry(
+                session_id=session_id
+            )
+        return None
+
+    def insert_clone_session_entry(self, session_id, ports):
+        """
+        Insert a new clone session.
+
+        :param session_id: id of a clone session
+        :param ports: list of egress ports to clone session
+        :return: inserted clone session
+        """
+        assert session_id > 0, \
+            "Clone session " + session_id + " must be > 0"
+        assert ports, \
+            "No clone session ports are provided"
+
+        session = CloneSessionEntry(session_id)
+        for p in ports:
+            session.add(p, 1)
+
+        ex_msg = ""
+        try:
+            session.insert()
+            LOGGER.info("Inserted clone session entry: %s", session)
+        except P4RuntimeWriteException as ex:
+            ex_msg = str(ex)
+        except P4RuntimeException as ex:
+            raise P4RuntimeException from ex
+
+        # Entry exists, needs to be modified
+        if "ALREADY_EXISTS" in ex_msg:
+            session.modify()
+            LOGGER.info("Updated clone session entry: %s", session)
+
+        self.clone_session_entries[session_id] = session
+
+        return session
+
+    def delete_clone_session_entry(self, session_id):
+        """
+        Delete a clone session by id.
+
+        :param session_id: id of a clone session
+        :return: deleted clone session
+        """
+        assert session_id > 0, \
+            "Clone session " + session_id + " must be > 0"
+
+        session = CloneSessionEntry(session_id)
+        session.delete()
+
+        if session_id in self.clone_session_entries:
+            del self.clone_session_entries[session_id]
+        LOGGER.info(
+            "Deleted clone session %d", session_id)
+
+        return session
+
+    def delete_clone_session_entries(self):
+        """
+        Delete all clone sessions.
+
+        :return: void
+        """
+        for e in CloneSessionEntry().read():
+            sid = e.session_id
+            e.delete()
+            del self.clone_session_entries[sid]
+
+        assert self.count_multicast_groups() == 0, \
+            "Failed to purge all clone sessions"
+        LOGGER.info("Deleted all clone sessions")
+
+    def print_clone_sessions_summary(self):
+        """
+        Print a summary of a P4 clone session state.
+        Summary covers:
+        (i) clone session id,
+        (ii) a string of \n-separated egress ports, and
+        (iii) a string of \n-separated replica instances.
+
+        :return: void
+        """
+        entry = []
+
+        for session in self.clone_session_entries.values():
+            ports_str = "\n".join(
+                str(r.egress_port) for r in session.replicas)
+            inst_str = "\n".join(
+                str(r.instance) for r in session.replicas)
+            entry.append([str(session.session_id), ports_str, inst_str])
+
+        if not entry:
+            entry.append(3 * ["-"])
+
+        print(
+            tabulate(
+                entry,
+                headers=["clone session id", "egress ports", "instances"],
+                stralign="right",
+                tablefmt="pretty"
+            )
+        )
+        print("\n")
+
+    ############################################################################
+    # Packet replication method 3: Packet in
+    ############################################################################
+    def get_packet_metadata(self, meta_type, attr_name=None, attr_id=None):
+        """
+        Retrieve the pipeline's metadata by metadata type field.
+
+        :param meta_type: metadata type field
+        :param attr_name: metadata name field (optional)
+        :param attr_id: metadata id field (optional)
+        :return: packet metadata
+        """
+        for table in self.__p4info.controller_packet_metadata:
+            pre = table.preamble
+            if pre.name == meta_type:
+                for meta in table.metadata:
+                    if attr_name is not None:
+                        if meta.name == attr_name:
+                            return meta
+                    elif attr_id is not None:
+                        if meta.id == attr_id:
+                            return meta
+        raise AttributeError(
+            f"ControllerPacketMetadata {meta_type} has no metadata "
+            f"{attr_name if attr_name is not None else attr_id} (check P4Info)")
+
+    # TODO: test packet in  # pylint: disable=W0511
+    def create_packet_in(self, payload, metadata=None):
+        """
+        Create a packet-in object.
+
+        :param payload: packet-in payload
+        :param metadata: packet-in metadata (optional)
+        :return: packet-in object
+        """
+        if not self.p4_objects[KEY_CTL_PKT_METADATA]:
+            LOGGER.warning("Cannot create packet in. "
+                           "No controller packet metadata in the pipeline\n")
+            return None
+
+        packet_in = PacketOut()
+        packet_in.payload = payload
+        if metadata:
+            for name, value in metadata.items():
+                p4info_meta = self.get_packet_metadata("packet_in", name)
+                meta = packet_in.metadata.add()
+                meta.metadata_id = p4info_meta.id
+                meta.value = encode(value, p4info_meta.bitwidth)
+        return packet_in
+
+    def send_packet_in(self, payload, metadata=None, timeout=1):
+        """
+        Send a packet-in message.
+        Note that the sniff method is blocking, thus it should be invoked by
+        another thread.
+
+        :param payload: packet-in payload
+        :param metadata: packet-in metadata (optional)
+        :param timeout: packet-in timeout (defaults to 1s)
+        :return: void
+        """
+        packet_in = self.create_packet_in(payload, metadata)
+
+        # TODO: experimental piece of code  # pylint: disable=W0511
+        captured_packet = []
+
+        def _sniff_packet(captured_pkt):
+            """
+            Invoke packet-in sniff method.
+
+            :param captured_pkt: buffer for the packet to be captured
+            :return: void
+            """
+            captured_pkt += packet_in.sniff(timeout=timeout)
+
+        _t = Thread(target=_sniff_packet, args=(captured_packet,))
+        _t.start()
+        # P4Runtime client sends the packet to the switch
+        CLIENT.stream_in_q["packet"].put(packet_in)
+        _t.join()
+        LOGGER.info("Packet-in sent: %s", packet_in)
+
+    ############################################################################
+    # Packet replication method 4: Packet out
+    ############################################################################
+    # TODO: test packet out  # pylint: disable=W0511
+    def create_packet_out(self, payload, metadata=None):
+        """
+        Create a packet-out object.
+
+        :param payload: packet-out payload
+        :param metadata: packet-out metadata (optional)
+        :return: packet-out object
+        """
+        if not self.p4_objects[KEY_CTL_PKT_METADATA]:
+            LOGGER.warning("Cannot create packet out. "
+                           "No controller packet metadata in the pipeline\n")
+            return None
+
+        packet_out = PacketOut()
+        packet_out.payload = payload
+        if metadata:
+            for name, value in metadata.items():
+                p4info_meta = self.get_packet_metadata("packet_out", name)
+                meta = packet_out.metadata.add()
+                meta.metadata_id = p4info_meta.id
+                meta.value = encode(value, p4info_meta.bitwidth)
+        return packet_out
+
+    def send_packet_out(self, payload, metadata=None):
+        """
+        Send a packet-out message.
+
+        :param payload: packet-out payload
+        :param metadata: packet-out metadata (optional)
+        :return: void
+        """
+        packet_out = self.create_packet_out(payload, metadata)
+        packet_out.send()
+        LOGGER.info("Packet-out sent: %s", packet_out)
+
+    ############################################################################
+    # Packet replication method 5: Idle timeout notification
+    ############################################################################
+    # TODO: Support IdleTimeoutNotification  # pylint: disable=W0511
+    ############################################################################
+
+    def print_objects(self):
+        """
+        Print all P4 objects of the installed pipeline.
+
+        :return: void
+        """
+        if not self.p4_objects:
+            self.__discover_objects()
+
+        for obj_name, objects in self.p4_objects.items():
+            entry = []
+
+            for obj in objects:
+                entry.append([obj.name])
+
+            if not entry:
+                entry.append("-")
+            print(
+                tabulate(
+                    entry,
+                    headers=[obj_name],
+                    stralign="right",
+                    tablefmt="pretty"
+                )
+            )
+        print("\n")
+
+
+class P4Object:
+    """
+    P4 object.
+    """
+
+    def __init__(self, obj_type, obj):
+        self.name = obj.preamble.name
+        self.id = obj.preamble.id
+        self._obj_type = obj_type
+        self._obj = obj
+        self.__doc__ = f"""
+A wrapper around the P4Info Protobuf message for
+{obj_type.pretty_name} '{self.name}'.
+You can access any field from the message with <self>.<field name>.
+You can access the name directly with <self>.name.
+You can access the id directly with <self>.id.
+If you need the underlying Protobuf message, you can access it with msg().
+"""
+
+    def __getattr__(self, name):
+        return getattr(self._obj, name)
+
+    def __settattr__(self, name, value):
+        return UserError(
+            f"Operation {name}:{value} not supported")
+
+    def msg(self):
+        """Get Protobuf message object"""
+        return self._obj
+
+    def actions(self):
+        """Print list of actions, only for tables and action profiles."""
+        if self._obj_type == P4Type.table:
+            for action in self._obj.action_refs:
+                print(CONTEXT.get_name_from_id(action.id))
+        elif self._obj_type == P4Type.action_profile:
+            t_id = self._obj.table_ids[0]
+            t_name = CONTEXT.get_name_from_id(t_id)
+            t = CONTEXT.get_table(t_name)
+            for action in t.action_refs:
+                print(CONTEXT.get_name_from_id(action.id))
+        else:
+            raise UserError(
+                "'actions' is only available for tables and action profiles")
+
+
+class P4Objects:
+    """
+    P4 objects.
+    """
+
+    def __init__(self, obj_type):
+        self._obj_type = obj_type
+        self._names = sorted([name for name, _ in CONTEXT.get_objs(obj_type)])
+        self._iter = None
+        self.__doc__ = """
+All the {pnames} in the P4 program.
+To access a specific {pname}, use {p4info}['<name>'].
+You can use this class to iterate over all {pname} instances:
+\tfor x in {p4info}:
+\t\tprint(x.id)
+""".format(pname=obj_type.pretty_name, pnames=obj_type.pretty_names,
+           p4info=obj_type.p4info_name)
+
+    def __getitem__(self, name):
+        obj = CONTEXT.get_obj(self._obj_type, name)
+        if obj is None:
+            raise UserError(
+                f"{self._obj_type.pretty_name} '{name}' does not exist")
+        return P4Object(self._obj_type, obj)
+
+    def __setitem__(self, name, value):
+        raise UserError("Operation not allowed")
+
+    def __iter__(self):
+        self._iter = iter(self._names)
+        return self
+
+    def __next__(self):
+        name = next(self._iter)
+        return self[name]
+
+
+class MatchKey:
+    """
+    P4 match key.
+    """
+
+    def __init__(self, table_name, match_fields):
+        self._table_name = table_name
+        self._fields = OrderedDict()
+        self._fields_suffixes = {}
+        for mf in match_fields:
+            self._add_field(mf)
+        self._mk = OrderedDict()
+        self._set_docstring()
+
+    def _set_docstring(self):
+        self.__doc__ = f"Match key fields for table '{self._table_name}':\n\n"
+        for _, info in self._fields.items():
+            self.__doc__ += str(info)
+        self.__doc__ += """
+Set a field value with <self>['<field_name>'] = '...'
+  * For exact match: <self>['<f>'] = '<value>'
+  * For ternary match: <self>['<f>'] = '<value>&&&<mask>'
+  * For LPM match: <self>['<f>'] = '<value>/<mask>'
+  * For range match: <self>['<f>'] = '<value>..<mask>'
+  * For optional match: <self>['<f>'] = '<value>'
+
+If it's inconvenient to use the whole field name, you can use a unique suffix.
+
+You may also use <self>.set(<f>='<value>')
+\t(<f> must not include a '.' in this case,
+but remember that you can use a unique suffix)
+"""
+
+    def _get_mf(self, name):
+        if name in self._fields:
+            return self._fields[name]
+        if name in self._fields_suffixes:
+            return self._fields[self._fields_suffixes[name]]
+        raise UserError(
+            f"'{name}' is not a valid match field name, nor a valid unique "
+            f"suffix, for table '{self._table_name}'")
+
+    def __setitem__(self, name, value):
+        field_info = self._get_mf(name)
+        self._mk[name] = self._parse_mf(value, field_info)
+        print(self._mk[name])
+
+    def __getitem__(self, name):
+        _ = self._get_mf(name)
+        print(self._mk.get(name, "Unset"))
+
+    def _parse_mf(self, s, field_info):
+        if not isinstance(s, str):
+            raise UserError("Match field value must be a string")
+        if field_info.match_type == p4info_pb2.MatchField.EXACT:
+            return self._parse_mf_exact(s, field_info)
+        if field_info.match_type == p4info_pb2.MatchField.LPM:
+            return self._parse_mf_lpm(s, field_info)
+        if field_info.match_type == p4info_pb2.MatchField.TERNARY:
+            return self._parse_mf_ternary(s, field_info)
+        if field_info.match_type == p4info_pb2.MatchField.RANGE:
+            return self._parse_mf_range(s, field_info)
+        if field_info.match_type == p4info_pb2.MatchField.OPTIONAL:
+            return self._parse_mf_optional(s, field_info)
+        raise UserError(
+            f"Unsupported match type for field:\n{field_info}")
+
+    def _parse_mf_exact(self, s, field_info):
+        v = encode(s.strip(), field_info.bitwidth)
+        return self._sanitize_and_convert_mf_exact(v, field_info)
+
+    def _sanitize_and_convert_mf_exact(self, value, field_info):
+        mf = p4runtime_pb2.FieldMatch()
+        mf.field_id = field_info.id
+        mf.exact.value = make_canonical_if_option_set(value)
+        return mf
+
+    def _parse_mf_optional(self, s, field_info):
+        v = encode(s.strip(), field_info.bitwidth)
+        return self._sanitize_and_convert_mf_optional(v, field_info)
+
+    def _sanitize_and_convert_mf_optional(self, value, field_info):
+        mf = p4runtime_pb2.FieldMatch()
+        mf.field_id = field_info.id
+        mf.optional.value = make_canonical_if_option_set(value)
+        return mf
+
+    def _parse_mf_lpm(self, s, field_info):
+        try:
+            prefix, length = s.split('/')
+            prefix, length = prefix.strip(), length.strip()
+        except ValueError:
+            prefix = s
+            length = str(field_info.bitwidth)
+
+        prefix = encode(prefix, field_info.bitwidth)
+        try:
+            length = int(length)
+        except ValueError as ex:
+            raise UserError(f"'{length}' is not a valid prefix length") from ex
+
+        return self._sanitize_and_convert_mf_lpm(prefix, length, field_info)
+
+    def _sanitize_and_convert_mf_lpm(self, prefix, length, field_info):
+        if length == 0:
+            raise UserError(
+                "Ignoring LPM don't care match (prefix length of 0) "
+                "as per P4Runtime spec")
+
+        mf = p4runtime_pb2.FieldMatch()
+        mf.field_id = field_info.id
+        mf.lpm.prefix_len = length
+
+        first_byte_masked = length // 8
+        if first_byte_masked == len(prefix):
+            mf.lpm.value = prefix
+            return mf
+
+        barray = bytearray(prefix)
+        transformed = False
+        r = length % 8
+        byte_mask = 0xff & ((0xff << (8 - r)))
+        if barray[first_byte_masked] & byte_mask != barray[first_byte_masked]:
+            transformed = True
+            barray[first_byte_masked] = barray[first_byte_masked] & byte_mask
+
+        for i in range(first_byte_masked + 1, len(prefix)):
+            if barray[i] != 0:
+                transformed = True
+                barray[i] = 0
+        if transformed:
+            print("LPM value was transformed to conform to the P4Runtime spec "
+                  "(trailing bits must be unset)")
+        mf.lpm.value = bytes(make_canonical_if_option_set(barray))
+        return mf
+
+    def _parse_mf_ternary(self, s, field_info):
+        try:
+            value, mask = s.split('&&&')
+            value, mask = value.strip(), mask.strip()
+        except ValueError:
+            value = s.strip()
+            mask = "0b" + ("1" * field_info.bitwidth)
+
+        value = encode(value, field_info.bitwidth)
+        mask = encode(mask, field_info.bitwidth)
+
+        return self._sanitize_and_convert_mf_ternary(value, mask, field_info)
+
+    def _sanitize_and_convert_mf_ternary(self, value, mask, field_info):
+        if int.from_bytes(mask, byteorder='big') == 0:
+            raise UserError(
+                "Ignoring ternary don't care match (mask of 0s) "
+                "as per P4Runtime spec")
+
+        mf = p4runtime_pb2.FieldMatch()
+        mf.field_id = field_info.id
+
+        barray = bytearray(value)
+        transformed = False
+        for i in range(len(value)):
+            if barray[i] & mask[i] != barray[i]:
+                transformed = True
+                barray[i] = barray[i] & mask[i]
+        if transformed:
+            print("Ternary value was transformed to conform to "
+                  "the P4Runtime spec (masked off bits must be unset)")
+        mf.ternary.value = bytes(
+            make_canonical_if_option_set(barray))
+        mf.ternary.mask = make_canonical_if_option_set(mask)
+        return mf
+
+    def _parse_mf_range(self, s, field_info):
+        try:
+            start, end = s.split('..')
+            start, end = start.strip(), end.strip()
+        except ValueError as ex:
+            raise UserError(f"'{s}' does not specify a valid range, "
+                            f"use '<start>..<end>'") from ex
+
+        start = encode(start, field_info.bitwidth)
+        end = encode(end, field_info.bitwidth)
+
+        return self._sanitize_and_convert_mf_range(start, end, field_info)
+
+    def _sanitize_and_convert_mf_range(self, start, end, field_info):
+        start_ = int.from_bytes(start, byteorder='big')
+        end_ = int.from_bytes(end, byteorder='big')
+        if start_ > end_:
+            raise UserError("Invalid range match: start is greater than end")
+        if start_ == 0 and end_ == ((1 << field_info.bitwidth) - 1):
+            raise UserError(
+                "Ignoring range don't care match (all possible values) "
+                "as per P4Runtime spec")
+        mf = p4runtime_pb2.FieldMatch()
+        mf.field_id = field_info.id
+        mf.range.low = make_canonical_if_option_set(start)
+        mf.range.high = make_canonical_if_option_set(end)
+        return mf
+
+    def _add_field(self, field_info):
+        self._fields[field_info.name] = field_info
+        self._recompute_suffixes()
+
+    def _recompute_suffixes(self):
+        suffixes = {}
+        suffix_count = Counter()
+        for fname in self._fields:
+            suffix = None
+            for s in reversed(fname.split(".")):
+                suffix = s if suffix is None else s + "." + suffix
+                suffixes[suffix] = fname
+                suffix_count[suffix] += 1
+        for suffix, c in suffix_count.items():
+            if c > 1:
+                del suffixes[suffix]
+        self._fields_suffixes = suffixes
+
+    def __str__(self):
+        return '\n'.join([str(mf) for name, mf in self._mk.items()])
+
+    def fields(self):
+        """
+        Return a list of match fields.
+
+        :return: list of match fields or None
+        """
+        fields = []
+        for name, _ in self._mk.items():
+            fields.append(name)
+        return fields
+
+    def value(self, field_name):
+        """
+        Get the value of a match field.
+
+        :param field_name: match field name
+        :return: match field value
+        """
+        for name, info in self._fields.items():
+            if name != field_name:
+                continue
+            if info.match_type == p4info_pb2.MatchField.EXACT:
+                return self._mk[name].exact.value.hex()
+            if info.match_type == p4info_pb2.MatchField.LPM:
+                return self._mk[name].lpm.value.hex()
+            if info.match_type == p4info_pb2.MatchField.TERNARY:
+                return self._mk[name].ternary.value.hex()
+            if info.match_type == p4info_pb2.MatchField.RANGE:
+                return self._mk[name].range.value.hex()
+            if info.match_type == p4info_pb2.MatchField.OPTIONAL:
+                return self._mk[name].optional.value.hex()
+        return None
+
+    def match_type(self, field_name):
+        """
+        Get the type of a match field.
+
+        :param field_name: match field name
+        :return: match field type
+        """
+        for name, info in self._fields.items():
+            if name not in field_name:
+                continue
+            return info.match_type
+        return None
+
+    def set(self, **kwargs):
+        """
+        Set match field parameter.
+
+        :param kwargs: parameters
+        :return: void
+        """
+        for name, value in kwargs.items():
+            self[name] = value
+
+    def clear(self):
+        """
+        Clear all match fields.
+
+        :return: void
+        """
+        self._mk.clear()
+
+    def _count(self):
+        return len(self._mk)
+
+
+class Action:
+    """
+    P4 action.
+    """
+
+    def __init__(self, action_name=None):
+        self._init = False
+        if action_name is None:
+            raise UserError("Please provide name for action")
+        self.action_name = action_name
+        action_info = CONTEXT.get_action(action_name)
+        if action_info is None:
+            raise UserError(f"Unknown action '{action_name}'")
+        self._action_id = action_info.preamble.id
+        self._params = OrderedDict()
+        for param in action_info.params:
+            self._params[param.name] = param
+        self._action_info = action_info
+        self._param_values = OrderedDict()
+        self._set_docstring()
+        self._init = True
+
+    def _set_docstring(self):
+        self.__doc__ = f"Action parameters for action '{self.action_name}':\n\n"
+        for _, info in self._params.items():
+            self.__doc__ += str(info)
+        self.__doc__ += "\n\n"
+        self.__doc__ += "Set a param value with " \
+                        "<self>['<param_name>'] = '<value>'\n"
+        self.__doc__ += "You may also use <self>.set(<param_name>='<value>')\n"
+
+    def _get_param(self, name):
+        if name not in self._params:
+            raise UserError("'{name}' is not a valid action parameter name "
+                            "for action '{self._action_name}'")
+        return self._params[name]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "action_name":
+            raise UserError("Cannot change action name")
+        super().__setattr__(name, value)
+
+    def __setitem__(self, name, value):
+        param_info = self._get_param(name)
+        self._param_values[name] = self._parse_param(value, param_info)
+        print(self._param_values[name])
+
+    def __getitem__(self, name):
+        _ = self._get_param(name)
+        print(self._param_values.get(name, "Unset"))
+
+    def _parse_param(self, s, param_info):
+        if not isinstance(s, str):
+            raise UserError("Action parameter value must be a string")
+        v = encode(s, param_info.bitwidth)
+        p = p4runtime_pb2.Action.Param()
+        p.param_id = param_info.id
+        p.value = make_canonical_if_option_set(v)
+        return p
+
+    def msg(self):
+        """
+        Create an action message.
+
+        :return: action message
+        """
+        msg = p4runtime_pb2.Action()
+        msg.action_id = self._action_id
+        msg.params.extend(self._param_values.values())
+        return msg
+
+    def _from_msg(self, msg):
+        assert self._action_id == msg.action_id
+        self._params.clear()
+        for p in msg.params:
+            p_name = CONTEXT.get_param_name(self.action_name, p.param_id)
+            self._param_values[p_name] = p
+
+    def __str__(self):
+        return str(self.msg())
+
+    def id(self):
+        """
+        Get action ID.
+
+        :return: action ID
+        """
+        return self._action_info.preamble.id
+
+    def alias(self):
+        """
+        Get action alias.
+
+        :return: action alias
+        """
+        return str(self._action_info.preamble.alias)
+
+    def set(self, **kwargs):
+        """
+        Set action parameters.
+
+        :param kwargs: parameters
+        :return: void
+        """
+        for name, value in kwargs.items():
+            self[name] = value
+
+
+class _EntityBase:
+    """
+    Basic entity.
+    """
+
+    def __init__(self, entity_type, p4runtime_cls, modify_only=False):
+        self._init = False
+        self._entity_type = entity_type
+        self._entry = p4runtime_cls()
+        self._modify_only = modify_only
+
+    def __dir__(self):
+        d = ["msg", "read"]
+        if self._modify_only:
+            d.append("modify")
+        else:
+            d.extend(["insert", "modify", "delete"])
+        return d
+
+    # to be called before issuing a P4Runtime request
+    # enforces checks that cannot be performed when setting individual fields
+    def _validate_msg(self):
+        return True
+
+    def _update_msg(self):
+        pass
+
+    def __getattr__(self, name):
+        raise AttributeError(f"'{self.__class__.__name__}' object "
+                             f"has no attribute '{name}'")
+
+    def msg(self):
+        """
+        Get a basic entity message.
+
+        :return: entity message
+        """
+        self._update_msg()
+        return self._entry
+
+    def _write(self, type_):
+        self._update_msg()
+        self._validate_msg()
+        update = p4runtime_pb2.Update()
+        update.type = type_
+        getattr(update.entity, self._entity_type.name).CopyFrom(self._entry)
+        CLIENT.write_update(update)
+
+    def insert(self):
+        """
+        Insert an entity.
+
+        :return: void
+        """
+        if self._modify_only:
+            raise NotImplementedError(
+                f"Insert not supported for {self._entity_type.name}")
+        logging.debug("Inserting entry")
+        self._write(p4runtime_pb2.Update.INSERT)
+
+    def delete(self):
+        """
+        Delete an entity.
+
+        :return: void
+        """
+        if self._modify_only:
+            raise NotImplementedError(
+                f"Delete not supported for {self._entity_type.name}")
+        logging.debug("Deleting entry")
+        self._write(p4runtime_pb2.Update.DELETE)
+
+    def modify(self):
+        """
+        Modify an entity.
+
+        :return: void
+        """
+        logging.debug("Modifying entry")
+        self._write(p4runtime_pb2.Update.MODIFY)
+
+    def _from_msg(self, msg):
+        raise NotImplementedError
+
+    def read(self, function=None):
+        """
+        Read an entity.
+
+        :param function: function to read (optional)
+        :return: retrieved entity
+        """
+        # Entities should override this method and provide a helpful docstring
+        self._update_msg()
+        self._validate_msg()
+        entity = p4runtime_pb2.Entity()
+        getattr(entity, self._entity_type.name).CopyFrom(self._entry)
+
+        iterator = CLIENT.read_one(entity)
+
+        # Cannot use a (simpler) generator here as we need to
+        # decorate __next__ with @parse_p4runtime_error.
+        class _EntryIterator:
+            def __init__(self, entity, it):
+                self._entity = entity
+                self._it = it
+                self._entities_it = None
+
+            def __iter__(self):
+                return self
+
+            @parse_p4runtime_error
+            def __next__(self):
+                if self._entities_it is None:
+                    rep = next(self._it)
+                    self._entities_it = iter(rep.entities)
+                try:
+                    entity = next(self._entities_it)
+                except StopIteration:
+                    self._entities_it = None
+                    return next(self)
+
+                if isinstance(self._entity, _P4EntityBase):
+                    ent = type(self._entity)(
+                        self._entity.name)  # create new instance of same entity
+                else:
+                    ent = type(self._entity)()
+                msg = getattr(entity, self._entity._entity_type.name)
+                ent._from_msg(msg)
+                # neither of these should be needed
+                # ent._update_msg()
+                # ent._entry.CopyFrom(msg)
+                return ent
+
+        if function is None:
+            return _EntryIterator(self, iterator)
+        for x in _EntryIterator(self, iterator):
+            function(x)
+
+
+class _P4EntityBase(_EntityBase):
+    """
+    Basic P4 entity.
+    """
+
+    def __init__(self, p4_type, entity_type, p4runtime_cls, name=None,
+                 modify_only=False):
+        super().__init__(entity_type, p4runtime_cls, modify_only)
+        self._p4_type = p4_type
+        if name is None:
+            raise UserError(
+                f"Please provide name for {p4_type.pretty_name}")
+        self.name = name
+        self._info = P4Objects(p4_type)[name]
+        self.id = self._info.id
+
+    def __dir__(self):
+        return super().__dir__() + ["name", "id", "info"]
+
+    def _from_msg(self, msg):
+        raise NotImplementedError
+
+    def info(self):
+        """
+        Display P4Info entry for the object.
+
+        :return: P4 info entry
+        """
+        return self._info
+
+
+class ActionProfileMember(_P4EntityBase):
+    """
+    P4 action profile member.
+    """
+
+    def __init__(self, action_profile_name=None):
+        super().__init__(
+            P4Type.action_profile, P4RuntimeEntity.action_profile_member,
+            p4runtime_pb2.ActionProfileMember, action_profile_name)
+        self.member_id = 0
+        self.action = None
+        self._valid_action_ids = self._get_action_set()
+        self.__doc__ = f"""
+An action profile member for '{action_profile_name}'
+
+Use <self>.info to display the P4Info entry for the action profile.
+
+Set the member id with <self>.member_id = <expr>.
+
+To set the action specification <self>.action = <instance of type Action>.
+To set the value of action parameters,
+use <self>.action['<param name>'] = <expr>.
+Type <self>.action? for more details.
+
+
+Typical usage to insert an action profile member:
+m = action_profile_member['<action_profile_name>'](action='<action_name>',
+member_id=1)
+m.action['<p1>'] = ...
+...
+m.action['<pM>'] = ...
+# OR m.action.set(p1=..., ..., pM=...)
+m.insert
+
+For information about how to read members, use <self>.read?
+"""
+        self._init = True
+
+    def __dir__(self):
+        return super().__dir__() + ["member_id", "action"]
+
+    def _get_action_set(self):
+        t_id = self._info.table_ids[0]
+        t_name = CONTEXT.get_name_from_id(t_id)
+        t = CONTEXT.get_table(t_name)
+        return {action.id for action in t.action_refs}
+
+    def __call__(self, **kwargs):
+        for name, value in kwargs.items():
+            if name == "action" and isinstance(value, str):
+                value = Action(value)
+            setattr(self, name, value)
+        return self
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "name":
+            raise UserError("Cannot change action profile name")
+        if name == "member_id":
+            if not isinstance(value, int):
+                raise UserError("member_id must be an integer")
+        if name == "action" and value is not None:
+            if not isinstance(value, Action):
+                raise UserError("action must be an instance of Action")
+            if not self._is_valid_action_id(value._action_id):
+                raise UserError(f"action '{value.action_name}' is not a valid "
+                                f"action for this action profile")
+        super().__setattr__(name, value)
+
+    def _is_valid_action_id(self, action_id):
+        return action_id in self._valid_action_ids
+
+    def _update_msg(self):
+        self._entry.action_profile_id = self.id
+        self._entry.member_id = self.member_id
+        if self.action is not None:
+            self._entry.action.CopyFrom(self.action.msg())
+
+    def _from_msg(self, msg):
+        self.member_id = msg.member_id
+        if msg.HasField('action'):
+            action = msg.action
+            action_name = CONTEXT.get_name_from_id(action.action_id)
+            self.action = Action(action_name)
+            self.action._from_msg(action)
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the appropriate fields unset).
+
+        If function is None, returns an iterator. Iterate over it to get all the
+        members (as ActionProfileMember instances) returned by the
+        server. Otherwise, function is applied to all the members returned
+        by the server.
+        """
+        return super().read(function)
+
+
+class GroupMember:
+    """
+    P4 group member.
+
+    A member in an ActionProfileGroup.
+    Construct with GroupMember(<member_id>, weight=<weight>, watch=<watch>,
+    watch_port=<watch_port>).
+    You can set / get attributes member_id (required), weight (default 1),
+    watch (default 0), watch_port (default "").
+    """
+
+    def __init__(self, member_id=None, weight=1, watch=0, watch_port=b""):
+        if member_id is None:
+            raise UserError("member_id is required")
+        self._msg = p4runtime_pb2.ActionProfileGroup.Member()
+        self._msg.member_id = member_id
+        self._msg.weight = weight
+        if watch:
+            self._msg.watch = watch
+        if watch_port:
+            self._msg.watch_port = watch_port
+
+    def __dir__(self):
+        return ["member_id", "weight", "watch", "watch_port"]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name == "member_id":
+            if not isinstance(value, int):
+                raise UserError("member_id must be an integer")
+            self._msg.member_id = value
+            return
+        if name == "weight":
+            if not isinstance(value, int):
+                raise UserError("weight must be an integer")
+            self._msg.weight = value
+            return
+        if name == "watch":
+            if not isinstance(value, int):
+                raise UserError("watch must be an integer")
+            self._msg.watch = value
+            return
+        if name == "watch_port":
+            if not isinstance(value, bytes):
+                raise UserError("watch_port must be a byte string")
+            self._msg.watch_port = value
+            return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name == "member_id":
+            return self._msg.member_id
+        if name == "weight":
+            return self._msg.weight
+        if name == "watch":
+            return self._msg.watch
+        if name == "watch_port":
+            return self._msg.watch_port
+        return super().__getattr__(name)
+
+    def __str__(self):
+        return str(self._msg)
+
+
+class ActionProfileGroup(_P4EntityBase):
+    """
+    P4 action profile group.
+    """
+
+    def __init__(self, action_profile_name=None):
+        super().__init__(
+            P4Type.action_profile, P4RuntimeEntity.action_profile_group,
+            p4runtime_pb2.ActionProfileGroup, action_profile_name)
+        self.group_id = 0
+        self.max_size = 0
+        self.members = []
+        self.__doc__ = f"""
+An action profile group for '{action_profile_name}'
+
+Use <self>.info to display the P4Info entry for the action profile.
+
+Set the group id with <self>.group_id = <expr>. Default is 0.
+Set the max size with <self>.max_size = <expr>. Default is 0.
+
+Add members to the group with <self>.add(<member_id>, weight=<weight>, watch=<watch>,
+watch_port=<watch_port>).
+weight, watch and watch port are optional (default to 1, 0 and "" respectively).
+
+Typical usage to insert an action profile group:
+g = action_profile_group['<action_profile_name>'](group_id=1)
+g.add(<member id 1>)
+g.add(<member id 2>)
+# OR g.add(<member id 1>).add(<member id 2>)
+
+For information about how to read groups, use <self>.read?
+"""
+        self._init = True
+
+    def __dir__(self):
+        return super().__dir__() + ["group_id", "max_size", "members", "add",
+                                    "clear"]
+
+    def __call__(self, **kwargs):
+        for name, value in kwargs.items():
+            setattr(self, name, value)
+        return self
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "name":
+            raise UserError("Cannot change action profile name")
+        if name == "group_id":
+            if not isinstance(value, int):
+                raise UserError("group_id must be an integer")
+        if name == "members":
+            if not isinstance(value, list):
+                raise UserError("members must be a list of GroupMember objects")
+            for member in value:
+                if not isinstance(member, GroupMember):
+                    raise UserError(
+                        "members must be a list of GroupMember objects")
+        super().__setattr__(name, value)
+
+    def add(self, member_id=None, weight=1, watch=0, watch_port=b""):
+        """Add a member to the members list."""
+        self.members.append(GroupMember(member_id, weight, watch, watch_port))
+        return self
+
+    def clear(self):
+        """Empty members list."""
+        self.members = []
+
+    def _update_msg(self):
+        self._entry.action_profile_id = self.id
+        self._entry.group_id = self.group_id
+        self._entry.max_size = self.max_size
+        del self._entry.members[:]
+        for member in self.members:
+            if not isinstance(member, GroupMember):
+                raise UserError("members must be a list of GroupMember objects")
+            m = self._entry.members.add()
+            m.CopyFrom(member._msg)
+
+    def _from_msg(self, msg):
+        self.group_id = msg.group_id
+        self.max_size = msg.max_size
+        self.members = []
+        for member in msg.members:
+            self.add(member.member_id, member.weight, member.watch,
+                     member.watch_port)
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the appropriate fields unset).
+
+        If function is None, returns an iterator. Iterate over it to get all the
+        members (as ActionProfileGroup instances) returned by the
+        server. Otherwise, function is applied to all the groups returned by the
+        server.
+        """
+        return super().read(function)
+
+
+def _get_action_profile(table_name):
+    table = CONTEXT.get_table(table_name)
+    implementation_id = table.implementation_id
+    if implementation_id == 0:
+        return None
+    try:
+        implementation_name = CONTEXT.get_name_from_id(implementation_id)
+    except KeyError as ex:
+        raise InvalidP4InfoError(
+            f"Invalid implementation_id {implementation_id} for "
+            f"table '{table_name}'") from ex
+    ap = CONTEXT.get_obj(P4Type.action_profile, implementation_name)
+    if ap is None:
+        raise InvalidP4InfoError(
+            f"Unknown implementation for table '{table_name}'")
+    return ap
+
+
+class OneshotAction:
+    """
+    A P4 action in a oneshot action set.
+    Construct with OneshotAction(<action (Action instance)>,
+    weight=<weight>, watch=<watch>, watch_port=<watch_port>).
+    You can set / get attributes action (required), weight (default 1),
+    watch (default 0), watch_port (default "").
+    """
+
+    def __init__(self, action=None, weight=1, watch=0, watch_port=b""):
+        if action is None:
+            raise UserError("action is required")
+        self.action = action
+        self.weight = weight
+        self.watch = watch
+        self.watch_port = watch_port
+
+    def __dir__(self):
+        return ["action", "weight", "watch", "watch_port", "msg"]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name == "action":
+            if not isinstance(value, Action):
+                raise UserError("action must be an instance of Action")
+        elif name == "weight":
+            if not isinstance(value, int):
+                raise UserError("weight must be an integer")
+        elif name == "watch":
+            if not isinstance(value, int):
+                raise UserError("watch must be an integer")
+        elif name == "watch_port":
+            print(type(value), value)
+            if not isinstance(value, bytes):
+                raise UserError("watch_port must be a byte string")
+        super().__setattr__(name, value)
+
+    def msg(self):
+        """
+        Create an one shot action message.
+
+        :return: one shot action message
+        """
+        msg = p4runtime_pb2.ActionProfileAction()
+        msg.action.CopyFrom(self.action.msg())
+        msg.weight = self.weight
+        if self.watch:
+            msg.watch = self.watch
+        if self.watch_port:
+            msg.watch_port = self.watch_port
+        return msg
+
+    def __str__(self):
+        return str(self.msg())
+
+
+class Oneshot:
+    """
+    One shot action set.
+    """
+
+    def __init__(self, table_name=None):
+        self._init = False
+        if table_name is None:
+            raise UserError("Please provide table name")
+        self.table_name = table_name
+        self.actions = []
+        self._table_info = P4Objects(P4Type.table)[table_name]
+        ap = _get_action_profile(table_name)
+        if not ap:
+            raise UserError("Cannot create Oneshot instance for a direct table")
+        if not ap.with_selector:
+            raise UserError(
+                "Cannot create Oneshot instance for a table "
+                "with an action profile without selector")
+        self.__doc__ = f"""
+A "oneshot" action set for table '{self.table_name}'.
+
+To add an action to the set, use <self>.add(<Action instance>).
+You can also access the set of actions with <self>.actions (which is a Python list).
+"""
+        self._init = True
+
+    def __dir__(self):
+        return ["table_name", "actions", "add", "msg"]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "table_name":
+            raise UserError("Cannot change table name")
+        if name == "actions":
+            if not isinstance(value, list):
+                raise UserError(
+                    "actions must be a list of OneshotAction objects")
+            for member in value:
+                if not isinstance(member, OneshotAction):
+                    raise UserError(
+                        "actions must be a list of OneshotAction objects")
+                if not self._is_valid_action_id(value.action._action_id):
+                    raise UserError(
+                        f"action '{value.action.action_name}' is not a valid "
+                        f"action for table {self.table_name}")
+        super().__setattr__(name, value)
+
+    def _is_valid_action_id(self, action_id):
+        for action_ref in self._table_info.action_refs:
+            if action_id == action_ref.id:
+                return True
+        return False
+
+    def add(self, action=None, weight=1, watch=0, watch_port=b""):
+        """
+        Add an action to the oneshot action set.
+
+        :param action: action object
+        :param weight: weight (integer)
+        :param watch: watch (integer)
+        :param watch_port: watch port
+        :return:
+        """
+        self.actions.append(OneshotAction(action, weight, watch, watch_port))
+        return self
+
+    def msg(self):
+        """
+        Create an action profile message.
+
+        :return: action profile message
+        """
+        msg = p4runtime_pb2.ActionProfileActionSet()
+        msg.action_profile_actions.extend(
+            [action.msg() for action in self.actions])
+        return msg
+
+    def _from_msg(self, msg):
+        for action in msg.action_profile_actions:
+            action_name = CONTEXT.get_name_from_id(action.action.action_id)
+            a = Action(action_name)
+            a._from_msg(action.action)
+            self.actions.append(OneshotAction(a, action.weight, action.watch,
+                                              action.watch_port))
+
+    def __str__(self):
+        return str(self.msg())
+
+
+class _CounterData:
+    """
+    P4 counter data.
+    """
+
+    @staticmethod
+    def attrs_for_counter_type(counter_type):
+        """
+        Return counter attributes.
+
+        :param counter_type: P4 counter type
+        :return: list of counter attributes
+        """
+        attrs = []
+        if counter_type in {p4info_pb2.CounterSpec.BYTES,
+                            p4info_pb2.CounterSpec.BOTH}:
+            attrs.append("byte_count")
+        if counter_type in {p4info_pb2.CounterSpec.PACKETS,
+                            p4info_pb2.CounterSpec.BOTH}:
+            attrs.append("packet_count")
+        return attrs
+
+    def __init__(self, counter_name, counter_type):
+        self._counter_name = counter_name
+        self._counter_type = counter_type
+        self._msg = p4runtime_pb2.CounterData()
+        self._attrs = _CounterData.attrs_for_counter_type(counter_type)
+
+    def __dir__(self):
+        return self._attrs
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name not in self._attrs:
+            type_name = p4info_pb2._COUNTERSPEC_UNIT.values_by_number[
+                self._counter_type].name
+            raise UserError(
+                f"Counter '{self._counter_name}' is of type '{type_name}', "
+                f"you cannot set '{name}'")
+        if not isinstance(value, int):
+            raise UserError(f"{name} must be an integer")
+        setattr(self._msg, name, value)
+
+    def __getattr__(self, name):
+        if name in ("byte_count", "packet_count"):
+            return getattr(self._msg, name)
+        raise AttributeError(f"'{self.__class__.__name__}' object has no "
+                             f"attribute '{name}'")
+
+    def msg(self):
+        """
+        Create a counter data message.
+
+        :return: counter data message
+        """
+        return self._msg
+
+    def _from_msg(self, msg):
+        self._msg.CopyFrom(msg)
+
+    def __str__(self):
+        return str(self.msg())
+
+    @classmethod
+    def set_count(cls, instance, counter_name, counter_type, name, value):
+        """
+        Set the value of a certain counter.
+
+        :param instance: counter instance
+        :param counter_name: counter name
+        :param counter_type: counter type
+        :param name: counter attribute name
+        :param value: counter attribute value
+        :return: updated counter instance
+        """
+        if instance is None:
+            d = cls(counter_name, counter_type)
+        else:
+            d = instance
+        setattr(d, name, value)
+        return d
+
+    @classmethod
+    def get_count(cls, instance, counter_name, counter_type, name):
+        """
+        Get the value of a certain counter.
+
+        :param instance:
+        :param counter_name: counter name
+        :param counter_type: counter type
+        :param name: counter attribute name
+        :return: counter name and value
+        """
+        if instance is None:
+            d = cls(counter_name, counter_type)
+        else:
+            d = instance
+        r = getattr(d, name)
+        return d, r
+
+
+class _MeterConfig:
+    """
+    P4 meter configuration.
+    """
+
+    @staticmethod
+    def attrs():
+        """
+        Get the attributes in this scope.
+
+        :return: list of scope attributes
+        """
+        return ["cir", "cburst", "pir", "pburst"]
+
+    def __init__(self, meter_name, meter_type):
+        self._meter_name = meter_name
+        self._meter_type = meter_type
+        self._msg = p4runtime_pb2.MeterConfig()
+        self._attrs = _MeterConfig.attrs()
+
+    def __dir__(self):
+        return self._attrs
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name in self._attrs:
+            if not isinstance(value, int):
+                raise UserError(f"{name} must be an integer")
+        setattr(self._msg, name, value)
+
+    def __getattr__(self, name):
+        if name in self._attrs:
+            return getattr(self._msg, name)
+        raise AttributeError(
+            f"'{self.__class__.__name__}' object has no attribute '{name}'")
+
+    def msg(self):
+        """
+        Create a meter config message.
+
+        :return: meter config message
+        """
+        return self._msg
+
+    def _from_msg(self, msg):
+        self._msg.CopyFrom(msg)
+
+    def __str__(self):
+        return str(self.msg())
+
+    @classmethod
+    def set_param(cls, instance, meter_name, meter_type, name, value):
+        """
+        Set the value of a certain meter parameter.
+
+        :param instance: meter instance
+        :param meter_name: meter name
+        :param meter_type: meter type
+        :param name: meter parameter name
+        :param value: meter parameter value
+        :return: updated meter
+        """
+        if instance is None:
+            d = cls(meter_name, meter_type)
+        else:
+            d = instance
+        setattr(d, name, value)
+        return d
+
+    @classmethod
+    def get_param(cls, instance, meter_name, meter_type, name):
+        """
+        Get the value of a certain meter parameter.
+
+        :param instance: meter instance
+        :param meter_name: meter name
+        :param meter_type: meter type
+        :param name: meter parameter name
+        :return: meter with parameter
+        """
+        if instance is None:
+            d = cls(meter_name, meter_type)
+        else:
+            d = instance
+        r = getattr(d, name)
+        return d, r
+
+
+class _IdleTimeout:
+    """
+    P4 idle timeout.
+    """
+
+    @staticmethod
+    def attrs():
+        """
+        Get the attributes in this scope.
+
+        :return: list of scope attributes
+        """
+        return ["elapsed_ns"]
+
+    def __init__(self):
+        self._msg = p4runtime_pb2.TableEntry.IdleTimeout()
+        self._attrs = _IdleTimeout.attrs()
+
+    def __dir__(self):
+        return self._attrs
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name in self._attrs:
+            if not isinstance(value, int):
+                raise UserError(f"{name} must be an integer")
+        setattr(self._msg, name, value)
+
+    def __getattr__(self, name):
+        if name in self._attrs:
+            return getattr(self._msg, name)
+        raise AttributeError(
+            f"'{self.__class__.__name__}' object has no attribute '{name}'")
+
+    def msg(self):
+        """
+        Create an idle timeout message.
+
+        :return: idle timeout message
+        """
+        return self._msg
+
+    def _from_msg(self, msg):
+        self._msg.CopyFrom(msg)
+
+    def __str__(self):
+        return str(self.msg())
+
+    @classmethod
+    def set_param(cls, instance, name, value):
+        """
+        Set the value of a certain idle timeout parameter.
+
+        :param instance: idle timeout instance
+        :param name: idle timeout parameter name
+        :param value: idle timeout parameter value
+        :return: updated idle timeout instance
+        """
+        if instance is None:
+            d = cls()
+        else:
+            d = instance
+        setattr(d, name, value)
+        return d
+
+    @classmethod
+    def get_param(cls, instance, name):
+        """
+        Set the value of a certain idle timeout parameter.
+
+        :param instance: idle timeout instance
+        :param name: idle timeout parameter name
+        :return: idle timeout instance with parameter
+        """
+        if instance is None:
+            d = cls()
+        else:
+            d = instance
+        r = getattr(d, name)
+        return d, r
+
+
+class TableEntry(_P4EntityBase):
+    """
+    P4 table entry.
+    """
+
+    @enum.unique
+    class _ActionSpecType(enum.Enum):
+        NONE = 0
+        DIRECT_ACTION = 1
+        MEMBER_ID = 2
+        GROUP_ID = 3
+        ONESHOT = 4
+
+    @classmethod
+    def _action_spec_name_to_type(cls, name):
+        return {
+            "action": cls._ActionSpecType.DIRECT_ACTION,
+            "member_id": cls._ActionSpecType.MEMBER_ID,
+            "group_id": cls._ActionSpecType.GROUP_ID,
+            "oneshot": cls._ActionSpecType.ONESHOT,
+        }.get(name, None)
+
+    def __init__(self, table_name=None):
+        super().__init__(
+            P4Type.table, P4RuntimeEntity.table_entry,
+            p4runtime_pb2.TableEntry, table_name)
+        self.match = MatchKey(table_name, self._info.match_fields)
+        self._action_spec_type = self._ActionSpecType.NONE
+        self._action_spec = None
+        self.action: Action
+        self.member_id = -1
+        self.group_id = -1
+        self.oneshot = None
+        self.priority = 0
+        self.is_default = False
+        ap = _get_action_profile(table_name)
+        if ap is None:
+            self._support_members = False
+            self._support_groups = False
+        else:
+            self._support_members = True
+            self._support_groups = ap.with_selector
+        self._direct_counter = None
+        self._direct_meter = None
+        for res_id in self._info.direct_resource_ids:
+            prefix = (res_id & 0xff000000) >> 24
+            if prefix == p4info_pb2.P4Ids.DIRECT_COUNTER:
+                self._direct_counter = CONTEXT.get_obj_by_id(res_id)
+            elif prefix == p4info_pb2.P4Ids.DIRECT_METER:
+                self._direct_meter = CONTEXT.get_obj_by_id(res_id)
+        self._counter_data = None
+        self._meter_config = None
+        self.idle_timeout_ns = 0
+        self._time_since_last_hit = None
+        self._idle_timeout_behavior = None
+        table = CONTEXT.get_table(table_name)
+        if table.idle_timeout_behavior > 0:
+            self._idle_timeout_behavior = table.idle_timeout_behavior
+        self.metadata = b""
+        self.__doc__ = f"""
+An entry for table '{table_name}'
+
+Use <self>.info to display the P4Info entry for this table.
+
+To set the match key, use <self>.match['<field name>'] = <expr>.
+Type <self>.match? for more details.
+"""
+        if self._direct_counter is not None:
+            self.__doc__ += """
+To set the counter spec, use <self>.counter_data.byte_count and/or <self>.counter_data.packet_count.
+To unset it, use <self>.counter_data = None or <self>.clear_counter_data().
+"""
+        if self._direct_meter is not None:
+            self.__doc__ += """
+To access the meter config, use <self>.meter_config.<cir|cburst|pir|pburst>.
+To unset it, use <self>.meter_config = None or <self>.clear_meter_config().
+"""
+        if ap is None:
+            self.__doc__ += """
+To set the action specification (this is a direct table):
+<self>.action = <instance of type Action>.
+To set the value of action parameters, use <self>.action['<param name>'] = <expr>.
+Type <self>.action? for more details.
+"""
+        if self._support_members:
+            self.__doc__ += """
+Access the member_id with <self>.member_id.
+"""
+        if self._support_groups:
+            self.__doc__ += """
+Or access the group_id with <self>.group_id.
+"""
+        if self._idle_timeout_behavior is not None:
+            self.__doc__ += """
+To access the time this entry was last hit, use <self>.time_since_last_hit.elapsed_ns.
+To unset it, use <self>.time_since_last_hit = None or <self>.clear_time_since_last_hit().
+"""
+        self.__doc__ += """
+To set the priority, use <self>.priority = <expr>.
+
+To mark the entry as default, use <self>.is_default = True.
+
+To add an idle timeout to the entry, use <self>.idle_timeout_ns = <expr>.
+
+To add metadata to the entry, use <self>.metadata = <expr>.
+"""
+        if ap is None:
+            self.__doc__ += """
+Typical usage to insert a table entry:
+t = table_entry['<table_name>'](action='<action_name>')
+t.match['<f1>'] = ...
+...
+t.match['<fN>'] = ...
+# OR t.match.set(f1=..., ..., fN=...)
+t.action['<p1>'] = ...
+...
+t.action['<pM>'] = ...
+# OR t.action.set(p1=..., ..., pM=...)
+t.insert
+
+Typical usage to set the default entry:
+t = table_entry['<table_name>'](is_default=True)
+t.action['<p1>'] = ...
+...
+t.action['<pM>'] = ...
+# OR t.action.set(p1=..., ..., pM=...)
+t.modify
+"""
+        else:
+            self.__doc__ += """
+Typical usage to insert a table entry:
+t = table_entry['<table_name>']
+t.match['<f1>'] = ...
+...
+t.match['<fN>'] = ...
+# OR t.match.set(f1=..., ..., fN=...)
+t.member_id = <expr>
+"""
+        self.__doc__ += """
+For information about how to read table entries, use <self>.read?
+"""
+
+        self._init = True
+
+    def __dir__(self):
+        d = super().__dir__() + [
+            "match", "priority", "is_default", "idle_timeout_ns", "metadata",
+            "clear_action", "clear_match", "clear_counter_data",
+            "clear_meter_config",
+            "clear_time_since_last_hit"]
+        if self._support_groups:
+            d.extend(["member_id", "group_id", "oneshot"])
+        elif self._support_members:
+            d.append("member_id")
+        else:
+            d.append("action")
+        if self._direct_counter is not None:
+            d.append("counter_data")
+        if self._direct_meter is not None:
+            d.append("meter_config")
+        if self._idle_timeout_behavior is not None:
+            d.append("time_since_last_hit")
+        return d
+
+    def __call__(self, **kwargs):
+        for name, value in kwargs.items():
+            if name == "action" and isinstance(value, str):
+                value = Action(value)
+            setattr(self, name, value)
+        return self
+
+    def _action_spec_set_member(self, member_id):
+        if isinstance(member_id, type(None)):
+            if self._action_spec_type == self._ActionSpecType.MEMBER_ID:
+                super().__setattr__("_action_spec_type",
+                                    self._ActionSpecType.NONE)
+                super().__setattr__("_action_spec", None)
+            return
+        if not isinstance(member_id, int):
+            raise UserError("member_id must be an integer")
+        if not self._support_members:
+            raise UserError("Table does not have an action profile and "
+                            "therefore does not support members")
+        super().__setattr__("_action_spec_type", self._ActionSpecType.MEMBER_ID)
+        super().__setattr__("_action_spec", member_id)
+
+    def _action_spec_set_group(self, group_id):
+        if isinstance(group_id, type(None)):
+            if self._action_spec_type == self._ActionSpecType.GROUP_ID:
+                super().__setattr__("_action_spec_type",
+                                    self._ActionSpecType.NONE)
+                super().__setattr__("_action_spec", None)
+            return
+        if not isinstance(group_id, int):
+            raise UserError("group_id must be an integer")
+        if not self._support_groups:
+            raise UserError(
+                "Table does not have an action profile with selector "
+                "and therefore does not support groups")
+        super().__setattr__("_action_spec_type", self._ActionSpecType.GROUP_ID)
+        super().__setattr__("_action_spec", group_id)
+
+    def _action_spec_set_action(self, action):
+        if isinstance(action, type(None)):
+            if self._action_spec_type == self._ActionSpecType.DIRECT_ACTION:
+                super().__setattr__("_action_spec_type",
+                                    self._ActionSpecType.NONE)
+                super().__setattr__("_action_spec", None)
+            return
+        if not isinstance(action, Action):
+            raise UserError("action must be an instance of Action")
+        if self._info.implementation_id != 0:
+            raise UserError(
+                "Table has an implementation and therefore "
+                "does not support direct actions (P4Runtime 1.0 doesn't "
+                "support writing the default action for indirect tables")
+        if not self._is_valid_action_id(action._action_id):
+            raise UserError(f"action '{action.action_name}' is not a valid "
+                            f"action for this table")
+        super().__setattr__("_action_spec_type",
+                            self._ActionSpecType.DIRECT_ACTION)
+        super().__setattr__("_action_spec", action)
+
+    def _action_spec_set_oneshot(self, oneshot):
+        if isinstance(oneshot, type(None)):
+            if self._action_spec_type == self._ActionSpecType.ONESHOT:
+                super().__setattr__("_action_spec_type",
+                                    self._ActionSpecType.NONE)
+                super().__setattr__("_action_spec", None)
+            return
+        if not isinstance(oneshot, Oneshot):
+            raise UserError("oneshot must be an instance of Oneshot")
+        if not self._support_groups:
+            raise UserError(
+                "Table does not have an action profile with selector "
+                "and therefore does not support oneshot programming")
+        if self.name != oneshot.table_name:
+            raise UserError(
+                "This Oneshot instance was not created for this table")
+        super().__setattr__("_action_spec_type", self._ActionSpecType.ONESHOT)
+        super().__setattr__("_action_spec", oneshot)
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "name":
+            raise UserError("Cannot change table name")
+        if name == "priority":
+            if not isinstance(value, int):
+                raise UserError("priority must be an integer")
+        if name == "match" and not isinstance(value, MatchKey):
+            raise UserError("match must be an instance of MatchKey")
+        if name == "is_default":
+            if not isinstance(value, bool):
+                raise UserError("is_default must be a boolean")
+            # TODO: handle other cases  # pylint: disable=W0511
+            # is_default is set to True)?
+            if value is True and self.match._count() > 0:
+                print("Clearing match key because entry is now default")
+                self.match.clear()
+        if name == "member_id":
+            self._action_spec_set_member(value)
+            return
+        if name == "group_id":
+            self._action_spec_set_group(value)
+            return
+        if name == "oneshot":
+            self._action_spec_set_oneshot(value)
+        if name == "action" and value is not None:
+            self._action_spec_set_action(value)
+            return
+        if name == "counter_data":
+            if self._direct_counter is None:
+                raise UserError("Table has no direct counter")
+            if value is None:
+                self._counter_data = None
+                return
+            raise UserError("Cannot set 'counter_data' directly")
+        if name == "meter_config":
+            if self._direct_meter is None:
+                raise UserError("Table has no direct meter")
+            if value is None:
+                self._meter_config = None
+                return
+            raise UserError("Cannot set 'meter_config' directly")
+        if name == "idle_timeout_ns":
+            if not isinstance(value, int):
+                raise UserError("idle_timeout_ns must be an integer")
+        if name == "time_since_last_hit":
+            if self._idle_timeout_behavior is None:
+                raise UserError("Table has no idle timeouts")
+            if value is None:
+                self._time_since_last_hit = None
+                return
+            raise UserError("Cannot set 'time_since_last_hit' directly")
+        if name == "metadata":
+            if not isinstance(value, bytes):
+                raise UserError("metadata must be a byte string")
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name == "counter_data":
+            if self._direct_counter is None:
+                raise UserError("Table has no direct counter")
+            if self._counter_data is None:
+                self._counter_data = _CounterData(
+                    self._direct_counter.preamble.name,
+                    self._direct_counter.spec.unit)
+            return self._counter_data
+        if name == "meter_config":
+            if self._direct_meter is None:
+                raise UserError("Table has no direct meter")
+            if self._meter_config is None:
+                self._meter_config = _MeterConfig(
+                    self._direct_meter.preamble.name,
+                    self._direct_meter.spec.unit)
+            return self._meter_config
+        if name == "time_since_last_hit":
+            if self._idle_timeout_behavior is None:
+                raise UserError("Table has no idle timeouts")
+            if self._time_since_last_hit is None:
+                self._time_since_last_hit = _IdleTimeout()
+            return self._time_since_last_hit
+
+        t = self._action_spec_name_to_type(name)
+        if t is None:
+            return super().__getattr__(name)
+        if self._action_spec_type == t:
+            return self._action_spec
+        if t == self._ActionSpecType.ONESHOT:
+            self._action_spec_type = self._ActionSpecType.ONESHOT
+            self._action_spec = Oneshot(self.name)
+            return self._action_spec
+        return None
+
+    def _is_valid_action_id(self, action_id):
+        for action_ref in self._info.action_refs:
+            if action_id == action_ref.id:
+                return True
+        return False
+
+    def _from_msg(self, msg):
+        self.priority = msg.priority
+        self.is_default = msg.is_default_action
+        self.idle_timeout_ns = msg.idle_timeout_ns
+        self.metadata = msg.metadata
+        for mf in msg.match:
+            mf_name = CONTEXT.get_mf_name(self.name, mf.field_id)
+            self.match._mk[mf_name] = mf
+        if msg.action.HasField('action'):
+            action = msg.action.action
+            action_name = CONTEXT.get_name_from_id(action.action_id)
+            self.action = Action(action_name)
+            self.action._from_msg(action)
+        elif msg.action.HasField('action_profile_member_id'):
+            self.member_id = msg.action.action_profile_member_id
+        elif msg.action.HasField('action_profile_group_id'):
+            self.group_id = msg.action.action_profile_group_id
+        elif msg.action.HasField('action_profile_action_set'):
+            self.oneshot = Oneshot(self.name)
+            self.oneshot._from_msg(msg.action.action_profile_action_set)
+        if msg.HasField('counter_data'):
+            self._counter_data = _CounterData(
+                self._direct_counter.preamble.name,
+                self._direct_counter.spec.unit)
+            self._counter_data._from_msg(msg.counter_data)
+        else:
+            self._counter_data = None
+        if msg.HasField('meter_config'):
+            self._meter_config = _MeterConfig(
+                self._direct_meter.preamble.name, self._direct_meter.spec.unit)
+            self._meter_config._from_msg(msg.meter_config)
+        else:
+            self._meter_config = None
+        if msg.HasField("time_since_last_hit"):
+            self._time_since_last_hit = _IdleTimeout()
+            self._time_since_last_hit._from_msg(msg.time_since_last_hit)
+        else:
+            self._time_since_last_hit = None
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the appropriate fields unset).
+        If function is None, returns an iterator. Iterate over it to get all the
+        table entries (TableEntry instances) returned by the server. Otherwise,
+        function is applied to all the table entries returned by the server.
+
+        For example:
+        for te in <self>.read():
+            print(te)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda te: print(te))
+
+        To delete all the entries from a table, simply use:
+        table_entry['<table_name>'].read(function=lambda x: x.delete())
+        """
+        return super().read(function)
+
+    def _update_msg(self):
+        entry = p4runtime_pb2.TableEntry()
+        entry.table_id = self.id
+        entry.match.extend(self.match._mk.values())
+        entry.priority = self.priority
+        entry.is_default_action = self.is_default
+        entry.idle_timeout_ns = self.idle_timeout_ns
+        entry.metadata = self.metadata
+        if self._action_spec_type == self._ActionSpecType.DIRECT_ACTION:
+            entry.action.action.CopyFrom(self._action_spec.msg())
+        elif self._action_spec_type == self._ActionSpecType.MEMBER_ID:
+            entry.action.action_profile_member_id = self._action_spec
+        elif self._action_spec_type == self._ActionSpecType.GROUP_ID:
+            entry.action.action_profile_group_id = self._action_spec
+        elif self._action_spec_type == self._ActionSpecType.ONESHOT:
+            entry.action.action_profile_action_set.CopyFrom(
+                self._action_spec.msg())
+        if self._counter_data is None:
+            entry.ClearField('counter_data')
+        else:
+            entry.counter_data.CopyFrom(self._counter_data.msg())
+        if self._meter_config is None:
+            entry.ClearField('meter_config')
+        else:
+            entry.meter_config.CopyFrom(self._meter_config.msg())
+        if self._time_since_last_hit is None:
+            entry.ClearField("time_since_last_hit")
+        else:
+            entry.time_since_last_hit.CopyFrom(self._time_since_last_hit.msg())
+        self._entry = entry
+
+    def _validate_msg(self):
+        if self.is_default and self.match._count() > 0:
+            raise UserError("Match key must be empty for default entry, "
+                            "use <self>.is_default = False "
+                            "or <self>.match.clear "
+                            "(whichever one is appropriate)")
+
+    def clear_action(self):
+        """Clears the action spec for the TableEntry."""
+        super().__setattr__("_action_spec_type", self._ActionSpecType.NONE)
+        super().__setattr__("_action_spec", None)
+
+    def clear_match(self):
+        """Clears the match spec for the TableEntry."""
+        self.match.clear()
+
+    def clear_counter_data(self):
+        """Clear all counter data, same as <self>.counter_data = None"""
+        self._counter_data = None
+
+    def clear_meter_config(self):
+        """Clear the meter config, same as <self>.meter_config = None"""
+        self._meter_config = None
+
+    def clear_time_since_last_hit(self):
+        """Clear the idle timeout, same as <self>.time_since_last_hit = None"""
+        self._time_since_last_hit = None
+
+
+class _CounterEntryBase(_P4EntityBase):
+    """
+    Basic P4 counter entry.
+    """
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self._counter_type = self._info.spec.unit
+        self.packet_count = -1
+        self.byte_count = -1
+        self._data = None
+
+    def __dir__(self):
+        return super().__dir__() + _CounterData.attrs_for_counter_type(
+            self._counter_type) + [
+                   "clear_data"]
+
+    def __call__(self, **kwargs):
+        for name, value in kwargs.items():
+            setattr(self, name, value)
+        return self
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "name":
+            raise UserError("Cannot change counter name")
+        if name in ("byte_count", "packet_count"):
+            self._data = _CounterData.set_count(
+                self._data, self.name, self._counter_type, name, value)
+            return
+        if name == "data":
+            if value is None:
+                self._data = None
+                return
+            raise UserError("Cannot set 'data' directly")
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name in ("byte_count", "packet_count"):
+            self._data, r = _CounterData.get_count(
+                self._data, self.name, self._counter_type, name)
+            return r
+        if name == "data":
+            if self._data is None:
+                self._data = _CounterData(self.name, self._counter_type)
+            return self._data
+        return super().__getattr__(name)
+
+    def _from_msg(self, msg):
+        self._entry.CopyFrom(msg)
+        if msg.HasField('data'):
+            self._data = _CounterData(self.name, self._counter_type)
+            self._data._from_msg(msg.data)
+        else:
+            self._data = None
+
+    def _update_msg(self):
+        if self._data is None:
+            self._entry.ClearField('data')
+        else:
+            self._entry.data.CopyFrom(self._data.msg())
+
+    def clear_data(self):
+        """Clear all counter data, same as <self>.data = None"""
+        self._data = None
+
+
+class CounterEntry(_CounterEntryBase):
+    """
+    P4 counter entry.
+    """
+
+    def __init__(self, counter_name=None):
+        super().__init__(
+            P4Type.counter, P4RuntimeEntity.counter_entry,
+            p4runtime_pb2.CounterEntry, counter_name,
+            modify_only=True)
+        self._entry.counter_id = self.id
+        self.index = -1
+        self.__doc__ = f"""
+An entry for counter '{counter_name}'
+
+Use <self>.info to display the P4Info entry for this counter.
+
+Set the index with <self>.index = <expr>.
+To reset it (e.g. for wildcard read), set it to None.
+
+Access byte count and packet count with <self>.byte_count / <self>.packet_count.
+
+To read from the counter, use <self>.read
+To write to the counter, use <self>.modify
+"""
+        self._init = True
+
+    def __dir__(self):
+        return super().__dir__() + ["index", "data"]
+
+    def __setattr__(self, name, value):
+        if name == "index":
+            if value is None:
+                self._entry.ClearField('index')
+                return
+            if not isinstance(value, int):
+                raise UserError("index must be an integer")
+            self._entry.index.index = value
+            return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name == "index":
+            return self._entry.index.index
+        return super().__getattr__(name)
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the index unset).
+        If function is None, returns an iterator. Iterate over it to get all the
+        counter entries (CounterEntry instances) returned by the
+        server. Otherwise, function is applied to all the counter entries
+        returned by the server.
+
+        For example:
+        for c in <self>.read():
+            print(c)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda c: print(c))
+        """
+        return super().read(function)
+
+
+class DirectCounterEntry(_CounterEntryBase):
+    """
+    Direct P4 counter entry.
+    """
+
+    def __init__(self, direct_counter_name=None):
+        super().__init__(
+            P4Type.direct_counter, P4RuntimeEntity.direct_counter_entry,
+            p4runtime_pb2.DirectCounterEntry, direct_counter_name,
+            modify_only=True)
+        self._direct_table_id = self._info.direct_table_id
+        try:
+            self._direct_table_name = CONTEXT.get_name_from_id(
+                self._direct_table_id)
+        except KeyError as ex:
+            raise InvalidP4InfoError(f"direct_table_id {self._direct_table_id} "
+                                     f"is not a valid table id") from ex
+        self._table_entry = TableEntry(self._direct_table_name)
+        self.__doc__ = f"""
+An entry for direct counter '{direct_counter_name}'
+
+Use <self>.info to display the P4Info entry for this direct counter.
+
+Set the table_entry with <self>.table_entry = <TableEntry instance>.
+The TableEntry instance must be for the table to which the direct counter is
+attached.
+To reset it (e.g. for wildcard read), set it to None. It is the same as:
+<self>.table_entry = TableEntry({self._direct_table_name})
+
+Access byte count and packet count with <self>.byte_count / <self>.packet_count.
+
+To read from the counter, use <self>.read
+To write to the counter, use <self>.modify
+"""
+        self._init = True
+
+    def __dir__(self):
+        return super().__dir__() + ["table_entry"]
+
+    def __setattr__(self, name, value):
+        if name == "index":
+            raise UserError("Direct counters are not index-based")
+        if name == "table_entry":
+            if value is None:
+                self._table_entry = TableEntry(self._direct_table_name)
+                return
+            if not isinstance(value, TableEntry):
+                raise UserError("table_entry must be an instance of TableEntry")
+            if value.name != self._direct_table_name:
+                raise UserError(f"This DirectCounterEntry is for "
+                                f"table '{self._direct_table_name}'")
+            self._table_entry = value
+            return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name == "index":
+            raise UserError("Direct counters are not index-based")
+        if name == "table_entry":
+            return self._table_entry
+        return super().__getattr__(name)
+
+    def _update_msg(self):
+        super()._update_msg()
+        if self._table_entry is None:
+            self._entry.ClearField('table_entry')
+        else:
+            self._entry.table_entry.CopyFrom(self._table_entry.msg())
+
+    def _from_msg(self, msg):
+        super()._from_msg(msg)
+        if msg.HasField('table_entry'):
+            self._table_entry._from_msg(msg.table_entry)
+        else:
+            self._table_entry = None
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the index unset).
+        If function is None, returns an iterator. Iterate over it to get all the
+        direct counter entries (DirectCounterEntry instances) returned by the
+        server. Otherwise, function is applied to all the direct counter entries
+        returned by the server.
+
+        For example:
+        for c in <self>.read():
+            print(c)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda c: print(c))
+        """
+        return super().read(function)
+
+
+class _MeterEntryBase(_P4EntityBase):
+    """
+    Basic P4 meter entry.
+    """
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self._meter_type = self._info.spec.unit
+        self.index = -1
+        self.cir = -1
+        self.cburst = -1
+        self.pir = -1
+        self.pburst = -1
+        self._config = None
+
+    def __dir__(self):
+        return super().__dir__() + _MeterConfig.attrs() + ["clear_config"]
+
+    def __call__(self, **kwargs):
+        for name, value in kwargs.items():
+            setattr(self, name, value)
+        return self
+
+    def __setattr__(self, name, value):
+        if name[0] == "_" or not self._init:
+            super().__setattr__(name, value)
+            return
+        if name == "name":
+            raise UserError("Cannot change meter name")
+        if name in _MeterConfig.attrs():
+            self._config = _MeterConfig.set_param(
+                self._config, self.name, self._meter_type, name, value)
+            return
+        if name == "config":
+            if value is None:
+                self._config = None
+                return
+            raise UserError("Cannot set 'config' directly")
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name in _MeterConfig.attrs():
+            self._config, r = _MeterConfig.get_param(
+                self._config, self.name, self._meter_type, name)
+            return r
+        if name == "config":
+            if self._config is None:
+                self._config = _MeterConfig(self.name, self._meter_type)
+            return self._config
+        return super().__getattr__(name)
+
+    def _from_msg(self, msg):
+        self._entry.CopyFrom(msg)
+        if msg.HasField('config'):
+            self._config = _MeterConfig(self.name, self._meter_type)
+            self._config._from_msg(msg.config)
+        else:
+            self._config = None
+
+    def _update_msg(self):
+        if self._config is None:
+            self._entry.ClearField('config')
+        else:
+            self._entry.config.CopyFrom(self._config.msg())
+
+    def clear_config(self):
+        """Clear the meter config, same as <self>.config = None"""
+        self._config = None
+
+
+class MeterEntry(_MeterEntryBase):
+    """
+    P4 meter entry.
+    """
+
+    def __init__(self, meter_name=None):
+        super().__init__(
+            P4Type.meter, P4RuntimeEntity.meter_entry,
+            p4runtime_pb2.MeterEntry, meter_name,
+            modify_only=True)
+        self._entry.meter_id = self.id
+        self.__doc__ = f"""
+An entry for meter '{meter_name}'
+
+Use <self>.info to display the P4Info entry for this meter.
+
+Set the index with <self>.index = <expr>.
+To reset it (e.g. for wildcard read), set it to None.
+
+Access meter rates and burst sizes with:
+<self>.cir
+<self>.cburst
+<self>.pir
+<self>.pburst
+
+To read from the meter, use <self>.read
+To write to the meter, use <self>.modify
+"""
+        self._init = True
+
+    def __dir__(self):
+        return super().__dir__() + ["index", "config"]
+
+    def __setattr__(self, name, value):
+        if name == "index":
+            if value is None:
+                self._entry.ClearField('index')
+                return
+            if not isinstance(value, int):
+                raise UserError("index must be an integer")
+            self._entry.index.index = value
+            return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name == "index":
+            return self._entry.index.index
+        return super().__getattr__(name)
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the index unset).
+        If function is None, returns an iterator. Iterate over it to get all the
+        meter entries (MeterEntry instances) returned by the
+        server. Otherwise, function is applied to all the meter entries
+        returned by the server.
+
+        For example:
+        for c in <self>.read():
+            print(c)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda c: print(c))
+        """
+        return super().read(function)
+
+
+class DirectMeterEntry(_MeterEntryBase):
+    """
+    Direct P4 meter entry.
+    """
+
+    def __init__(self, direct_meter_name=None):
+        super().__init__(
+            P4Type.direct_meter, P4RuntimeEntity.direct_meter_entry,
+            p4runtime_pb2.DirectMeterEntry, direct_meter_name,
+            modify_only=True)
+        self._direct_table_id = self._info.direct_table_id
+        try:
+            self._direct_table_name = CONTEXT.get_name_from_id(
+                self._direct_table_id)
+        except KeyError as ex:
+            raise InvalidP4InfoError(f"direct_table_id {self._direct_table_id} "
+                                     f"is not a valid table id") from ex
+        self._table_entry = TableEntry(self._direct_table_name)
+        self.__doc__ = f"""
+An entry for direct meter '{direct_meter_name}'
+
+Use <self>.info to display the P4Info entry for this direct meter.
+
+Set the table_entry with <self>.table_entry = <TableEntry instance>.
+The TableEntry instance must be for the table to which the direct meter is attached.
+To reset it (e.g. for wildcard read), set it to None. It is the same as:
+<self>.table_entry = TableEntry({self._direct_table_name})
+
+Access meter rates and burst sizes with:
+<self>.cir
+<self>.cburst
+<self>.pir
+<self>.pburst
+
+To read from the meter, use <self>.read
+To write to the meter, use <self>.modify
+"""
+        self._init = True
+
+    def __dir__(self):
+        return super().__dir__() + ["table_entry"]
+
+    def __setattr__(self, name, value):
+        if name == "index":
+            raise UserError("Direct meters are not index-based")
+        if name == "table_entry":
+            if value is None:
+                self._table_entry = TableEntry(self._direct_table_name)
+                return
+            if not isinstance(value, TableEntry):
+                raise UserError("table_entry must be an instance of TableEntry")
+            if value.name != self._direct_table_name:
+                raise UserError(f"This DirectMeterEntry is for "
+                                f"table '{self._direct_table_name}'")
+            self._table_entry = value
+            return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name == "index":
+            raise UserError("Direct meters are not index-based")
+        if name == "table_entry":
+            return self._table_entry
+        return super().__getattr__(name)
+
+    def _update_msg(self):
+        super()._update_msg()
+        if self._table_entry is None:
+            self._entry.ClearField('table_entry')
+        else:
+            self._entry.table_entry.CopyFrom(self._table_entry.msg())
+
+    def _from_msg(self, msg):
+        super()._from_msg(msg)
+        if msg.HasField('table_entry'):
+            self._table_entry._from_msg(msg.table_entry)
+        else:
+            self._table_entry = None
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the index unset).
+        If function is None, returns an iterator. Iterate over it to get all the
+        direct meter entries (DirectMeterEntry instances) returned by the
+        server. Otherwise, function is applied to all the direct meter entries
+        returned by the server.
+
+        For example:
+        for c in <self>.read():
+            print(c)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda c: print(c))
+        """
+        return super().read(function)
+
+
+class P4RuntimeEntityBuilder:
+    """
+    P4 entity builder.
+    """
+
+    def __init__(self, obj_type, entity_type, entity_cls):
+        self._obj_type = obj_type
+        self._names = sorted([name for name, _ in CONTEXT.get_objs(obj_type)])
+        self._entity_type = entity_type
+        self._entity_cls = entity_cls
+        self.__doc__ = f"""Construct a {entity_cls.__name__} entity
+Usage: <var> = {entity_type.name}["<{obj_type.pretty_name} name>"]
+This is equivalent to <var>={entity_cls.__name__}(<{obj_type.pretty_name} name>)
+Use command '{obj_type.p4info_name}' to see list of {obj_type.pretty_names}
+"""
+
+    def _ipython_key_completions_(self):
+        return self._names
+
+    def __getitem__(self, name):
+        obj = CONTEXT.get_obj(self._obj_type, name)
+        if obj is None:
+            raise UserError(
+                f"{self._obj_type.pretty_name} '{name}' does not exist")
+        return self._entity_cls(name)
+
+    def __setitem__(self, name, value):
+        raise UserError("Operation not allowed")
+
+    def __str__(self):
+        return f"Construct a {self.entity_cls.__name__} entity"
+
+
+class Replica:
+    """
+    A port "replica" (port number + instance id) used for multicast
+    and clone session programming.
+    Construct with Replica(egress_port, instance=<instance>).
+    You can set / get attributes egress_port (required), instance (default 0).
+    """
+
+    def __init__(self, egress_port=None, instance=0):
+        if egress_port is None:
+            raise UserError("egress_port is required")
+        self._msg = p4runtime_pb2.Replica()
+        self._msg.egress_port = egress_port
+        self._msg.instance = instance
+
+    def __dir__(self):
+        return ["port", "egress_port", "instance"]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name in ("egress_port", "port"):
+            if not isinstance(value, int):
+                raise UserError("egress_port must be an integer")
+            self._msg.egress_port = value
+            return
+        if name == "instance":
+            if not isinstance(value, int):
+                raise UserError("instance must be an integer")
+            self._msg.instance = value
+            return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        if name in ("egress_port", "port"):
+            return self._msg.egress_port
+        if name == "instance":
+            return self._msg.instance
+        return super().__getattr__(name)
+
+    def __str__(self):
+        return str(self._msg)
+
+
+class MulticastGroupEntry(_EntityBase):
+    """
+    P4 multicast group entry.
+    """
+
+    def __init__(self, group_id=0):
+        super().__init__(
+            P4RuntimeEntity.packet_replication_engine_entry,
+            p4runtime_pb2.PacketReplicationEngineEntry)
+        self.group_id = group_id
+        self.replicas = []
+        self.__doc__ = """
+Multicast group entry.
+Create an instance with multicast_group_entry(<group_id>).
+Add replicas with <self>.add(<eg_port_1>, <instance_1>).add(<eg_port_2>, <instance_2>)...
+"""
+        self._init = True
+
+    def __dir__(self):
+        return ["group_id", "replicas"]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name == "group_id":
+            if not isinstance(value, int):
+                raise UserError("group_id must be an integer")
+        if name == "replicas":
+            if not isinstance(value, list):
+                raise UserError("replicas must be a list of Replica objects")
+            for r in value:
+                if not isinstance(r, Replica):
+                    raise UserError(
+                        "replicas must be a list of Replica objects")
+        super().__setattr__(name, value)
+
+    def _from_msg(self, msg):
+        self.group_id = msg.multicast_group_entry.multicast_group_id
+        for r in msg.multicast_group_entry.replicas:
+            self.add(r.egress_port, r.instance)
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the group_id as 0).
+        If function is None, returns an iterator. Iterate over it to get all the
+        multicast group entries (MulticastGroupEntry instances) returned by the
+        server. Otherwise, function is applied to all the multicast group entries
+        returned by the server.
+
+        For example:
+        for c in <self>.read():
+            print(c)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda c: print(c))
+        """
+        return super().read(function)
+
+    def _update_msg(self):
+        entry = p4runtime_pb2.PacketReplicationEngineEntry()
+        mcg_entry = entry.multicast_group_entry
+        mcg_entry.multicast_group_id = self.group_id
+        for replica in self.replicas:
+            r = mcg_entry.replicas.add()
+            r.CopyFrom(replica._msg)
+        self._entry = entry
+
+    def add(self, egress_port=None, instance=0):
+        """Add a replica to the multicast group."""
+        self.replicas.append(Replica(egress_port, instance))
+        return self
+
+    def _write(self, type_):
+        if self.group_id == 0:
+            raise UserError("0 is not a valid group_id for MulticastGroupEntry")
+        super()._write(type_)
+
+
+class CloneSessionEntry(_EntityBase):
+    """
+    P4 clone session entry.
+    """
+
+    def __init__(self, session_id=0):
+        super().__init__(
+            P4RuntimeEntity.packet_replication_engine_entry,
+            p4runtime_pb2.PacketReplicationEngineEntry)
+        self.session_id = session_id
+        self.replicas = []
+        self.cos = 0
+        self.packet_length_bytes = 0
+        self.__doc__ = """
+Clone session entry.
+Create an instance with clone_session_entry(<session_id>).
+Add replicas with <self>.add(<eg_port_1>, <instance_1>).add(<eg_port_2>,
+<instance_2>)...
+Access class of service with <self>.cos.
+Access truncation length with <self>.packet_length_bytes.
+"""
+        self._init = True
+
+    def __dir__(self):
+        return ["session_id", "replicas", "cos", "packet_length_bytes"]
+
+    def __setattr__(self, name, value):
+        if name[0] == "_":
+            super().__setattr__(name, value)
+            return
+        if name == "session_id":
+            if not isinstance(value, int):
+                raise UserError("session_id must be an integer")
+        if name == "replicas":
+            if not isinstance(value, list):
+                raise UserError("replicas must be a list of Replica objects")
+            for r in value:
+                if not isinstance(r, Replica):
+                    raise UserError(
+                        "replicas must be a list of Replica objects")
+        if name == "cos":
+            if not isinstance(value, int):
+                raise UserError("cos must be an integer")
+        if name == "packet_length_bytes":
+            if not isinstance(value, int):
+                raise UserError("packet_length_bytes must be an integer")
+        super().__setattr__(name, value)
+
+    def _from_msg(self, msg):
+        self.session_id = msg.clone_session_entry.session_id
+        for r in msg.clone_session_entry.replicas:
+            self.add(r.egress_port, r.instance)
+        self.cos = msg.clone_session_entry.class_of_service
+        self.packet_length_bytes = msg.clone_session_entry.packet_length_bytes
+
+    def read(self, function=None):
+        """Generate a P4Runtime Read RPC. Supports wildcard reads (just leave
+        the session_id as 0).
+        If function is None, returns an iterator. Iterate over it to get all the
+        clone session entries (CloneSessionEntry instances) returned by the
+        server. Otherwise, function is applied to all the clone session entries
+        returned by the server.
+
+        For example:
+        for c in <self>.read():
+            print(c)
+        The above code is equivalent to the following one-liner:
+        <self>.read(lambda c: print(c))
+        """
+        return super().read(function)
+
+    def _update_msg(self):
+        entry = p4runtime_pb2.PacketReplicationEngineEntry()
+        cs_entry = entry.clone_session_entry
+        cs_entry.session_id = self.session_id
+        for replica in self.replicas:
+            r = cs_entry.replicas.add()
+            r.CopyFrom(replica._msg)
+        cs_entry.class_of_service = self.cos
+        cs_entry.packet_length_bytes = self.packet_length_bytes
+        self._entry = entry
+
+    def add(self, egress_port=None, instance=0):
+        """Add a replica to the clone session."""
+        self.replicas.append(Replica(egress_port, instance))
+        return self
+
+    def _write(self, type_):
+        if self.session_id == 0:
+            raise UserError("0 is not a valid group_id for CloneSessionEntry")
+        super()._write(type_)
+
+
+class PacketMetadata:
+    """
+    P4 packet metadata.
+    """
+
+    def __init__(self, metadata_info_list):
+        self._md_info = OrderedDict()
+        self._md = OrderedDict()
+        # Initialize every metadata to zero value
+        for md in metadata_info_list:
+            self._md_info[md.name] = md
+            self._md[md.name] = self._parse_md('0', md)
+        self._set_docstring()
+
+    def _set_docstring(self):
+        self.__doc__ = "Available metadata:\n\n"
+        for _, info in self._md_info.items():
+            self.__doc__ += str(info)
+        self.__doc__ += """
+Set a metadata value with <self>.['<metadata_name>'] = '...'
+
+You may also use <self>.set(<md_name>='<value>')
+"""
+
+    def __dir__(self):
+        return ["clear"]
+
+    def _get_md_info(self, name):
+        if name in self._md_info:
+            return self._md_info[name]
+        raise UserError(f"'{name}' is not a valid metadata name")
+
+    def __getitem__(self, name):
+        _ = self._get_md_info(name)
+        print(self._md.get(name, "Unset"))
+
+    def _parse_md(self, value, md_info):
+        if not isinstance(value, str):
+            raise UserError("Metadata value must be a string")
+        md = p4runtime_pb2.PacketMetadata()
+        md.metadata_id = md_info.id
+        md.value = encode(value.strip(), md_info.bitwidth)
+        return md
+
+    def __setitem__(self, name, value):
+        md_info = self._get_md_info(name)
+        self._md[name] = self._parse_md(value, md_info)
+
+    def _ipython_key_completions_(self):
+        return self._md_info.keys()
+
+    def set(self, **kwargs):
+        """
+        Set packet metadata parameters.
+
+        :param kwargs: packet metadata parameter map
+        :return: void
+        """
+        for name, value in kwargs.items():
+            self[name] = value
+
+    def clear(self):
+        """
+        Clear packet metadata.
+
+        :return: void
+        """
+        self._md.clear()
+
+    def values(self):
+        """
+        Get packet metadata values.
+
+        :return: list of packet metadata values
+        """
+        return self._md.values()
+
+
+class PacketIn():
+    """
+    P4 packet in.
+    """
+
+    def __init__(self):
+        ctrl_pkt_md = P4Objects(P4Type.controller_packet_metadata)
+        self.md_info_list = {}
+        if "packet_in" in ctrl_pkt_md:
+            self.p4_info = ctrl_pkt_md["packet_in"]
+            for md_info in self.p4_info.metadata:
+                self.md_info_list[md_info.name] = md_info
+        self.packet_in_queue = queue.Queue()
+
+        def _packet_in_recv_func(packet_in_queue):
+            while True:
+                msg = CLIENT.get_stream_packet("packet", timeout=None)
+                if not msg:
+                    break
+                packet_in_queue.put(msg)
+
+        self.recv_t = Thread(target=_packet_in_recv_func,
+                             args=(self.packet_in_queue,))
+        self.recv_t.start()
+
+    def sniff(self, function=None, timeout=None):
+        """
+        Return an iterator of packet-in messages.
+        If the function is provided, we do not return an iterator;
+        instead we apply the function to every packet-in message.
+
+        :param function: packet-in function
+        :param timeout: timeout in seconds
+        :return: list of packet-in messages
+        """
+        msgs = []
+
+        if timeout is not None and timeout < 0:
+            raise ValueError("Timeout can't be a negative number.")
+
+        if timeout is None:
+            while True:
+                try:
+                    msgs.append(self.packet_in_queue.get(block=True))
+                except KeyboardInterrupt:
+                    # User sends a Ctrl+C -> breaking
+                    break
+
+        else:  # timeout parameter is provided
+            deadline = time.time() + timeout
+            remaining_time = timeout
+            while remaining_time > 0:
+                try:
+                    msgs.append(self.packet_in_queue.get(block=True,
+                                                         timeout=remaining_time))
+                    remaining_time = deadline - time.time()
+                except KeyboardInterrupt:
+                    # User sends an interrupt(e.g., Ctrl+C).
+                    break
+                except queue.Empty:
+                    # No item available on timeout. Exiting
+                    break
+
+        if function is None:
+            return iter(msgs)
+        for msg in msgs:
+            function(msg)
+
+    def str(self):
+        """
+        Packet-in metadata to string.
+
+        :return: void
+        """
+        for name, info in self.md_info_list.itmes():
+            print(f"Packet-in metadata attribute '{name}':'{info}'")
+
+
+class PacketOut:
+    """
+    P4 packet out.
+    """
+
+    def __init__(self, payload=b'', **kwargs):
+
+        self.p4_info = P4Objects(P4Type.controller_packet_metadata)[
+            "packet_out"]
+        self._entry = None
+        self.payload = payload
+        self.metadata = PacketMetadata(self.p4_info.metadata)
+        if kwargs:
+            for key, value in kwargs.items():
+                self.metadata[key] = value
+
+    def _update_msg(self):
+        self._entry = p4runtime_pb2.PacketOut()
+        self._entry.payload = self.payload
+        self._entry.metadata.extend(self.metadata.values())
+
+    def __setattr__(self, name, value):
+        if name == "payload" and not isinstance(value, bytes):
+            raise UserError("payload must be a bytes type")
+        if name == "metadata" and not isinstance(value, PacketMetadata):
+            raise UserError("metadata must be a PacketMetadata type")
+        return super().__setattr__(name, value)
+
+    def __dir__(self):
+        return ["metadata", "send", "payload"]
+
+    def __str__(self):
+        self._update_msg()
+        return str(self._entry)
+
+    def send(self):
+        """
+        Send a packet-out message.
+
+        :return: void
+        """
+        self._update_msg()
+        msg = p4runtime_pb2.StreamMessageRequest()
+        msg.packet.CopyFrom(self._entry)
+        CLIENT.stream_out_q.put(msg)
+
+    def str(self):
+        """
+        Packet-out metadata to string.
+
+        :return: void
+        """
+        for key, value in self.metadata.itmes():
+            print(f"Packet-out metadata attribute '{key}':'{value}'")
+
+
+class IdleTimeoutNotification():
+    """
+    P4 idle timeout notification.
+    """
+
+    def __init__(self):
+        self.notification_queue = queue.Queue()
+
+        def _notification_recv_func(notification_queue):
+            while True:
+                msg = CLIENT.get_stream_packet("idle_timeout_notification",
+                                               timeout=None)
+                if not msg:
+                    break
+                notification_queue.put(msg)
+
+        self.recv_t = Thread(target=_notification_recv_func,
+                             args=(self.notification_queue,))
+        self.recv_t.start()
+
+    def sniff(self, function=None, timeout=None):
+        """
+        Return an iterator of notification messages.
+        If the function is provided, we do not return an iterator and instead we apply
+        the function to every notification message.
+        """
+        msgs = []
+
+        if timeout is not None and timeout < 0:
+            raise ValueError("Timeout can't be a negative number.")
+
+        if timeout is None:
+            while True:
+                try:
+                    msgs.append(self.notification_queue.get(block=True))
+                except KeyboardInterrupt:
+                    # User sends a Ctrl+C -> breaking
+                    break
+
+        else:  # timeout parameter is provided
+            deadline = time.time() + timeout
+            remaining_time = timeout
+            while remaining_time > 0:
+                try:
+                    msgs.append(self.notification_queue.get(block=True,
+                                                            timeout=remaining_time))
+                    remaining_time = deadline - time.time()
+                except KeyboardInterrupt:
+                    # User sends an interrupt(e.g., Ctrl+C).
+                    break
+                except queue.Empty:
+                    # No item available on timeout. Exiting
+                    break
+
+        if function is None:
+            return iter(msgs)
+        for msg in msgs:
+            function(msg)
diff --git a/src/device/service/drivers/p4/p4_util.py b/src/device/service/drivers/p4/p4_util.py
deleted file mode 100644
index b3d54499f56772768dc19bc1cae3bbf9a25e7dc2..0000000000000000000000000000000000000000
--- a/src/device/service/drivers/p4/p4_util.py
+++ /dev/null
@@ -1,271 +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.
-
-"""
-P4 driver utilities.
-"""
-
-import logging
-import queue
-import sys
-import threading
-from functools import wraps
-import grpc
-import google.protobuf.text_format
-from google.rpc import code_pb2
-
-from p4.v1 import p4runtime_pb2
-from p4.v1 import p4runtime_pb2_grpc
-
-P4_ATTR_DEV_ID = 'id'
-P4_ATTR_DEV_NAME = 'name'
-P4_ATTR_DEV_VENDOR = 'vendor'
-P4_ATTR_DEV_HW_VER = 'hw_ver'
-P4_ATTR_DEV_SW_VER = 'sw_ver'
-P4_ATTR_DEV_PIPECONF = 'pipeconf'
-
-P4_VAL_DEF_VENDOR = 'Unknown'
-P4_VAL_DEF_HW_VER = 'BMv2 simple_switch'
-P4_VAL_DEF_SW_VER = 'Stratum'
-P4_VAL_DEF_PIPECONF = 'org.onosproject.pipelines.fabric'
-
-STREAM_ATTR_ARBITRATION = 'arbitration'
-STREAM_ATTR_PACKET = 'packet'
-STREAM_ATTR_DIGEST = 'digest'
-STREAM_ATTR_UNKNOWN = 'unknown'
-
-LOGGER = logging.getLogger(__name__)
-
-
-class P4RuntimeException(Exception):
-    """
-    P4Runtime exception handler.
-
-    Attributes
-    ----------
-    grpc_error : object
-        gRPC error
-    """
-
-    def __init__(self, grpc_error):
-        super().__init__()
-        self.grpc_error = grpc_error
-
-    def __str__(self):
-        return str('P4Runtime RPC error (%s): %s',
-                   self.grpc_error.code().name(), self.grpc_error.details())
-
-
-def parse_p4runtime_error(fun):
-    """
-    Parse P4Runtime error.
-
-    :param fun: function
-    :return: parsed error
-    """
-    @wraps(fun)
-    def handle(*args, **kwargs):
-        try:
-            return fun(*args, **kwargs)
-        except grpc.RpcError as rpc_ex:
-            raise P4RuntimeException(rpc_ex) from None
-        except Exception as ex:
-            raise Exception(ex) from None
-    return handle
-
-
-class P4RuntimeClient:
-    """
-    P4Runtime client.
-
-    Attributes
-    ----------
-    device_id : int
-        P4 device ID
-    grpc_address : str
-        IP address and port
-    election_id : tuple
-        Mastership election ID
-    role_name : str
-        Role name (optional)
-    """
-    def __init__(self, device_id, grpc_address, election_id, role_name=None):
-        self.device_id = device_id
-        self.election_id = election_id
-        self.role_name = role_name
-        self.stream_in_q = None
-        self.stream_out_q = None
-        self.stream = None
-        self.stream_recv_thread = None
-        LOGGER.debug(
-            'Connecting to device %d at %s', device_id, grpc_address)
-        self.channel = grpc.insecure_channel(grpc_address)
-        self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel)
-        try:
-            self.set_up_stream()
-        except P4RuntimeException:
-            LOGGER.critical('Failed to connect to P4Runtime server')
-            sys.exit(1)
-
-    def set_up_stream(self):
-        """
-        Set up a gRPC stream.
-        """
-        self.stream_out_q = queue.Queue()
-        # queues for different messages
-        self.stream_in_q = {
-            STREAM_ATTR_ARBITRATION: queue.Queue(),
-            STREAM_ATTR_PACKET: queue.Queue(),
-            STREAM_ATTR_DIGEST: queue.Queue(),
-            STREAM_ATTR_UNKNOWN: queue.Queue(),
-        }
-
-        def stream_req_iterator():
-            while True:
-                st_p = self.stream_out_q.get()
-                if st_p is None:
-                    break
-                yield st_p
-
-        def stream_recv_wrapper(stream):
-            @parse_p4runtime_error
-            def stream_recv():
-                for st_p in stream:
-                    if st_p.HasField(STREAM_ATTR_ARBITRATION):
-                        self.stream_in_q[STREAM_ATTR_ARBITRATION].put(st_p)
-                    elif st_p.HasField(STREAM_ATTR_PACKET):
-                        self.stream_in_q[STREAM_ATTR_PACKET].put(st_p)
-                    elif st_p.HasField(STREAM_ATTR_DIGEST):
-                        self.stream_in_q[STREAM_ATTR_DIGEST].put(st_p)
-                    else:
-                        self.stream_in_q[STREAM_ATTR_UNKNOWN].put(st_p)
-            try:
-                stream_recv()
-            except P4RuntimeException as ex:
-                LOGGER.critical('StreamChannel error, closing stream')
-                LOGGER.critical(ex)
-                for k in self.stream_in_q:
-                    self.stream_in_q[k].put(None)
-        self.stream = self.stub.StreamChannel(stream_req_iterator())
-        self.stream_recv_thread = threading.Thread(
-            target=stream_recv_wrapper, args=(self.stream,))
-        self.stream_recv_thread.start()
-        self.handshake()
-
-    def handshake(self):
-        """
-        Handshake with gRPC server.
-        """
-
-        req = p4runtime_pb2.StreamMessageRequest()
-        arbitration = req.arbitration
-        arbitration.device_id = self.device_id
-        election_id = arbitration.election_id
-        election_id.high = self.election_id[0]
-        election_id.low = self.election_id[1]
-        if self.role_name is not None:
-            arbitration.role.name = self.role_name
-        self.stream_out_q.put(req)
-
-        rep = self.get_stream_packet(STREAM_ATTR_ARBITRATION, timeout=2)
-        if rep is None:
-            LOGGER.critical('Failed to establish session with server')
-            sys.exit(1)
-        is_primary = (rep.arbitration.status.code == code_pb2.OK)
-        LOGGER.debug('Session established, client is %s',
-                        'primary' if is_primary else 'backup')
-        if not is_primary:
-            LOGGER.warning(
-                'You are not the primary client, '
-                'you only have read access to the server')
-
-    def get_stream_packet(self, type_, timeout=1):
-        """
-        Get a new message from the stream.
-
-        :param type_: stream type.
-        :param timeout: time to wait.
-        :return: message or None
-        """
-        if type_ not in self.stream_in_q:
-            LOGGER.critical('Unknown stream type %s', type_)
-            return None
-        try:
-            msg = self.stream_in_q[type_].get(timeout=timeout)
-            return msg
-        except queue.Empty:  # timeout expired
-            return None
-
-    @parse_p4runtime_error
-    def get_p4info(self):
-        """
-        Retrieve P4Info content.
-
-        :return: P4Info object.
-        """
-
-        LOGGER.debug('Retrieving P4Info file')
-        req = p4runtime_pb2.GetForwardingPipelineConfigRequest()
-        req.device_id = self.device_id
-        req.response_type =\
-            p4runtime_pb2.GetForwardingPipelineConfigRequest.P4INFO_AND_COOKIE
-        rep = self.stub.GetForwardingPipelineConfig(req)
-        return rep.config.p4info
-
-    @parse_p4runtime_error
-    def set_fwd_pipe_config(self, p4info_path, bin_path):
-        """
-        Configure the pipeline.
-
-        :param p4info_path: path to the P4Info file
-        :param bin_path: path to the binary file
-        :return:
-        """
-
-        LOGGER.debug('Setting forwarding pipeline config')
-        req = p4runtime_pb2.SetForwardingPipelineConfigRequest()
-        req.device_id = self.device_id
-        if self.role_name is not None:
-            req.role = self.role_name
-        election_id = req.election_id
-        election_id.high = self.election_id[0]
-        election_id.low = self.election_id[1]
-        req.action =\
-            p4runtime_pb2.SetForwardingPipelineConfigRequest.VERIFY_AND_COMMIT
-        with open(p4info_path, 'r', encoding='utf8') as f_1:
-            with open(bin_path, 'rb', encoding='utf8') as f_2:
-                try:
-                    google.protobuf.text_format.Merge(
-                        f_1.read(), req.config.p4info)
-                except google.protobuf.text_format.ParseError:
-                    LOGGER.error('Error when parsing P4Info')
-                    raise
-                req.config.p4_device_config = f_2.read()
-        return self.stub.SetForwardingPipelineConfig(req)
-
-    def tear_down(self):
-        """
-        Tear connection with the gRPC server down.
-        """
-
-        if self.stream_out_q:
-            LOGGER.debug('Cleaning up stream')
-            self.stream_out_q.put(None)
-        if self.stream_in_q:
-            for k in self.stream_in_q:
-                self.stream_in_q[k].put(None)
-        if self.stream_recv_thread:
-            self.stream_recv_thread.join()
-        self.channel.close()
-        del self.channel
diff --git a/src/device/service/drivers/xr/README_XR.md b/src/device/service/drivers/xr/README_XR.md
index 234261124fc70059ac14e947274a3a4e95648192..e11c39267eb96d2a635c25a9e78a28ddaf86d18c 100644
--- a/src/device/service/drivers/xr/README_XR.md
+++ b/src/device/service/drivers/xr/README_XR.md
@@ -33,10 +33,18 @@ docker run -d -p 32000:5000 --restart=always --name registry registry:2
 
 Setup mydeploy script outside the git repo. E.g. following will do. SOURCE IT ON ALL SHELLS.
 
+IMPORTANT: September 2022 version of controller has a bug where any update to device trigger update to device
+until GRPC endpoints are so loaded that K8s kills device service. XR does not need automation service, so it can
+be left out.
+
 ```bash
 export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
-
-export TFS_COMPONENTS="context device automation service compute monitoring webui"
+# Without automation service (see note above)
+export TFS_COMPONENTS="context device pathcomp service slice compute monitoring webui"
+# Correct setting
+# export TFS_COMPONENTS="context device automation pathcomp service slice compute monitoring webui"
+# Pre-rebase
+#export TFS_COMPONENTS="context device automation service compute monitoring webui"
 export TFS_IMAGE_TAG="dev"
 export TFS_K8S_NAMESPACE="tfs"
 export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
@@ -79,6 +87,17 @@ Run deploy script to build in docker containers and then instantiate to configur
 ./deploy.sh
 ```
 
+If protobuf definitions have changed, regenerate version controlled Java files manually
+(it is a horrifying bug in build system that this is not automated!).
+```
+cd automation
+# In case Java is not already installed
+sudo apt-get install openjdk-11-jdk -y
+./mvnw compile
+```
+
+Compilation fails but does update the protobuf generated files.
+
 ## Testing
 
 Upload descriptors_emulatex_xr.json via WEB UI to setup fake topology.
diff --git a/src/device/tests/Device_OpenConfig_Template.py b/src/device/tests/Device_OpenConfig_Template.py
index 6afa2721ff920c39de243b308b9b9a4749cb013b..af339cce40b60f8ea0e310613c951968f4fc9aeb 100644
--- a/src/device/tests/Device_OpenConfig_Template.py
+++ b/src/device/tests/Device_OpenConfig_Template.py
@@ -32,9 +32,11 @@ DEVICE_OC_CONNECT_RULES = json_device_connect_rules(DEVICE_OC_ADDRESS, DEVICE_OC
     'hostkey_verify' : True,
     'look_for_keys'  : True,
     'allow_agent'    : True,
+    'delete_rule'    : False,
     'device_params'  : {'name': 'default'},
     'manager_params' : {'timeout' : DEVICE_OC_TIMEOUT},
 })
 
+
 DEVICE_OC_CONFIG_RULES   = []           # populate your configuration rules to test
 DEVICE_OC_DECONFIG_RULES = []           # populate your deconfiguration rules to test
diff --git a/src/device/tests/device_p4.py b/src/device/tests/device_p4.py
index 4cd0a4c745d3a07b71f320ce79d73c95ffb0af37..ccc62c2195c8dae41a8e98b128b08965954d57f0 100644
--- a/src/device/tests/device_p4.py
+++ b/src/device/tests/device_p4.py
@@ -16,18 +16,23 @@
 P4 device example configuration.
 """
 
-from common.tools.object_factory.ConfigRule import json_config_rule_set
+import os
+from common.tools.object_factory.ConfigRule import (
+    json_config_rule_set, json_config_rule_delete)
 from common.tools.object_factory.Device import (
     json_device_connect_rules, json_device_id, json_device_p4_disabled)
 
-DEVICE_P4_DPID = 0
+CUR_PATH = os.path.dirname(os.path.abspath(__file__))
+
+DEVICE_P4_DPID = 1
 DEVICE_P4_NAME = 'device:leaf1'
-DEVICE_P4_ADDRESS = '127.0.0.1'
+DEVICE_P4_IP_ADDR = '127.0.0.1'
 DEVICE_P4_PORT = '50101'
 DEVICE_P4_VENDOR = 'Open Networking Foundation'
 DEVICE_P4_HW_VER = 'BMv2 simple_switch'
 DEVICE_P4_SW_VER = 'Stratum'
-DEVICE_P4_PIPECONF = 'org.onosproject.pipelines.fabric'
+DEVICE_P4_BIN_PATH = os.path.join(CUR_PATH, 'p4/test-bmv2.json')
+DEVICE_P4_INFO_PATH = os.path.join(CUR_PATH, 'p4/test-p4info.txt')
 DEVICE_P4_WORKERS = 2
 DEVICE_P4_GRACE_PERIOD = 60
 DEVICE_P4_TIMEOUT = 60
@@ -37,16 +42,52 @@ DEVICE_P4_ID = json_device_id(DEVICE_P4_UUID)
 DEVICE_P4 = json_device_p4_disabled(DEVICE_P4_UUID)
 
 DEVICE_P4_CONNECT_RULES = json_device_connect_rules(
-    DEVICE_P4_ADDRESS, DEVICE_P4_PORT, {
+    DEVICE_P4_IP_ADDR,
+    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
+        'vendor': DEVICE_P4_VENDOR,
+        'hw_ver': DEVICE_P4_HW_VER,
+        'sw_ver': DEVICE_P4_SW_VER,
+        'timeout': DEVICE_P4_TIMEOUT,
+        'p4bin': DEVICE_P4_BIN_PATH,
+        'p4info': DEVICE_P4_INFO_PATH
     }
 )
 
-DEVICE_P4_CONFIG_RULES = [
-    json_config_rule_set('key1', 'value1'),
+DEVICE_P4_CONFIG_TABLE_ENTRY = [
+    json_config_rule_set(
+        'table',
+        {
+            'table-name': 'IngressPipeImpl.acl_table',
+            'match-fields': [
+                {
+                    'match-field': 'hdr.ethernet.dst_addr',
+                    'match-value': 'aa:bb:cc:dd:ee:22 &&& ff:ff:ff:ff:ff:ff'
+                }
+            ],
+            'action-name': 'IngressPipeImpl.clone_to_cpu',
+            'action-params': [],
+            'priority': 1
+        }
+    )
+]
+
+DEVICE_P4_DECONFIG_TABLE_ENTRY = [
+    json_config_rule_delete(
+        'table',
+        {
+            'table-name': 'IngressPipeImpl.acl_table',
+            'match-fields': [
+                {
+                    'match-field': 'hdr.ethernet.dst_addr',
+                    'match-value': 'aa:bb:cc:dd:ee:22 &&& ff:ff:ff:ff:ff:ff'
+                }
+            ],
+            'action-name': 'IngressPipeImpl.clone_to_cpu',
+            'action-params': [],
+            'priority': 1
+        }
+    )
 ]
diff --git a/src/device/tests/mock_p4runtime_service.py b/src/device/tests/mock_p4runtime_service.py
index 77da0113676dc6f820d995b34915df6d0ba30f01..c1b2dcb45a18caf0c839f9bd8a68484bba5efbea 100644
--- a/src/device/tests/mock_p4runtime_service.py
+++ b/src/device/tests/mock_p4runtime_service.py
@@ -22,7 +22,7 @@ import grpc
 from p4.v1 import p4runtime_pb2_grpc
 
 from .device_p4 import(
-    DEVICE_P4_ADDRESS, DEVICE_P4_PORT,
+    DEVICE_P4_IP_ADDR, DEVICE_P4_PORT,
     DEVICE_P4_WORKERS, DEVICE_P4_GRACE_PERIOD)
 from .mock_p4runtime_servicer_impl import MockP4RuntimeServicerImpl
 
@@ -35,7 +35,7 @@ class MockP4RuntimeService:
     """
 
     def __init__(
-            self, address=DEVICE_P4_ADDRESS, port=DEVICE_P4_PORT,
+            self, address=DEVICE_P4_IP_ADDR, port=DEVICE_P4_PORT,
             max_workers=DEVICE_P4_WORKERS,
             grace_period=DEVICE_P4_GRACE_PERIOD):
         self.address = address
diff --git a/src/device/tests/mock_p4runtime_servicer_impl.py b/src/device/tests/mock_p4runtime_servicer_impl.py
index d29445da43afb58ef062f62c496b0780f92a4648..8a516303d9310be55662ef749175655c4069ae5c 100644
--- a/src/device/tests/mock_p4runtime_servicer_impl.py
+++ b/src/device/tests/mock_p4runtime_servicer_impl.py
@@ -22,11 +22,12 @@ from p4.v1 import p4runtime_pb2, p4runtime_pb2_grpc
 from p4.config.v1 import p4info_pb2
 
 try:
-    from p4_util import STREAM_ATTR_ARBITRATION, STREAM_ATTR_PACKET
+    from p4_client import STREAM_ATTR_ARBITRATION, STREAM_ATTR_PACKET
 except ImportError:
-    from device.service.drivers.p4.p4_util import STREAM_ATTR_ARBITRATION,\
+    from device.service.drivers.p4.p4_client import STREAM_ATTR_ARBITRATION,\
         STREAM_ATTR_PACKET
 
+
 class MockP4RuntimeServicerImpl(p4runtime_pb2_grpc.P4RuntimeServicer):
     """
     A P4Runtime service implementation for testing purposes.
diff --git a/src/device/tests/p4/test-bmv2.json b/src/device/tests/p4/test-bmv2.json
new file mode 100644
index 0000000000000000000000000000000000000000..f6ef6af34907ae00bcfa1034bb317a8f270b8995
--- /dev/null
+++ b/src/device/tests/p4/test-bmv2.json
@@ -0,0 +1,1910 @@
+{
+  "header_types" : [
+    {
+      "name" : "scalars_0",
+      "id" : 0,
+      "fields" : [
+        ["tmp_0", 1, false],
+        ["tmp_1", 1, false],
+        ["tmp", 1, false],
+        ["local_metadata_t.l4_src_port", 16, false],
+        ["local_metadata_t.l4_dst_port", 16, false],
+        ["local_metadata_t.is_multicast", 1, false],
+        ["local_metadata_t.next_srv6_sid", 128, false],
+        ["local_metadata_t.ip_proto", 8, false],
+        ["local_metadata_t.icmp_type", 8, false],
+        ["_padding_0", 4, false]
+      ]
+    },
+    {
+      "name" : "standard_metadata",
+      "id" : 1,
+      "fields" : [
+        ["ingress_port", 9, false],
+        ["egress_spec", 9, false],
+        ["egress_port", 9, false],
+        ["clone_spec", 32, false],
+        ["instance_type", 32, false],
+        ["drop", 1, false],
+        ["recirculate_port", 16, false],
+        ["packet_length", 32, false],
+        ["enq_timestamp", 32, false],
+        ["enq_qdepth", 19, false],
+        ["deq_timedelta", 32, false],
+        ["deq_qdepth", 19, false],
+        ["ingress_global_timestamp", 48, false],
+        ["egress_global_timestamp", 48, false],
+        ["lf_field_list", 32, false],
+        ["mcast_grp", 16, false],
+        ["resubmit_flag", 32, false],
+        ["egress_rid", 16, false],
+        ["recirculate_flag", 32, false],
+        ["checksum_error", 1, false],
+        ["parser_error", 32, false],
+        ["priority", 3, false],
+        ["_padding", 2, false]
+      ]
+    },
+    {
+      "name" : "cpu_out_header_t",
+      "id" : 2,
+      "fields" : [
+        ["egress_port", 9, false],
+        ["_pad", 7, false]
+      ]
+    },
+    {
+      "name" : "cpu_in_header_t",
+      "id" : 3,
+      "fields" : [
+        ["ingress_port", 9, false],
+        ["_pad", 7, false]
+      ]
+    },
+    {
+      "name" : "ethernet_t",
+      "id" : 4,
+      "fields" : [
+        ["dst_addr", 48, false],
+        ["src_addr", 48, false],
+        ["ether_type", 16, false]
+      ]
+    },
+    {
+      "name" : "ipv4_t",
+      "id" : 5,
+      "fields" : [
+        ["version", 4, false],
+        ["ihl", 4, false],
+        ["dscp", 6, false],
+        ["ecn", 2, false],
+        ["total_len", 16, false],
+        ["identification", 16, false],
+        ["flags", 3, false],
+        ["frag_offset", 13, false],
+        ["ttl", 8, false],
+        ["protocol", 8, false],
+        ["hdr_checksum", 16, false],
+        ["src_addr", 32, false],
+        ["dst_addr", 32, false]
+      ]
+    },
+    {
+      "name" : "ipv6_t",
+      "id" : 6,
+      "fields" : [
+        ["version", 4, false],
+        ["traffic_class", 8, false],
+        ["flow_label", 20, false],
+        ["payload_len", 16, false],
+        ["next_hdr", 8, false],
+        ["hop_limit", 8, false],
+        ["src_addr", 128, false],
+        ["dst_addr", 128, false]
+      ]
+    },
+    {
+      "name" : "srv6h_t",
+      "id" : 7,
+      "fields" : [
+        ["next_hdr", 8, false],
+        ["hdr_ext_len", 8, false],
+        ["routing_type", 8, false],
+        ["segment_left", 8, false],
+        ["last_entry", 8, false],
+        ["flags", 8, false],
+        ["tag", 16, false]
+      ]
+    },
+    {
+      "name" : "tcp_t",
+      "id" : 8,
+      "fields" : [
+        ["src_port", 16, false],
+        ["dst_port", 16, false],
+        ["seq_no", 32, false],
+        ["ack_no", 32, false],
+        ["data_offset", 4, false],
+        ["res", 3, false],
+        ["ecn", 3, false],
+        ["ctrl", 6, false],
+        ["window", 16, false],
+        ["checksum", 16, false],
+        ["urgent_ptr", 16, false]
+      ]
+    },
+    {
+      "name" : "udp_t",
+      "id" : 9,
+      "fields" : [
+        ["src_port", 16, false],
+        ["dst_port", 16, false],
+        ["len", 16, false],
+        ["checksum", 16, false]
+      ]
+    },
+    {
+      "name" : "icmp_t",
+      "id" : 10,
+      "fields" : [
+        ["type", 8, false],
+        ["icmp_code", 8, false],
+        ["checksum", 16, false],
+        ["identifier", 16, false],
+        ["sequence_number", 16, false],
+        ["timestamp", 64, false]
+      ]
+    },
+    {
+      "name" : "icmpv6_t",
+      "id" : 11,
+      "fields" : [
+        ["type", 8, false],
+        ["code", 8, false],
+        ["checksum", 16, false]
+      ]
+    },
+    {
+      "name" : "ndp_t",
+      "id" : 12,
+      "fields" : [
+        ["flags", 32, false],
+        ["target_ipv6_addr", 128, false],
+        ["type", 8, false],
+        ["length", 8, false],
+        ["target_mac_addr", 48, false]
+      ]
+    },
+    {
+      "name" : "srv6_list_t",
+      "id" : 13,
+      "fields" : [
+        ["segment_id", 128, false]
+      ]
+    }
+  ],
+  "headers" : [
+    {
+      "name" : "scalars",
+      "id" : 0,
+      "header_type" : "scalars_0",
+      "metadata" : true,
+      "pi_omit" : true
+    },
+    {
+      "name" : "standard_metadata",
+      "id" : 1,
+      "header_type" : "standard_metadata",
+      "metadata" : true,
+      "pi_omit" : true
+    },
+    {
+      "name" : "cpu_out",
+      "id" : 2,
+      "header_type" : "cpu_out_header_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "cpu_in",
+      "id" : 3,
+      "header_type" : "cpu_in_header_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "ethernet",
+      "id" : 4,
+      "header_type" : "ethernet_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "ipv4",
+      "id" : 5,
+      "header_type" : "ipv4_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "ipv6",
+      "id" : 6,
+      "header_type" : "ipv6_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "srv6h",
+      "id" : 7,
+      "header_type" : "srv6h_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "tcp",
+      "id" : 8,
+      "header_type" : "tcp_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "udp",
+      "id" : 9,
+      "header_type" : "udp_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "icmp",
+      "id" : 10,
+      "header_type" : "icmp_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "icmpv6",
+      "id" : 11,
+      "header_type" : "icmpv6_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "ndp",
+      "id" : 12,
+      "header_type" : "ndp_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "srv6_list[0]",
+      "id" : 13,
+      "header_type" : "srv6_list_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "srv6_list[1]",
+      "id" : 14,
+      "header_type" : "srv6_list_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "srv6_list[2]",
+      "id" : 15,
+      "header_type" : "srv6_list_t",
+      "metadata" : false,
+      "pi_omit" : true
+    },
+    {
+      "name" : "srv6_list[3]",
+      "id" : 16,
+      "header_type" : "srv6_list_t",
+      "metadata" : false,
+      "pi_omit" : true
+    }
+  ],
+  "header_stacks" : [
+    {
+      "name" : "srv6_list",
+      "id" : 0,
+      "header_type" : "srv6_list_t",
+      "size" : 4,
+      "header_ids" : [13, 14, 15, 16]
+    }
+  ],
+  "header_union_types" : [],
+  "header_unions" : [],
+  "header_union_stacks" : [],
+  "field_lists" : [
+    {
+      "id" : 1,
+      "name" : "fl",
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 474,
+        "column" : 34,
+        "source_fragment" : "{ standard_metadata.ingress_port }"
+      },
+      "elements" : [
+        {
+          "type" : "field",
+          "value" : ["standard_metadata", "ingress_port"]
+        }
+      ]
+    }
+  ],
+  "errors" : [
+    ["NoError", 1],
+    ["PacketTooShort", 2],
+    ["NoMatch", 3],
+    ["StackOutOfBounds", 4],
+    ["HeaderTooShort", 5],
+    ["ParserTimeout", 6],
+    ["ParserInvalidArgument", 7]
+  ],
+  "enums" : [],
+  "parsers" : [
+    {
+      "name" : "parser",
+      "id" : 0,
+      "init_state" : "start",
+      "parse_states" : [
+        {
+          "name" : "start",
+          "id" : 0,
+          "parser_ops" : [],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x00ff",
+              "mask" : null,
+              "next_state" : "parse_packet_out"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : "parse_ethernet"
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["standard_metadata", "ingress_port"]
+            }
+          ]
+        },
+        {
+          "name" : "parse_packet_out",
+          "id" : 1,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "cpu_out"
+                }
+              ],
+              "op" : "extract"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : "parse_ethernet"
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "parse_ethernet",
+          "id" : 2,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "ethernet"
+                }
+              ],
+              "op" : "extract"
+            }
+          ],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x0800",
+              "mask" : null,
+              "next_state" : "parse_ipv4"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x86dd",
+              "mask" : null,
+              "next_state" : "parse_ipv6"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["ethernet", "ether_type"]
+            }
+          ]
+        },
+        {
+          "name" : "parse_ipv4",
+          "id" : 3,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "ipv4"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.ip_proto"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["ipv4", "protocol"]
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x06",
+              "mask" : null,
+              "next_state" : "parse_tcp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x11",
+              "mask" : null,
+              "next_state" : "parse_udp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x01",
+              "mask" : null,
+              "next_state" : "parse_icmp"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["ipv4", "protocol"]
+            }
+          ]
+        },
+        {
+          "name" : "parse_ipv6",
+          "id" : 4,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "ipv6"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.ip_proto"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["ipv6", "next_hdr"]
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x06",
+              "mask" : null,
+              "next_state" : "parse_tcp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x11",
+              "mask" : null,
+              "next_state" : "parse_udp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x3a",
+              "mask" : null,
+              "next_state" : "parse_icmpv6"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x2b",
+              "mask" : null,
+              "next_state" : "parse_srv6"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["ipv6", "next_hdr"]
+            }
+          ]
+        },
+        {
+          "name" : "parse_tcp",
+          "id" : 5,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "tcp"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.l4_src_port"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["tcp", "src_port"]
+                }
+              ],
+              "op" : "set"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.l4_dst_port"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["tcp", "dst_port"]
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "parse_udp",
+          "id" : 6,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "udp"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.l4_src_port"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["udp", "src_port"]
+                }
+              ],
+              "op" : "set"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.l4_dst_port"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["udp", "dst_port"]
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "parse_icmp",
+          "id" : 7,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "icmp"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.icmp_type"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["icmp", "type"]
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "parse_icmpv6",
+          "id" : 8,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "icmpv6"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.icmp_type"]
+                },
+                {
+                  "type" : "field",
+                  "value" : ["icmpv6", "type"]
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x87",
+              "mask" : null,
+              "next_state" : "parse_ndp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x88",
+              "mask" : null,
+              "next_state" : "parse_ndp"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["icmpv6", "type"]
+            }
+          ]
+        },
+        {
+          "name" : "parse_ndp",
+          "id" : 9,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "ndp"
+                }
+              ],
+              "op" : "extract"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "parse_srv6",
+          "id" : 10,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "regular",
+                  "value" : "srv6h"
+                }
+              ],
+              "op" : "extract"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : "parse_srv6_list"
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "parse_srv6_list",
+          "id" : 11,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "stack",
+                  "value" : "srv6_list"
+                }
+              ],
+              "op" : "extract"
+            },
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "tmp_0"]
+                },
+                {
+                  "type" : "expression",
+                  "value" : {
+                    "type" : "expression",
+                    "value" : {
+                      "op" : "?",
+                      "left" : {
+                        "type" : "hexstr",
+                        "value" : "0x01"
+                      },
+                      "right" : {
+                        "type" : "hexstr",
+                        "value" : "0x00"
+                      },
+                      "cond" : {
+                        "type" : "expression",
+                        "value" : {
+                          "op" : "==",
+                          "left" : {
+                            "type" : "expression",
+                            "value" : {
+                              "op" : "&",
+                              "left" : {
+                                "type" : "expression",
+                                "value" : {
+                                  "op" : "+",
+                                  "left" : {
+                                    "type" : "expression",
+                                    "value" : {
+                                      "op" : "&",
+                                      "left" : {
+                                        "type" : "field",
+                                        "value" : ["srv6h", "segment_left"]
+                                      },
+                                      "right" : {
+                                        "type" : "hexstr",
+                                        "value" : "0xffffffff"
+                                      }
+                                    }
+                                  },
+                                  "right" : {
+                                    "type" : "hexstr",
+                                    "value" : "0xffffffff"
+                                  }
+                                }
+                              },
+                              "right" : {
+                                "type" : "hexstr",
+                                "value" : "0xffffffff"
+                              }
+                            }
+                          },
+                          "right" : {
+                            "type" : "expression",
+                            "value" : {
+                              "op" : "last_stack_index",
+                              "left" : null,
+                              "right" : {
+                                "type" : "header_stack",
+                                "value" : "srv6_list"
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x01",
+              "mask" : null,
+              "next_state" : "mark_current_srv6"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : "check_last_srv6"
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["scalars", "tmp_0"]
+            }
+          ]
+        },
+        {
+          "name" : "mark_current_srv6",
+          "id" : 12,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "local_metadata_t.next_srv6_sid"]
+                },
+                {
+                  "type" : "expression",
+                  "value" : {
+                    "type" : "stack_field",
+                    "value" : ["srv6_list", "segment_id"]
+                  }
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : "check_last_srv6"
+            }
+          ],
+          "transition_key" : []
+        },
+        {
+          "name" : "check_last_srv6",
+          "id" : 13,
+          "parser_ops" : [
+            {
+              "parameters" : [
+                {
+                  "type" : "field",
+                  "value" : ["scalars", "tmp_1"]
+                },
+                {
+                  "type" : "expression",
+                  "value" : {
+                    "type" : "expression",
+                    "value" : {
+                      "op" : "?",
+                      "left" : {
+                        "type" : "hexstr",
+                        "value" : "0x01"
+                      },
+                      "right" : {
+                        "type" : "hexstr",
+                        "value" : "0x00"
+                      },
+                      "cond" : {
+                        "type" : "expression",
+                        "value" : {
+                          "op" : "==",
+                          "left" : {
+                            "type" : "expression",
+                            "value" : {
+                              "op" : "&",
+                              "left" : {
+                                "type" : "field",
+                                "value" : ["srv6h", "last_entry"]
+                              },
+                              "right" : {
+                                "type" : "hexstr",
+                                "value" : "0xffffffff"
+                              }
+                            }
+                          },
+                          "right" : {
+                            "type" : "expression",
+                            "value" : {
+                              "op" : "last_stack_index",
+                              "left" : null,
+                              "right" : {
+                                "type" : "header_stack",
+                                "value" : "srv6_list"
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              ],
+              "op" : "set"
+            }
+          ],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x01",
+              "mask" : null,
+              "next_state" : "parse_srv6_next_hdr"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x00",
+              "mask" : null,
+              "next_state" : "parse_srv6_list"
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["scalars", "tmp_1"]
+            }
+          ]
+        },
+        {
+          "name" : "parse_srv6_next_hdr",
+          "id" : 14,
+          "parser_ops" : [],
+          "transitions" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x06",
+              "mask" : null,
+              "next_state" : "parse_tcp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x11",
+              "mask" : null,
+              "next_state" : "parse_udp"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x3a",
+              "mask" : null,
+              "next_state" : "parse_icmpv6"
+            },
+            {
+              "value" : "default",
+              "mask" : null,
+              "next_state" : null
+            }
+          ],
+          "transition_key" : [
+            {
+              "type" : "field",
+              "value" : ["srv6h", "next_hdr"]
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "parse_vsets" : [],
+  "deparsers" : [
+    {
+      "name" : "deparser",
+      "id" : 0,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 602,
+        "column" : 8,
+        "source_fragment" : "DeparserImpl"
+      },
+      "order" : ["cpu_in", "ethernet", "ipv4", "ipv6", "srv6h", "srv6_list[0]", "srv6_list[1]", "srv6_list[2]", "srv6_list[3]", "tcp", "udp", "icmp", "icmpv6", "ndp"]
+    }
+  ],
+  "meter_arrays" : [],
+  "counter_arrays" : [
+    {
+      "name" : "l2_exact_table_counter",
+      "id" : 0,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 399,
+        "column" : 8,
+        "source_fragment" : "counters"
+      },
+      "is_direct" : true,
+      "binding" : "IngressPipeImpl.l2_exact_table"
+    },
+    {
+      "name" : "l2_ternary_table_counter",
+      "id" : 1,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 423,
+        "column" : 8,
+        "source_fragment" : "counters"
+      },
+      "is_direct" : true,
+      "binding" : "IngressPipeImpl.l2_ternary_table"
+    },
+    {
+      "name" : "acl_table_counter",
+      "id" : 2,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 494,
+        "column" : 8,
+        "source_fragment" : "counters"
+      },
+      "is_direct" : true,
+      "binding" : "IngressPipeImpl.acl_table"
+    }
+  ],
+  "register_arrays" : [],
+  "calculations" : [
+    {
+      "name" : "calc",
+      "id" : 0,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 580,
+        "column" : 8,
+        "source_fragment" : "update_checksum(hdr.ndp.isValid(), ..."
+      },
+      "algo" : "csum16",
+      "input" : [
+        {
+          "type" : "field",
+          "value" : ["ipv6", "src_addr"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ipv6", "dst_addr"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ipv6", "payload_len"]
+        },
+        {
+          "type" : "hexstr",
+          "value" : "0x00",
+          "bitwidth" : 8
+        },
+        {
+          "type" : "field",
+          "value" : ["ipv6", "next_hdr"]
+        },
+        {
+          "type" : "field",
+          "value" : ["icmpv6", "type"]
+        },
+        {
+          "type" : "field",
+          "value" : ["icmpv6", "code"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ndp", "flags"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ndp", "target_ipv6_addr"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ndp", "type"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ndp", "length"]
+        },
+        {
+          "type" : "field",
+          "value" : ["ndp", "target_mac_addr"]
+        }
+      ]
+    }
+  ],
+  "learn_lists" : [],
+  "actions" : [
+    {
+      "name" : "NoAction",
+      "id" : 0,
+      "runtime_data" : [],
+      "primitives" : []
+    },
+    {
+      "name" : "IngressPipeImpl.drop",
+      "id" : 1,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "mark_to_drop",
+          "parameters" : [
+            {
+              "type" : "header",
+              "value" : "standard_metadata"
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 351,
+            "column" : 8,
+            "source_fragment" : "mark_to_drop(standard_metadata)"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "IngressPipeImpl.drop",
+      "id" : 2,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "mark_to_drop",
+          "parameters" : [
+            {
+              "type" : "header",
+              "value" : "standard_metadata"
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 351,
+            "column" : 8,
+            "source_fragment" : "mark_to_drop(standard_metadata)"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "IngressPipeImpl.drop",
+      "id" : 3,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "mark_to_drop",
+          "parameters" : [
+            {
+              "type" : "header",
+              "value" : "standard_metadata"
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 351,
+            "column" : 8,
+            "source_fragment" : "mark_to_drop(standard_metadata)"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "IngressPipeImpl.set_egress_port",
+      "id" : 4,
+      "runtime_data" : [
+        {
+          "name" : "port_num",
+          "bitwidth" : 9
+        }
+      ],
+      "primitives" : [
+        {
+          "op" : "assign",
+          "parameters" : [
+            {
+              "type" : "field",
+              "value" : ["standard_metadata", "egress_spec"]
+            },
+            {
+              "type" : "runtime_data",
+              "value" : 0
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 383,
+            "column" : 8,
+            "source_fragment" : "standard_metadata.egress_spec = port_num"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "IngressPipeImpl.set_multicast_group",
+      "id" : 5,
+      "runtime_data" : [
+        {
+          "name" : "gid",
+          "bitwidth" : 16
+        }
+      ],
+      "primitives" : [
+        {
+          "op" : "assign",
+          "parameters" : [
+            {
+              "type" : "field",
+              "value" : ["standard_metadata", "mcast_grp"]
+            },
+            {
+              "type" : "runtime_data",
+              "value" : 0
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 409,
+            "column" : 8,
+            "source_fragment" : "standard_metadata.mcast_grp = gid"
+          }
+        },
+        {
+          "op" : "assign",
+          "parameters" : [
+            {
+              "type" : "field",
+              "value" : ["scalars", "local_metadata_t.is_multicast"]
+            },
+            {
+              "type" : "expression",
+              "value" : {
+                "type" : "expression",
+                "value" : {
+                  "op" : "b2d",
+                  "left" : null,
+                  "right" : {
+                    "type" : "bool",
+                    "value" : true
+                  }
+                }
+              }
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 410,
+            "column" : 8,
+            "source_fragment" : "local_metadata.is_multicast = true"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "IngressPipeImpl.send_to_cpu",
+      "id" : 6,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "assign",
+          "parameters" : [
+            {
+              "type" : "field",
+              "value" : ["standard_metadata", "egress_spec"]
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x00ff"
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 466,
+            "column" : 8,
+            "source_fragment" : "standard_metadata.egress_spec = 255"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "IngressPipeImpl.clone_to_cpu",
+      "id" : 7,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "clone_ingress_pkt_to_egress",
+          "parameters" : [
+            {
+              "type" : "hexstr",
+              "value" : "0x00000063"
+            },
+            {
+              "type" : "hexstr",
+              "value" : "0x1"
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 474,
+            "column" : 8,
+            "source_fragment" : "clone3(CloneType.I2E, 99, { standard_metadata.ingress_port })"
+          }
+        }
+      ]
+    },
+    {
+      "name" : "act",
+      "id" : 8,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "assign",
+          "parameters" : [
+            {
+              "type" : "field",
+              "value" : ["scalars", "tmp"]
+            },
+            {
+              "type" : "expression",
+              "value" : {
+                "type" : "expression",
+                "value" : {
+                  "op" : "b2d",
+                  "left" : null,
+                  "right" : {
+                    "type" : "bool",
+                    "value" : true
+                  }
+                }
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "name" : "act_0",
+      "id" : 9,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "assign",
+          "parameters" : [
+            {
+              "type" : "field",
+              "value" : ["scalars", "tmp"]
+            },
+            {
+              "type" : "expression",
+              "value" : {
+                "type" : "expression",
+                "value" : {
+                  "op" : "b2d",
+                  "left" : null,
+                  "right" : {
+                    "type" : "bool",
+                    "value" : false
+                  }
+                }
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "name" : "act_1",
+      "id" : 10,
+      "runtime_data" : [],
+      "primitives" : [
+        {
+          "op" : "mark_to_drop",
+          "parameters" : [
+            {
+              "type" : "header",
+              "value" : "standard_metadata"
+            }
+          ],
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 567,
+            "column" : 12,
+            "source_fragment" : "mark_to_drop(standard_metadata)"
+          }
+        }
+      ]
+    }
+  ],
+  "pipelines" : [
+    {
+      "name" : "ingress",
+      "id" : 0,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 345,
+        "column" : 8,
+        "source_fragment" : "IngressPipeImpl"
+      },
+      "init_table" : "IngressPipeImpl.l2_exact_table",
+      "tables" : [
+        {
+          "name" : "IngressPipeImpl.l2_exact_table",
+          "id" : 0,
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 386,
+            "column" : 10,
+            "source_fragment" : "l2_exact_table"
+          },
+          "key" : [
+            {
+              "match_type" : "exact",
+              "name" : "hdr.ethernet.dst_addr",
+              "target" : ["ethernet", "dst_addr"],
+              "mask" : null
+            }
+          ],
+          "match_type" : "exact",
+          "type" : "simple",
+          "max_size" : 1024,
+          "with_counters" : true,
+          "support_timeout" : false,
+          "direct_meters" : null,
+          "action_ids" : [4, 1],
+          "actions" : ["IngressPipeImpl.set_egress_port", "IngressPipeImpl.drop"],
+          "base_default_next" : null,
+          "next_tables" : {
+            "__HIT__" : "tbl_act",
+            "__MISS__" : "tbl_act_0"
+          },
+          "default_entry" : {
+            "action_id" : 1,
+            "action_const" : true,
+            "action_data" : [],
+            "action_entry_const" : true
+          }
+        },
+        {
+          "name" : "tbl_act",
+          "id" : 1,
+          "key" : [],
+          "match_type" : "exact",
+          "type" : "simple",
+          "max_size" : 1024,
+          "with_counters" : false,
+          "support_timeout" : false,
+          "direct_meters" : null,
+          "action_ids" : [8],
+          "actions" : ["act"],
+          "base_default_next" : "node_5",
+          "next_tables" : {
+            "act" : "node_5"
+          },
+          "default_entry" : {
+            "action_id" : 8,
+            "action_const" : true,
+            "action_data" : [],
+            "action_entry_const" : true
+          }
+        },
+        {
+          "name" : "tbl_act_0",
+          "id" : 2,
+          "key" : [],
+          "match_type" : "exact",
+          "type" : "simple",
+          "max_size" : 1024,
+          "with_counters" : false,
+          "support_timeout" : false,
+          "direct_meters" : null,
+          "action_ids" : [9],
+          "actions" : ["act_0"],
+          "base_default_next" : "node_5",
+          "next_tables" : {
+            "act_0" : "node_5"
+          },
+          "default_entry" : {
+            "action_id" : 9,
+            "action_const" : true,
+            "action_data" : [],
+            "action_entry_const" : true
+          }
+        },
+        {
+          "name" : "IngressPipeImpl.l2_ternary_table",
+          "id" : 3,
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 413,
+            "column" : 10,
+            "source_fragment" : "l2_ternary_table"
+          },
+          "key" : [
+            {
+              "match_type" : "ternary",
+              "name" : "hdr.ethernet.dst_addr",
+              "target" : ["ethernet", "dst_addr"],
+              "mask" : null
+            }
+          ],
+          "match_type" : "ternary",
+          "type" : "simple",
+          "max_size" : 1024,
+          "with_counters" : true,
+          "support_timeout" : false,
+          "direct_meters" : null,
+          "action_ids" : [5, 2],
+          "actions" : ["IngressPipeImpl.set_multicast_group", "IngressPipeImpl.drop"],
+          "base_default_next" : "IngressPipeImpl.acl_table",
+          "next_tables" : {
+            "IngressPipeImpl.set_multicast_group" : "IngressPipeImpl.acl_table",
+            "IngressPipeImpl.drop" : "IngressPipeImpl.acl_table"
+          },
+          "default_entry" : {
+            "action_id" : 2,
+            "action_const" : true,
+            "action_data" : [],
+            "action_entry_const" : true
+          }
+        },
+        {
+          "name" : "IngressPipeImpl.acl_table",
+          "id" : 4,
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 477,
+            "column" : 10,
+            "source_fragment" : "acl_table"
+          },
+          "key" : [
+            {
+              "match_type" : "ternary",
+              "name" : "standard_metadata.ingress_port",
+              "target" : ["standard_metadata", "ingress_port"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "hdr.ethernet.dst_addr",
+              "target" : ["ethernet", "dst_addr"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "hdr.ethernet.src_addr",
+              "target" : ["ethernet", "src_addr"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "hdr.ethernet.ether_type",
+              "target" : ["ethernet", "ether_type"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "local_metadata.ip_proto",
+              "target" : ["scalars", "local_metadata_t.ip_proto"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "local_metadata.icmp_type",
+              "target" : ["scalars", "local_metadata_t.icmp_type"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "local_metadata.l4_src_port",
+              "target" : ["scalars", "local_metadata_t.l4_src_port"],
+              "mask" : null
+            },
+            {
+              "match_type" : "ternary",
+              "name" : "local_metadata.l4_dst_port",
+              "target" : ["scalars", "local_metadata_t.l4_dst_port"],
+              "mask" : null
+            }
+          ],
+          "match_type" : "ternary",
+          "type" : "simple",
+          "max_size" : 1024,
+          "with_counters" : true,
+          "support_timeout" : false,
+          "direct_meters" : null,
+          "action_ids" : [6, 7, 3, 0],
+          "actions" : ["IngressPipeImpl.send_to_cpu", "IngressPipeImpl.clone_to_cpu", "IngressPipeImpl.drop", "NoAction"],
+          "base_default_next" : null,
+          "next_tables" : {
+            "IngressPipeImpl.send_to_cpu" : null,
+            "IngressPipeImpl.clone_to_cpu" : null,
+            "IngressPipeImpl.drop" : null,
+            "NoAction" : null
+          },
+          "default_entry" : {
+            "action_id" : 0,
+            "action_const" : false,
+            "action_data" : [],
+            "action_entry_const" : false
+          }
+        }
+      ],
+      "action_profiles" : [],
+      "conditionals" : [
+        {
+          "name" : "node_5",
+          "id" : 0,
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 533,
+            "column" : 16,
+            "source_fragment" : "!l2_exact_table.apply().hit"
+          },
+          "expression" : {
+            "type" : "expression",
+            "value" : {
+              "op" : "not",
+              "left" : null,
+              "right" : {
+                "type" : "expression",
+                "value" : {
+                  "op" : "d2b",
+                  "left" : null,
+                  "right" : {
+                    "type" : "field",
+                    "value" : ["scalars", "tmp"]
+                  }
+                }
+              }
+            }
+          },
+          "true_next" : "IngressPipeImpl.l2_ternary_table",
+          "false_next" : "IngressPipeImpl.acl_table"
+        }
+      ]
+    },
+    {
+      "name" : "egress",
+      "id" : 1,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 546,
+        "column" : 8,
+        "source_fragment" : "EgressPipeImpl"
+      },
+      "init_table" : "node_10",
+      "tables" : [
+        {
+          "name" : "tbl_act_1",
+          "id" : 5,
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 567,
+            "column" : 12,
+            "source_fragment" : "mark_to_drop(standard_metadata)"
+          },
+          "key" : [],
+          "match_type" : "exact",
+          "type" : "simple",
+          "max_size" : 1024,
+          "with_counters" : false,
+          "support_timeout" : false,
+          "direct_meters" : null,
+          "action_ids" : [10],
+          "actions" : ["act_1"],
+          "base_default_next" : null,
+          "next_tables" : {
+            "act_1" : null
+          },
+          "default_entry" : {
+            "action_id" : 10,
+            "action_const" : true,
+            "action_data" : [],
+            "action_entry_const" : true
+          }
+        }
+      ],
+      "action_profiles" : [],
+      "conditionals" : [
+        {
+          "name" : "node_10",
+          "id" : 1,
+          "source_info" : {
+            "filename" : "p4src/main.p4",
+            "line" : 565,
+            "column" : 12,
+            "source_fragment" : "local_metadata.is_multicast == true && ..."
+          },
+          "expression" : {
+            "type" : "expression",
+            "value" : {
+              "op" : "and",
+              "left" : {
+                "type" : "expression",
+                "value" : {
+                  "op" : "==",
+                  "left" : {
+                    "type" : "expression",
+                    "value" : {
+                      "op" : "d2b",
+                      "left" : null,
+                      "right" : {
+                        "type" : "field",
+                        "value" : ["scalars", "local_metadata_t.is_multicast"]
+                      }
+                    }
+                  },
+                  "right" : {
+                    "type" : "bool",
+                    "value" : true
+                  }
+                }
+              },
+              "right" : {
+                "type" : "expression",
+                "value" : {
+                  "op" : "==",
+                  "left" : {
+                    "type" : "field",
+                    "value" : ["standard_metadata", "ingress_port"]
+                  },
+                  "right" : {
+                    "type" : "field",
+                    "value" : ["standard_metadata", "egress_port"]
+                  }
+                }
+              }
+            }
+          },
+          "false_next" : null,
+          "true_next" : "tbl_act_1"
+        }
+      ]
+    }
+  ],
+  "checksums" : [
+    {
+      "name" : "cksum",
+      "id" : 0,
+      "source_info" : {
+        "filename" : "p4src/main.p4",
+        "line" : 580,
+        "column" : 8,
+        "source_fragment" : "update_checksum(hdr.ndp.isValid(), ..."
+      },
+      "target" : ["icmpv6", "checksum"],
+      "type" : "generic",
+      "calculation" : "calc",
+      "verify" : false,
+      "update" : true,
+      "if_cond" : {
+        "type" : "expression",
+        "value" : {
+          "op" : "d2b",
+          "left" : null,
+          "right" : {
+            "type" : "field",
+            "value" : ["ndp", "$valid$"]
+          }
+        }
+      }
+    }
+  ],
+  "force_arith" : [],
+  "extern_instances" : [],
+  "field_aliases" : [
+    [
+      "queueing_metadata.enq_timestamp",
+      ["standard_metadata", "enq_timestamp"]
+    ],
+    [
+      "queueing_metadata.enq_qdepth",
+      ["standard_metadata", "enq_qdepth"]
+    ],
+    [
+      "queueing_metadata.deq_timedelta",
+      ["standard_metadata", "deq_timedelta"]
+    ],
+    [
+      "queueing_metadata.deq_qdepth",
+      ["standard_metadata", "deq_qdepth"]
+    ],
+    [
+      "intrinsic_metadata.ingress_global_timestamp",
+      ["standard_metadata", "ingress_global_timestamp"]
+    ],
+    [
+      "intrinsic_metadata.egress_global_timestamp",
+      ["standard_metadata", "egress_global_timestamp"]
+    ],
+    [
+      "intrinsic_metadata.lf_field_list",
+      ["standard_metadata", "lf_field_list"]
+    ],
+    [
+      "intrinsic_metadata.mcast_grp",
+      ["standard_metadata", "mcast_grp"]
+    ],
+    [
+      "intrinsic_metadata.resubmit_flag",
+      ["standard_metadata", "resubmit_flag"]
+    ],
+    [
+      "intrinsic_metadata.egress_rid",
+      ["standard_metadata", "egress_rid"]
+    ],
+    [
+      "intrinsic_metadata.recirculate_flag",
+      ["standard_metadata", "recirculate_flag"]
+    ],
+    [
+      "intrinsic_metadata.priority",
+      ["standard_metadata", "priority"]
+    ]
+  ],
+  "program" : "p4src/main.p4",
+  "__meta__" : {
+    "version" : [2, 18],
+    "compiler" : "https://github.com/p4lang/p4c"
+  }
+}
\ No newline at end of file
diff --git a/src/device/tests/p4/test-p4info.txt b/src/device/tests/p4/test-p4info.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6382852ad8f597786003252184153b526c66fb9e
--- /dev/null
+++ b/src/device/tests/p4/test-p4info.txt
@@ -0,0 +1,245 @@
+pkg_info {
+  arch: "v1model"
+}
+tables {
+  preamble {
+    id: 33605373
+    name: "IngressPipeImpl.l2_exact_table"
+    alias: "l2_exact_table"
+  }
+  match_fields {
+    id: 1
+    name: "hdr.ethernet.dst_addr"
+    bitwidth: 48
+    match_type: EXACT
+  }
+  action_refs {
+    id: 16812802
+  }
+  action_refs {
+    id: 16796182
+    annotations: "@defaultonly"
+    scope: DEFAULT_ONLY
+  }
+  const_default_action_id: 16796182
+  direct_resource_ids: 318813612
+  size: 1024
+}
+tables {
+  preamble {
+    id: 33573501
+    name: "IngressPipeImpl.l2_ternary_table"
+    alias: "l2_ternary_table"
+  }
+  match_fields {
+    id: 1
+    name: "hdr.ethernet.dst_addr"
+    bitwidth: 48
+    match_type: TERNARY
+  }
+  action_refs {
+    id: 16841371
+  }
+  action_refs {
+    id: 16796182
+    annotations: "@defaultonly"
+    scope: DEFAULT_ONLY
+  }
+  const_default_action_id: 16796182
+  direct_resource_ids: 318768597
+  size: 1024
+}
+tables {
+  preamble {
+    id: 33557865
+    name: "IngressPipeImpl.acl_table"
+    alias: "acl_table"
+  }
+  match_fields {
+    id: 1
+    name: "standard_metadata.ingress_port"
+    bitwidth: 9
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 2
+    name: "hdr.ethernet.dst_addr"
+    bitwidth: 48
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 3
+    name: "hdr.ethernet.src_addr"
+    bitwidth: 48
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 4
+    name: "hdr.ethernet.ether_type"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 5
+    name: "local_metadata.ip_proto"
+    bitwidth: 8
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 6
+    name: "local_metadata.icmp_type"
+    bitwidth: 8
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 7
+    name: "local_metadata.l4_src_port"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  match_fields {
+    id: 8
+    name: "local_metadata.l4_dst_port"
+    bitwidth: 16
+    match_type: TERNARY
+  }
+  action_refs {
+    id: 16833331
+  }
+  action_refs {
+    id: 16782152
+  }
+  action_refs {
+    id: 16796182
+  }
+  action_refs {
+    id: 16800567
+    annotations: "@defaultonly"
+    scope: DEFAULT_ONLY
+  }
+  direct_resource_ids: 318773822
+  size: 1024
+}
+actions {
+  preamble {
+    id: 16800567
+    name: "NoAction"
+    alias: "NoAction"
+  }
+}
+actions {
+  preamble {
+    id: 16796182
+    name: "IngressPipeImpl.drop"
+    alias: "drop"
+  }
+}
+actions {
+  preamble {
+    id: 16812802
+    name: "IngressPipeImpl.set_egress_port"
+    alias: "set_egress_port"
+  }
+  params {
+    id: 1
+    name: "port_num"
+    bitwidth: 9
+  }
+}
+actions {
+  preamble {
+    id: 16841371
+    name: "IngressPipeImpl.set_multicast_group"
+    alias: "set_multicast_group"
+  }
+  params {
+    id: 1
+    name: "gid"
+    bitwidth: 16
+  }
+}
+actions {
+  preamble {
+    id: 16833331
+    name: "IngressPipeImpl.send_to_cpu"
+    alias: "send_to_cpu"
+  }
+}
+actions {
+  preamble {
+    id: 16782152
+    name: "IngressPipeImpl.clone_to_cpu"
+    alias: "clone_to_cpu"
+  }
+}
+direct_counters {
+  preamble {
+    id: 318813612
+    name: "l2_exact_table_counter"
+    alias: "l2_exact_table_counter"
+  }
+  spec {
+    unit: BOTH
+  }
+  direct_table_id: 33605373
+}
+direct_counters {
+  preamble {
+    id: 318768597
+    name: "l2_ternary_table_counter"
+    alias: "l2_ternary_table_counter"
+  }
+  spec {
+    unit: BOTH
+  }
+  direct_table_id: 33573501
+}
+direct_counters {
+  preamble {
+    id: 318773822
+    name: "acl_table_counter"
+    alias: "acl_table_counter"
+  }
+  spec {
+    unit: BOTH
+  }
+  direct_table_id: 33557865
+}
+controller_packet_metadata {
+  preamble {
+    id: 67132047
+    name: "packet_in"
+    alias: "packet_in"
+    annotations: "@controller_header(\"packet_in\")"
+  }
+  metadata {
+    id: 1
+    name: "ingress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "_pad"
+    bitwidth: 7
+  }
+}
+controller_packet_metadata {
+  preamble {
+    id: 67111875
+    name: "packet_out"
+    alias: "packet_out"
+    annotations: "@controller_header(\"packet_out\")"
+  }
+  metadata {
+    id: 1
+    name: "egress_port"
+    bitwidth: 9
+  }
+  metadata {
+    id: 2
+    name: "_pad"
+    bitwidth: 7
+  }
+}
+type_info {
+}
diff --git a/src/device/tests/test_internal_p4.py b/src/device/tests/test_internal_p4.py
new file mode 100644
index 0000000000000000000000000000000000000000..4907e538843dfa5d9c7833b4d02f05e483720510
--- /dev/null
+++ b/src/device/tests/test_internal_p4.py
@@ -0,0 +1,252 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Internal P4 driver tests.
+"""
+
+import pytest
+from device.service.drivers.p4.p4_driver import P4Driver
+from device.service.drivers.p4.p4_common import (
+    matches_mac, encode_mac, decode_mac, encode,
+    matches_ipv4, encode_ipv4, decode_ipv4,
+    matches_ipv6, encode_ipv6, decode_ipv6,
+    encode_num, decode_num
+)
+from .device_p4 import(
+        DEVICE_P4_IP_ADDR, DEVICE_P4_PORT, DEVICE_P4_DPID, DEVICE_P4_NAME,
+        DEVICE_P4_VENDOR, DEVICE_P4_HW_VER, DEVICE_P4_SW_VER,
+        DEVICE_P4_WORKERS, DEVICE_P4_GRACE_PERIOD,
+        DEVICE_P4_CONFIG_TABLE_ENTRY, DEVICE_P4_DECONFIG_TABLE_ENTRY)
+from .mock_p4runtime_service import MockP4RuntimeService
+
+
+@pytest.fixture(scope='session')
+def p4runtime_service():
+    """
+    Spawn a mock P4Runtime server.
+
+    :return: void
+    """
+    _service = MockP4RuntimeService(
+        address=DEVICE_P4_IP_ADDR, port=DEVICE_P4_PORT,
+        max_workers=DEVICE_P4_WORKERS,
+        grace_period=DEVICE_P4_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+
+@pytest.fixture(scope='session')
+def device_driverapi_p4():
+    """
+    Invoke an instance of the P4 driver.
+
+    :return: void
+    """
+    _driver = P4Driver(
+        address=DEVICE_P4_IP_ADDR,
+        port=DEVICE_P4_PORT,
+        id=DEVICE_P4_DPID,
+        name=DEVICE_P4_NAME,
+        vendor=DEVICE_P4_VENDOR,
+        hw_ver=DEVICE_P4_HW_VER,
+        sw_ver=DEVICE_P4_SW_VER)
+    _driver.Connect()
+    yield _driver
+    _driver.Disconnect()
+
+
+def test_device_driverapi_p4_setconfig(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the SetConfig RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    result = device_driverapi_p4.SetConfig(
+        DEVICE_P4_CONFIG_TABLE_ENTRY
+    )
+    assert list(result)
+
+
+def test_device_driverapi_p4_getconfig(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the GetConfig RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    pytest.skip('Skipping test: GetConfig')
+
+
+def test_device_driverapi_p4_getresource(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the GetResource RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    pytest.skip('Skipping test: GetResource')
+
+
+def test_device_driverapi_p4_deleteconfig(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the DeleteConfig RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    result = device_driverapi_p4.DeleteConfig(
+        DEVICE_P4_DECONFIG_TABLE_ENTRY
+    )
+    assert list(result)
+
+
+def test_device_driverapi_p4_subscribe_state(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the SubscribeState RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    pytest.skip('Skipping test: SubscribeState')
+
+
+def test_device_driverapi_p4_getstate(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the GetState RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    pytest.skip('Skipping test: GetState')
+
+
+def test_device_driverapi_p4_unsubscribe_state(
+        p4runtime_service: MockP4RuntimeService,
+        device_driverapi_p4: P4Driver):
+    """
+    Test the UnsubscribeState RPC of the P4 driver API.
+
+    :param p4runtime_service: Mock P4Runtime service
+    :param device_driverapi_p4: instance of the P4 device driver
+    :return: void
+    """
+    pytest.skip('Skipping test: UnsubscribeState')
+
+
+def test_p4_common_mac():
+    """
+    Test MAC converters.
+
+    :return: void
+    """
+    wrong_mac = "aa:bb:cc:dd:ee"
+    assert not matches_mac(wrong_mac)
+
+    mac = "aa:bb:cc:dd:ee:fe"
+    assert matches_mac(mac)
+    enc_mac = encode_mac(mac)
+    assert enc_mac == b'\xaa\xbb\xcc\xdd\xee\xfe',\
+        "String-based MAC address to bytes failed"
+    enc_mac = encode(mac, 6*8)
+    assert enc_mac == b'\xaa\xbb\xcc\xdd\xee\xfe',\
+        "String-based MAC address to bytes failed"
+    dec_mac = decode_mac(enc_mac)
+    assert mac == dec_mac,\
+        "MAC address bytes to string failed"
+
+
+def test_p4_common_ipv4():
+    """
+    Test IPv4 converters.
+
+    :return: void
+    """
+    assert not matches_ipv4("10.0.0.1.5")
+    assert not matches_ipv4("256.0.0.1")
+    assert not matches_ipv4("256.0.1")
+    assert not matches_ipv4("10001")
+
+    ipv4 = "10.0.0.1"
+    assert matches_ipv4(ipv4)
+    enc_ipv4 = encode_ipv4(ipv4)
+    assert enc_ipv4 == b'\x0a\x00\x00\x01',\
+        "String-based IPv4 address to bytes failed"
+    dec_ipv4 = decode_ipv4(enc_ipv4)
+    assert ipv4 == dec_ipv4,\
+        "IPv4 address bytes to string failed"
+
+
+def test_p4_common_ipv6():
+    """
+    Test IPv6 converters.
+
+    :return: void
+    """
+    assert not matches_ipv6('10.0.0.1')
+    assert matches_ipv6('2001:0000:85a3::8a2e:370:1111')
+
+    ipv6 = "1:2:3:4:5:6:7:8"
+    assert matches_ipv6(ipv6)
+    enc_ipv6 = encode_ipv6(ipv6)
+    assert enc_ipv6 == \
+           b'\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08',\
+           "String-based IPv6 address to bytes failed"
+    dec_ipv6 = decode_ipv6(enc_ipv6)
+    assert ipv6 == dec_ipv6,\
+        "IPv6 address bytes to string failed"
+
+
+def test_p4_common_numbers():
+    """
+    Test numerical converters.
+
+    :return: void
+    """
+    num = 1337
+    byte_len = 5
+    enc_num = encode_num(num, byte_len * 8)
+    assert enc_num == b'\x00\x00\x00\x05\x39',\
+        "Number to bytes conversion failed"
+    dec_num = decode_num(enc_num)
+    assert num == dec_num,\
+        "Bytes to number conversion failed"
+    assert encode((num,), byte_len * 8) == enc_num
+    assert encode([num], byte_len * 8) == enc_num
+
+    num = 256
+    try:
+        encode_num(num, 8)
+    except OverflowError:
+        pass
diff --git a/src/device/tests/test_unit_p4.py b/src/device/tests/test_unit_p4.py
deleted file mode 100644
index 777ab280aa2b500c3c2b445fcecdf81024b817f3..0000000000000000000000000000000000000000
--- a/src/device/tests/test_unit_p4.py
+++ /dev/null
@@ -1,97 +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 pytest
-from device.service.drivers.p4.p4_driver import P4Driver
-from .device_p4 import(
-        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
-
-
-@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()
-
-
-@pytest.fixture(scope='session')
-def device_driverapi_p4():
-    _driver = P4Driver(
-        address=DEVICE_P4_ADDRESS,
-        port=DEVICE_P4_PORT,
-        id=DEVICE_P4_DPID,
-        name=DEVICE_P4_NAME,
-        vendor=DEVICE_P4_VENDOR,
-        hw_ver=DEVICE_P4_HW_VER,
-        sw_ver=DEVICE_P4_SW_VER,
-        pipeconf=DEVICE_P4_PIPECONF)
-    _driver.Connect()
-    yield _driver
-    _driver.Disconnect()
-
-
-def test_device_driverapi_p4_setconfig(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.SetConfig([])
-    return
-
-
-def test_device_driverapi_p4_getconfig(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.GetConfig()
-    return
-
-
-def test_device_driverapi_p4_getresource(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.GetResource("")
-    return
-
-
-def test_device_driverapi_p4_getstate(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.GetState()
-    return
-
-
-def test_device_driverapi_p4_deleteconfig(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.DeleteConfig([])
-    return
-
-
-def test_device_driverapi_p4_subscribe_state(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.SubscribeState([])
-    return
-
-
-def test_device_driverapi_p4_unsubscribe_state(
-        p4runtime_service: MockP4RuntimeService,
-        device_driverapi_p4: P4Driver):  # pylint: disable=redefined-outer-name
-    device_driverapi_p4.UnsubscribeState([])
-    return
diff --git a/src/device/tests/test_unitary_emulated.py b/src/device/tests/test_unitary_emulated.py
index 87c067a08e37475bcf44b0546abcfcaf25fc965d..745c25c1eba679dc67e0ed9e04f38eb0ae8c3af4 100644
--- a/src/device/tests/test_unitary_emulated.py
+++ b/src/device/tests/test_unitary_emulated.py
@@ -299,12 +299,7 @@ def test_device_emulated_monitor(
     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)
+        timestamp = float(received_sample.timestamp.timestamp)
         assert timestamp > t_start_monitoring
         assert timestamp < t_end_monitoring
         assert received_sample.kpi_value.HasField('floatVal') or received_sample.kpi_value.HasField('intVal')
diff --git a/src/device/tests/test_unitary_openconfig.py b/src/device/tests/test_unitary_openconfig.py
index 32fb5709a98d095982d46d16450117a84f89f165..6144a95d96bbbfd68213356f06573a2200c11bb1 100644
--- a/src/device/tests/test_unitary_openconfig.py
+++ b/src/device/tests/test_unitary_openconfig.py
@@ -29,8 +29,12 @@ from .PrepareTestScenario import ( # pylint: disable=unused-import
     mock_service, device_service, context_client, device_client, monitoring_client, test_prepare_environment)
 
 try:
-    from .Device_OpenConfig_Infinera1 import(
+    #from .Device_OpenConfig_Infinera1 import(
     #from .Device_OpenConfig_Infinera2 import(
+    #from .Device_OpenConfig_Adva import(
+    #from .Device_OpenConfig_Adva_149 import(
+    from .Device_OpenConfig_Adva_155 import(
+    #from .Device_OpenConfig_Cisco import(
         DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
         DEVICE_OC_UUID)
     ENABLE_OPENCONFIG = True
@@ -38,10 +42,9 @@ except ImportError:
     ENABLE_OPENCONFIG = False
 
 ENABLE_OPENCONFIG_CONFIGURE   = True
-ENABLE_OPENCONFIG_MONITOR     = True
+ENABLE_OPENCONFIG_MONITOR     = False
 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)
diff --git a/src/device/tests/test_unitary_p4.py b/src/device/tests/test_unitary_p4.py
index 86a669bd40deb8f7839d3e682b8a1f52f3c38e1b..43313caff33d646918b9be23c87e499185714a2c 100644
--- a/src/device/tests/test_unitary_p4.py
+++ b/src/device/tests/test_unitary_p4.py
@@ -12,22 +12,34 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import copy, grpc, logging, pytest
-from common.proto.context_pb2 import Device, DeviceId
+"""
+P4 unit tests.
+"""
+
+import copy
+import logging
+import operator
+import grpc
+import pytest
+from common.proto.context_pb2 import ConfigActionEnum, Device, DeviceId,\
+    DeviceOperationalStatusEnum
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from device.service.DeviceService import DeviceService
 from device.service.driver_api._Driver import _Driver
-from .PrepareTestScenario import ( # pylint: disable=unused-import
+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)
+    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)
+        DEVICE_P4, DEVICE_P4_ID, DEVICE_P4_UUID,
+        DEVICE_P4_IP_ADDR, DEVICE_P4_PORT, DEVICE_P4_WORKERS,
+        DEVICE_P4_GRACE_PERIOD, DEVICE_P4_CONNECT_RULES,
+        DEVICE_P4_CONFIG_TABLE_ENTRY, DEVICE_P4_DECONFIG_TABLE_ENTRY)
     ENABLE_P4 = True
 except ImportError:
     ENABLE_P4 = False
@@ -35,10 +47,17 @@ except ImportError:
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
+
 @pytest.fixture(scope='session')
 def p4runtime_service():
+    """
+    Spawn a mock P4Runtime server.
+
+    :return: void
+    """
     _service = MockP4RuntimeService(
-        address=DEVICE_P4_ADDRESS, port=DEVICE_P4_PORT,
+        address=DEVICE_P4_IP_ADDR,
+        port=DEVICE_P4_PORT,
         max_workers=DEVICE_P4_WORKERS,
         grace_period=DEVICE_P4_GRACE_PERIOD)
     _service.start()
@@ -47,27 +66,35 @@ def p4runtime_service():
 
 
 # ----- 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
+    """
+    Test AddDevice RPC with wrong inputs.
 
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
+    :param context_client: context component client
+    :param device_client: device component client
+    :param device_service: device component service
+    :return:
+    """
 
-    with pytest.raises(grpc.RpcError) as e:
+    if not ENABLE_P4:
+        pytest.skip('Skipping test: No P4 device has been configured')
+
+    with pytest.raises(grpc.RpcError) as ex:
         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_P4_CONFIG_TABLE_ENTRY)
         device_client.AddDevice(Device(**device_p4_with_extra_rules))
-    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    assert ex.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())
+    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(ex.value.details())
     assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
 
 
@@ -76,35 +103,67 @@ def test_device_p4_add_correct(
         device_client: DeviceClient,                # pylint: disable=redefined-outer-name
         device_service: DeviceService,              # pylint: disable=redefined-outer-name
         p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+    """
+    Test AddDevice RPC with correct inputs.
+
+    :param context_client: context component client
+    :param device_client: device component client
+    :param device_service: device component service
+    :param p4runtime_service: Mock P4Runtime service
+    :return:
+    """
 
-    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_instance_cache = device_service.device_servicer.driver_instance_cache
-    driver : _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
+    driver: _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
     assert driver is not None
 
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
+    config_rules = [
+        (
+            ConfigActionEnum.Name(config_rule.action),
+            config_rule.custom.resource_key,
+            config_rule.custom.resource_value
+        )
+        for config_rule in device_data.device_config.config_rules
+        if config_rule.WhichOneof('config_rule') == 'custom'
+    ]
+    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_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
+    """
+    Test GetDevice RPC.
+
+    :param context_client: context component client
+    :param device_client: device component client
+    :param device_service: device component service
+    :param p4runtime_service: Mock P4Runtime service
+    :return:
+    """
 
-    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_ID))
-    LOGGER.info('initial_config = {:s}'.format(
-        grpc_message_to_json_string(initial_config)))
+    assert len(initial_config.config_rules) == 0
+    LOGGER.info('initial_config = %s',
+                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)))
+    LOGGER.info('device_data = %s', grpc_message_to_json_string(device_data))
 
 
 def test_device_p4_configure(
@@ -112,11 +171,58 @@ 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
+    """
+    Test ConfigureDevice RPC.
 
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
+    :param context_client: context component client
+    :param device_client: device component client
+    :param device_service: device component service
+    :param p4runtime_service: Mock P4Runtime service
+    :return:
+    """
 
-    pytest.skip('Skipping test for unimplemented method')
+    if not ENABLE_P4:
+        pytest.skip('Skipping test: No P4 device has been configured')
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver: _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
+    assert driver is not None
+
+    # No entries should exist at this point in time
+    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    assert len(driver_config) == len(driver.get_manager().get_resource_keys())
+    assert driver.get_manager().count_active_entries() == 0
+
+    # Flip the operational status and check it is correctly flipped in Context
+    device_p4_with_operational_status = copy.deepcopy(DEVICE_P4)
+    device_p4_with_operational_status['device_operational_status'] = \
+        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+    device_client.ConfigureDevice(Device(**device_p4_with_operational_status))
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
+    assert device_data.device_operational_status == \
+           DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+    # Insert a new table entry
+    device_p4_with_config_rules = copy.deepcopy(DEVICE_P4)
+    device_p4_with_config_rules['device_config']['config_rules'].extend(
+        DEVICE_P4_CONFIG_TABLE_ENTRY)
+    device_client.ConfigureDevice(Device(**device_p4_with_config_rules))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action),
+         config_rule.custom.resource_key,
+         config_rule.custom.resource_value)
+        for config_rule in device_data.device_config.config_rules
+        if config_rule.WhichOneof('config_rule') == 'custom'
+    ]
+    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_P4_CONFIG_TABLE_ENTRY:
+        assert 'custom' in config_rule
 
 
 def test_device_p4_deconfigure(
@@ -124,11 +230,53 @@ 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
+    """
+    Test DeconfigureDevice RPC.
 
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
+    :param context_client: context component client
+    :param device_client: device component client
+    :param device_service: device component service
+    :param p4runtime_service: Mock P4Runtime service
+    :return:
+    """
 
-    pytest.skip('Skipping test for unimplemented method')
+    if not ENABLE_P4:
+        pytest.skip('Skipping test: No P4 device has been configured')
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver: _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
+    assert driver is not None
+
+    # Delete a table entry
+    device_p4_with_config_rules = copy.deepcopy(DEVICE_P4)
+    device_p4_with_config_rules['device_config']['config_rules'].extend(
+        DEVICE_P4_DECONFIG_TABLE_ENTRY)
+    device_client.ConfigureDevice(Device(**device_p4_with_config_rules))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action),
+         config_rule.custom.resource_key,
+         config_rule.custom.resource_value)
+        for config_rule in device_data.device_config.config_rules
+        if config_rule.WhichOneof('config_rule') == 'custom'
+    ]
+    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_P4_CONFIG_TABLE_ENTRY:
+        assert 'custom' in config_rule
+
+    # Flip the operational status and check it is correctly flipped in Context
+    device_p4_with_operational_status = copy.deepcopy(DEVICE_P4)
+    device_p4_with_operational_status['device_operational_status'] = \
+        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
+    device_client.ConfigureDevice(Device(**device_p4_with_operational_status))
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
+    assert device_data.device_operational_status == \
+           DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
 
 
 def test_device_p4_delete(
@@ -136,10 +284,20 @@ def test_device_p4_delete(
         device_client: DeviceClient,                # pylint: disable=redefined-outer-name
         device_service: DeviceService,              # pylint: disable=redefined-outer-name
         p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+    """
+    Test DeleteDevice RPC.
+
+    :param context_client: context component client
+    :param device_client: device component client
+    :param device_service: device component service
+    :param p4runtime_service: Mock P4Runtime service
+    :return:
+    """
 
-    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_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)
+    driver: _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
     assert driver is None
diff --git a/src/monitoring/.gitignore b/src/monitoring/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ac497892a71b6dda0ef118a1d174a5409849a201
--- /dev/null
+++ b/src/monitoring/.gitignore
@@ -0,0 +1,3 @@
+# Ignoring specific folders/files used internally while coding Monitoring component
+proto/
+genproto_win.sh
diff --git a/src/monitoring/.gitlab-ci.yml b/src/monitoring/.gitlab-ci.yml
index fac3f967bbf531ef5cc9b67b2a1afe47fb9990d5..ef3a8c39a045dd059f8a7942223bdc20775ae92c 100644
--- a/src/monitoring/.gitlab-ci.yml
+++ b/src/monitoring/.gitlab-ci.yml
@@ -49,14 +49,14 @@ unit test monitoring:
   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 influxdb; then docker rm -f influxdb; else echo "influxdb image is not in the system"; fi
+    - if docker container ls | grep questdb; then docker rm -f questdb; else echo "questdb image is not in the system"; 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 pull "influxdb:1.8"
-    - docker run --name influxdb -d -p 8086:8086 -e INFLUXDB_DB=$INFLUXDB_DATABASE -e INFLUXDB_ADMIN_USER=$INFLUXDB_USER -e INFLUXDB_ADMIN_PASSWORD=$INFLUXDB_PASSWORD -e INFLUXDB_HTTP_AUTH_ENABLED=True --network=teraflowbridge influxdb:1.8
+    - docker pull questdb/questdb
+    - docker run --name questdb -d -p 9000:9000  -p 9009:9009  -p 8812:8812  -p 9003:9003  -e QDB_CAIRO_COMMIT_LAG=1000 -e QDB_CAIRO_MAX_UNCOMMITTED_ROWS=100000 --network=teraflowbridge --rm questdb/questdb
     - sleep 10
-    - docker run --name $IMAGE_NAME -d -p 7070:7070 --env INFLUXDB_USER=$INFLUXDB_USER --env INFLUXDB_PASSWORD=$INFLUXDB_PASSWORD --env INFLUXDB_DATABASE=$INFLUXDB_DATABASE --env INFLUXDB_HOSTNAME=influxdb --env INFLUXDB_PORT=8086 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG
+    - docker run --name $IMAGE_NAME -d -p 7070:7070 --env METRICSDB_HOSTNAME=questdb --env METRICSDB_ILP_PORT=9009 --env METRICSDB_REST_PORT=9000 --env METRICSDB_TABLE=monitoring -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG
     - sleep 30
     - docker ps -a
     - docker logs $IMAGE_NAME
@@ -65,7 +65,7 @@ unit test monitoring:
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
     - docker rm -f $IMAGE_NAME
-    - docker rm -f  influxdb
+    - docker rm -f  questdb
     - 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)'
diff --git a/src/monitoring/client/MonitoringClient.py b/src/monitoring/client/MonitoringClient.py
index 7042042dac6c070f79885226ec9a576e10c38f40..f65072f19013b820312aa56b7f0062f9c95f712c 100644
--- a/src/monitoring/client/MonitoringClient.py
+++ b/src/monitoring/client/MonitoringClient.py
@@ -16,11 +16,14 @@ 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.proto.context_pb2 import Empty
-from common.proto.monitoring_pb2 import Kpi, KpiDescriptor, KpiId, MonitorKpiRequest
-from common.proto.monitoring_pb2_grpc import MonitoringServiceStub
+
 from common.tools.client.RetryDecorator import retry, delay_exponential
 from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.proto.context_pb2 import Empty
+from common.proto.monitoring_pb2 import Kpi, KpiDescriptor, KpiId, MonitorKpiRequest, \
+    KpiDescriptorList, KpiQuery, KpiList, SubsDescriptor, SubscriptionID, SubsIDList, \
+    AlarmDescriptor, AlarmID, AlarmIDList, AlarmResponse, AlarmSubscription
+from common.proto.monitoring_pb2_grpc import MonitoringServiceStub
 
 LOGGER = logging.getLogger(__name__)
 MAX_RETRIES = 15
@@ -48,10 +51,17 @@ class MonitoringClient:
         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)))
+    def SetKpi(self, request : KpiDescriptor) -> KpiId:
+        LOGGER.debug('SetKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.SetKpi(request)
+        LOGGER.debug('SetKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def DeleteKpi(self,request : KpiId) -> Empty:
+        LOGGER.debug('DeleteKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.DeleteKpi(request)
+        LOGGER.info('DeleteKpi result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
@@ -61,6 +71,13 @@ class MonitoringClient:
         LOGGER.debug('GetKpiDescriptor result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
+    @RETRY_DECORATOR
+    def GetKpiDescriptorList(self, request : Empty) -> KpiDescriptorList:
+        LOGGER.debug('GetKpiDescriptorList: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetKpiDescriptorList(request)
+        LOGGER.debug('GetKpiDescriptorList 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)))
@@ -75,6 +92,73 @@ class MonitoringClient:
         LOGGER.debug('MonitorKpi result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
+    @RETRY_DECORATOR
+    def QueryKpiData(self, request : KpiQuery) -> KpiList:
+        LOGGER.debug('QueryKpiData: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.QueryKpiData(request)
+        LOGGER.debug('QueryKpiData result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def SubscribeKpi(self, request : SubsDescriptor) -> Iterator[KpiList]:
+        LOGGER.debug('SubscribeKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.SubscribeKpi(request)
+        LOGGER.debug('SubscribeKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetSubsDescriptor(self, request : SubscriptionID) -> SubsDescriptor:
+        LOGGER.debug('GetSubsDescriptor: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetSubsDescriptor(request)
+        LOGGER.debug('GetSubsDescriptor result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetSubscriptions(self, request : Empty) -> SubsIDList:
+        LOGGER.debug('GetSubscriptions: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetSubscriptions(request)
+        LOGGER.debug('GetSubscriptions result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def DeleteSubscription(self, request : SubscriptionID) -> Empty:
+        LOGGER.debug('DeleteSubscription: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.DeleteSubscription(request)
+        LOGGER.debug('DeleteSubscription result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def SetKpiAlarm(self, request : AlarmDescriptor) -> AlarmID:
+        LOGGER.debug('SetKpiAlarm: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.SetKpiAlarm(request)
+        LOGGER.debug('SetKpiAlarm result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetAlarms(self, request : Empty) -> AlarmIDList:
+        LOGGER.debug('GetAlarms: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetAlarms(request)
+        LOGGER.debug('GetAlarms result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    def GetAlarmDescriptor(self, request : AlarmID) -> AlarmDescriptor:
+        LOGGER.debug('GetAlarmDescriptor: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetAlarmDescriptor(request)
+        LOGGER.debug('GetAlarmDescriptor result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    def GetAlarmResponseStream(self, request : AlarmSubscription) -> AlarmResponse:
+        LOGGER.debug('GetAlarmResponseStream: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetAlarmResponseStream(request)
+        LOGGER.debug('GetAlarmResponseStream result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    def DeleteAlarm(self, request : AlarmID) -> Empty:
+        LOGGER.debug('DeleteAlarm: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.DeleteAlarm(request)
+        LOGGER.debug('DeleteAlarm 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)))
diff --git a/src/monitoring/requirements.in b/src/monitoring/requirements.in
index 1b5459e32c326893f89df02bd1c96fb459577a36..50f283a1940ed99d16276857d2cab22220921879 100644
--- a/src/monitoring/requirements.in
+++ b/src/monitoring/requirements.in
@@ -5,17 +5,18 @@ fastcache==1.1.0
 #opencensus[stackdriver]
 #google-cloud-profiler
 #numpy
-Jinja2==3.0.3
-ncclient==0.6.13
-p4runtime==1.3.0
-paramiko==2.9.2
-influxdb
+#Jinja2==3.0.3
+#ncclient==0.6.13
+#p4runtime==1.3.0
+#paramiko==2.9.2
+influx-line-protocol==0.1.4
 python-dateutil==2.8.2
 python-json-logger==2.0.2
 pytz==2021.3
 redis==4.1.2
 requests==2.27.1
 xmltodict==0.12.0
+questdb==1.0.1
 
 # pip's dependency resolver does not take into account installed packages.
 # p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one
diff --git a/src/monitoring/service/EventTools.py b/src/monitoring/service/EventTools.py
index 6d017b627e2d464efbb67c7903afa529176bccd3..4999d2a95991d79ed5417948e220d35aa668c653 100644
--- a/src/monitoring/service/EventTools.py
+++ b/src/monitoring/service/EventTools.py
@@ -19,16 +19,13 @@ import grpc
 
 from common.rpc_method_wrapper.ServiceExceptions import ServiceException
 from context.client.ContextClient import ContextClient
-#from common.proto import kpi_sample_types_pb2
+
 from common.proto.context_pb2 import Empty, EventTypeEnum
 
-from common.logger import getJSONLogger
 from monitoring.client.MonitoringClient import MonitoringClient
+from monitoring.service.MonitoringServiceServicerImpl import LOGGER
 from common.proto import monitoring_pb2
 
-LOGGER = getJSONLogger('monitoringservice-server')
-LOGGER.setLevel('DEBUG')
-
 class EventsDeviceCollector:
     def __init__(self) -> None: # pylint: disable=redefined-outer-name
         self._events_queue = Queue()
@@ -74,7 +71,7 @@ class EventsDeviceCollector:
             kpi_id_list = []
 
             while not self._events_queue.empty():
-                LOGGER.info('getting Kpi by KpiID')
+                # LOGGER.info('getting Kpi by KpiID')
                 event = self.get_event(block=True)
                 if event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE:
                     device = self._context_client.GetDevice(event.device_id)
@@ -91,14 +88,11 @@ class EventsDeviceCollector:
                             kpi_descriptor.device_id.CopyFrom(device.device_id)
                             kpi_descriptor.endpoint_id.CopyFrom(end_point.endpoint_id)
 
-                            kpi_id = self._monitoring_client.CreateKpi(kpi_descriptor)
+                            kpi_id = self._monitoring_client.SetKpi(kpi_descriptor)
                             kpi_id_list.append(kpi_id)
-
             return kpi_id_list
-
         except ServiceException as e:
             LOGGER.exception('ListenEvents exception')
-
         except Exception as e:  # pragma: no cover
             LOGGER.exception('ListenEvents exception')
 
diff --git a/src/monitoring/service/MetricsDBTools.py b/src/monitoring/service/MetricsDBTools.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc194c430c9700a2d89e0757c75c64025082ac29
--- /dev/null
+++ b/src/monitoring/service/MetricsDBTools.py
@@ -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.
+
+from questdb.ingress import Sender, IngressError
+import requests
+import json
+import logging
+import datetime
+
+LOGGER = logging.getLogger(__name__)
+
+class MetricsDB():
+  def __init__(self, host, ilp_port, rest_port, table):
+    self.host=host
+    self.ilp_port=int(ilp_port)
+    self.rest_port=rest_port
+    self.table=table
+    self.create_table()
+
+  def write_KPI(self,time,kpi_id,kpi_sample_type,device_id,endpoint_id,service_id,kpi_value):
+    counter=0
+    number_of_retries=10
+    while (counter<number_of_retries):
+      try:
+        with Sender(self.host, self.ilp_port) as sender:
+          sender.row(
+          self.table,
+          symbols={
+              'kpi_id': kpi_id,
+              'kpi_sample_type': kpi_sample_type,
+              'device_id': device_id,
+              'endpoint_id': endpoint_id,
+              'service_id': service_id},
+          columns={
+              'kpi_value': kpi_value},
+          at=datetime.datetime.fromtimestamp(time))
+          sender.flush()
+        counter=number_of_retries
+        LOGGER.info(f"KPI written")
+      except IngressError as ierr:
+        # LOGGER.info(ierr)
+        # LOGGER.info(f"Ingress Retry number {counter}")
+        counter=counter+1
+
+
+  def run_query(self, sql_query):
+    query_params = {'query': sql_query, 'fmt' : 'json'}
+    url = f"http://{self.host}:{self.rest_port}/exec"
+    response = requests.get(url, params=query_params)
+    json_response = json.loads(response.text)
+    LOGGER.info(f"Query executed, result:{json_response}")
+  
+  def create_table(self):
+    query = f'CREATE TABLE IF NOT EXISTS {self.table}'\
+    '(kpi_id SYMBOL,'\
+    'kpi_sample_type SYMBOL,'\
+    'device_id SYMBOL,'\
+    'endpoint_id SYMBOL,'\
+    'service_id SYMBOL,'\
+    'timestamp TIMESTAMP,'\
+    'kpi_value DOUBLE)'\
+    'TIMESTAMP(timestamp);'
+    self.run_query(query)
+    LOGGER.info(f"Table {self.table} created")
diff --git a/src/monitoring/service/MonitoringServiceServicerImpl.py b/src/monitoring/service/MonitoringServiceServicerImpl.py
index 00dbf7c8ce84c618581762090ddfca663e304814..df3b907415aabe0ed4c276ac6ac09582636ebe6b 100644
--- a/src/monitoring/service/MonitoringServiceServicerImpl.py
+++ b/src/monitoring/service/MonitoringServiceServicerImpl.py
@@ -13,47 +13,63 @@
 # limitations under the License.
 
 import os, grpc, logging
-from prometheus_client import Counter, Summary
-from common.proto import context_pb2
-from common.proto import device_pb2
-from common.proto import monitoring_pb2
-from common.proto import monitoring_pb2_grpc
+
+from typing import Iterator
+
+from common.Constants import ServiceNameEnum
+from common.Settings import get_setting, get_service_port_grpc, get_service_host
+from common.logger import getJSONLogger
+from common.proto.context_pb2 import Empty
+from common.proto.device_pb2 import MonitoringSettings
 from common.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.proto.monitoring_pb2_grpc import MonitoringServiceServicer
+from common.proto.monitoring_pb2 import AlarmResponse, AlarmDescriptor, AlarmIDList, SubsIDList, KpiId, \
+    KpiDescriptor, KpiList, KpiQuery, SubsDescriptor, SubscriptionID, AlarmID, KpiDescriptorList, \
+    MonitorKpiRequest, Kpi, AlarmSubscription
 from common.rpc_method_wrapper.ServiceExceptions import ServiceException
-from monitoring.service import SqliteTools, InfluxTools
+
+from monitoring.service import SqliteTools, MetricsDBTools
 from device.client.DeviceClient import DeviceClient
 
-LOGGER = logging.getLogger(__name__)
+from prometheus_client import Counter, Summary
+
+LOGGER = getJSONLogger('monitoringservice-server')
+LOGGER.setLevel('DEBUG')
 
 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")
-INFLUXDB_USER = os.environ.get("INFLUXDB_USER")
-INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD")
-INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE")
+METRICSDB_HOSTNAME  = os.environ.get("METRICSDB_HOSTNAME")
+METRICSDB_ILP_PORT  = os.environ.get("METRICSDB_ILP_PORT")
+METRICSDB_REST_PORT = os.environ.get("METRICSDB_REST_PORT")
+METRICSDB_TABLE     = os.environ.get("METRICSDB_TABLE")
 
 
-class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceServicer):
+DEVICESERVICE_SERVICE_HOST = get_setting('DEVICESERVICE_SERVICE_HOST',      default=get_service_host(ServiceNameEnum.DEVICE)     )
+DEVICESERVICE_SERVICE_PORT_GRPC = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC', default=get_service_port_grpc(ServiceNameEnum.DEVICE))
+
+
+class MonitoringServiceServicerImpl(MonitoringServiceServicer):
     def __init__(self):
         LOGGER.info('Init monitoringService')
 
         # Init sqlite monitoring db
         self.sql_db = SqliteTools.SQLite('monitoring.db')
+        self.deviceClient = DeviceClient(host=DEVICESERVICE_SERVICE_HOST, port=DEVICESERVICE_SERVICE_PORT_GRPC)  # instantiate the client
 
-        # Create influx_db client
-        self.influx_db = InfluxTools.Influx(INFLUXDB_HOSTNAME,"8086",INFLUXDB_USER,INFLUXDB_PASSWORD,INFLUXDB_DATABASE)
+        self.metrics_db = MetricsDBTools.MetricsDB(METRICSDB_HOSTNAME,METRICSDB_ILP_PORT,METRICSDB_REST_PORT,METRICSDB_TABLE)
+        LOGGER.info('MetricsDB initialized')
 
-    # CreateKpi (CreateKpiRequest) returns (KpiId) {}
-    def CreateKpi(
-        self, request : monitoring_pb2.KpiDescriptor, grpc_context : grpc.ServicerContext
-    ) -> monitoring_pb2.KpiId:
+    # SetKpi (SetKpiRequest) returns (KpiId) {}
+    def SetKpi(
+        self, request : KpiDescriptor, grpc_context : grpc.ServicerContext
+    ) -> KpiId:
         # CREATEKPI_COUNTER_STARTED.inc()
-        LOGGER.info('CreateKpi')
+        LOGGER.info('SetKpi')
         try:
             # Here the code to create a sqlite query to crete a KPI and return a KpiID
-            kpi_id = monitoring_pb2.KpiId()
+            kpi_id = KpiId()
 
             kpi_description = request.kpi_description
             kpi_sample_type = request.kpi_sample_type
@@ -65,34 +81,55 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
                 kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
 
             kpi_id.kpi_id.uuid = str(data)
-
             # CREATEKPI_COUNTER_COMPLETED.inc()
             return kpi_id
         except ServiceException as e:
-            LOGGER.exception('CreateKpi exception')
+            LOGGER.exception('SetKpi exception')
             # CREATEKPI_COUNTER_FAILED.inc()
             grpc_context.abort(e.code, e.details)
         except Exception as e:  # pragma: no cover
-            LOGGER.exception('CreateKpi exception')
+            LOGGER.exception('SetKpi exception')
             # CREATEKPI_COUNTER_FAILED.inc()
             grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
 
+    def DeleteKpi ( self, request : KpiId, grpc_context : grpc.ServicerContext) -> Empty:
+
+        LOGGER.info('DeleteKpi')
+        try:
+             # TBC
+            return Empty()
+        except ServiceException as e:
+            LOGGER.exception('DeleteKpi exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('DeleteKpi exception')
+
+    def GetKpiDescriptorList ( self, request : Empty, grpc_context : grpc.ServicerContext) -> KpiDescriptorList:
+
+        LOGGER.info('GetKpiDescriptorList')
+        try:
+             # TBC
+            return KpiDescriptorList()
+        except ServiceException as e:
+            LOGGER.exception('GetKpiDescriptorList exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('GetKpiDescriptorList exception')
+
     # rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {}
-    def MonitorKpi(
-        self, request : monitoring_pb2.MonitorKpiRequest, grpc_context : grpc.ServicerContext
-    ) -> context_pb2.Empty:
+    def MonitorKpi ( self, request : MonitorKpiRequest, grpc_context : grpc.ServicerContext) -> Empty:
 
         LOGGER.info('MonitorKpi')
         try:
-            # Creates the request to send to the device service
-            monitor_device_request = device_pb2.MonitoringSettings()
+            # Sets the request to send to the device service
+            monitor_device_request = MonitoringSettings()
 
             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.sampling_duration_s = request.monitoring_window_s
+            monitor_device_request.sampling_interval_s = request.sampling_rate_s
 
             device_client = DeviceClient()
             device_client.MonitorDeviceKpi(monitor_device_request)
@@ -106,10 +143,10 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
             # CREATEKPI_COUNTER_FAILED.inc()
 
-        return context_pb2.Empty()
+        return Empty()
 
     # rpc IncludeKpi(IncludeKpiRequest)  returns(context.Empty)    {}
-    def IncludeKpi(self, request : monitoring_pb2.Kpi, grpc_context : grpc.ServicerContext) -> context_pb2.Empty:
+    def IncludeKpi(self, request : Kpi, grpc_context : grpc.ServicerContext) -> Empty:
 
         LOGGER.info('IncludeKpi')
 
@@ -117,18 +154,18 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context)
             if kpiDescriptor is None:
                 LOGGER.warning('Ignoring sample with KPIId({:s}): not found in database'.format(str(request.kpi_id)))
-                return context_pb2.Empty()
+                return Empty()
 
             kpiSampleType   = KpiSampleType.Name(kpiDescriptor.kpi_sample_type).upper().replace('KPISAMPLETYPE_', '')
             kpiId           = request.kpi_id.kpi_id.uuid
             deviceId        = kpiDescriptor.device_id.device_uuid.uuid
             endpointId      = kpiDescriptor.endpoint_id.endpoint_uuid.uuid
             serviceId       = kpiDescriptor.service_id.service_uuid.uuid
-            time_stamp      = request.timestamp
+            time_stamp      = request.timestamp.timestamp
             kpi_value       = getattr(request.kpi_value, request.kpi_value.WhichOneof('value'))
 
-            # Build the structure to be included as point in the influxDB
-            self.influx_db.write_KPI(time_stamp,kpiId,kpiSampleType,deviceId,endpointId,serviceId,kpi_value)
+            # Build the structure to be included as point in the MetricsDB
+            self.metrics_db.write_KPI(time_stamp,kpiId,kpiSampleType,deviceId,endpointId,serviceId,kpi_value)
 
             #self.influx_db.read_KPI_points()
 
@@ -139,23 +176,21 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
         except Exception:  # pragma: no cover
             LOGGER.exception('IncludeKpi exception')
             # CREATEKPI_COUNTER_FAILED.inc()
-        return context_pb2.Empty()
+        return Empty()
 
-    def GetStreamKpi ( self, request, grpc_context : grpc.ServicerContext):
-        # receives monitoring.KpiId returns stream monitoring.Kpi
-        LOGGER.info('GetStreamKpi')
-        yield monitoring_pb2.Kpi()
+    # def GetStreamKpi ( self, request, grpc_context : grpc.ServicerContext):
+    #
+    #     LOGGER.info('GetStreamKpi')
+    #     yield monitoring_pb2.Kpi()
+    #
+    # @MONITORING_GETINSTANTKPI_REQUEST_TIME.time()
+    # def GetInstantKpi ( self, request, grpc_context : grpc.ServicerContext):
+    #
+    #     LOGGER.info('GetInstantKpi')
+    #     return monitoring_pb2.Kpi()
 
-    @MONITORING_GETINSTANTKPI_REQUEST_TIME.time()
-    def GetInstantKpi ( self, request, grpc_context : grpc.ServicerContext):
-        # receives monitoring.KpiId returns monitoring.Kpi
-        LOGGER.info('GetInstantKpi')
-        return monitoring_pb2.Kpi()
 
-
-    def GetKpiDescriptor(
-        self, request : monitoring_pb2.KpiId, grpc_context : grpc.ServicerContext
-    ) -> monitoring_pb2.KpiDescriptor:
+    def GetKpiDescriptor(self, request : KpiId, grpc_context : grpc.ServicerContext) -> KpiDescriptor:
         LOGGER.info('getting Kpi by KpiID')
         try:
             kpi_db = self.sql_db.get_KPI(int(request.kpi_id.uuid))
@@ -163,7 +198,7 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             #LOGGER.info('kpi_db={:s}'.format(str(kpi_db)))
             if kpi_db is None: return None
 
-            kpiDescriptor = monitoring_pb2.KpiDescriptor()
+            kpiDescriptor = KpiDescriptor()
 
             kpiDescriptor.kpi_description                   = kpi_db[1]
             kpiDescriptor.kpi_sample_type                   = kpi_db[2]
@@ -178,3 +213,125 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
 
         except Exception:  # pragma: no cover
             LOGGER.exception('GetKpiDescriptor exception')
+
+    def QueryKpiData ( self, request : KpiQuery, grpc_context : grpc.ServicerContext) -> KpiList:
+
+        LOGGER.info('QueryKpiData')
+        try:
+             # TBC
+            return KpiQuery()
+        except ServiceException as e:
+            LOGGER.exception('QueryKpiData exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('QueryKpiData exception')
+
+    def SubscribeKpi ( self, request : SubsDescriptor, grpc_context : grpc.ServicerContext) -> KpiList:
+
+        LOGGER.info('SubscribeKpi')
+        try:
+             # TBC
+            yield KpiList()
+        except ServiceException as e:
+            LOGGER.exception('SubscribeKpi exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('SubscribeKpi exception')
+
+
+    def GetSubsDescriptor ( self, request : SubscriptionID, grpc_context : grpc.ServicerContext) -> SubsDescriptor:
+
+        LOGGER.info('GetSubsDescriptor')
+        try:
+             # TBC
+            return SubsDescriptor()
+        except ServiceException as e:
+            LOGGER.exception('GetSubsDescriptor exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('GetSubsDescriptor exception')
+
+    def GetSubscriptions ( self, request : Empty, grpc_context : grpc.ServicerContext) -> SubsIDList:
+
+        LOGGER.info('GetSubscriptions')
+        try:
+             # TBC
+            return SubsIDList()
+        except ServiceException as e:
+            LOGGER.exception('GetSubscriptions exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('GetSubscriptions exception')
+
+    def DeleteSubscription ( self, request : SubscriptionID, grpc_context : grpc.ServicerContext) -> Empty:
+
+        LOGGER.info('DeleteSubscription')
+        try:
+             # TBC
+            return Empty()
+        except ServiceException as e:
+            LOGGER.exception('DeleteSubscription exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('DeleteSubscription exception')
+
+    def SetKpiAlarm ( self, request : AlarmDescriptor, grpc_context : grpc.ServicerContext) -> AlarmResponse:
+
+        LOGGER.info('SetKpiAlarm')
+        try:
+             # TBC
+            return AlarmResponse()
+        except ServiceException as e:
+            LOGGER.exception('SetKpiAlarm exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('SetKpiAlarm exception')
+
+
+    def GetAlarms ( self, request : Empty, grpc_context : grpc.ServicerContext) -> AlarmIDList:
+
+        LOGGER.info('GetAlarms')
+        try:
+             # TBC
+            return AlarmIDList()
+        except ServiceException as e:
+            LOGGER.exception('GetAlarms exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('GetAlarms exception')
+
+    def GetAlarmDescriptor ( self, request : AlarmID, grpc_context : grpc.ServicerContext) -> AlarmDescriptor:
+
+        LOGGER.info('GetAlarmDescriptor')
+        try:
+             # TBC
+            return AlarmDescriptor()
+        except ServiceException as e:
+            LOGGER.exception('GetAlarmDescriptor exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('GetAlarmDescriptor exception')
+
+    def GetAlarmResponseStream(self, request : AlarmSubscription, grpc_context : grpc.ServicerContext) -> Iterator[AlarmResponse]:
+
+        LOGGER.info('GetAlarmResponseStream')
+        try:
+            # TBC
+            yield AlarmResponse()
+        except ServiceException as e:
+            LOGGER.exception('GetAlarmResponseStream exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('GetAlarmResponseStream exception')
+
+    def DeleteAlarm ( self, request : AlarmID, grpc_context : grpc.ServicerContext) -> Empty:
+
+        LOGGER.info('DeleteAlarm')
+        try:
+             # TBC
+            return Empty()
+        except ServiceException as e:
+            LOGGER.exception('DeleteAlarm exception')
+            grpc_context.abort(e.code, e.details)
+        except Exception as e:  # pragma: no cover
+            LOGGER.exception('DeleteAlarm exception')
diff --git a/src/monitoring/service/__main__.py b/src/monitoring/service/__main__.py
index e37412fa004704d089a8e00bada8033d8abe53bd..3334a860ccd94d51390ab5f5869d25e2475084ee 100644
--- a/src/monitoring/service/__main__.py
+++ b/src/monitoring/service/__main__.py
@@ -45,8 +45,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 = 86400
-                monitor_kpi_request.sampling_interval_s = 30
+                monitor_kpi_request.monitoring_window_s = 86400
+                monitor_kpi_request.sampling_rate_s = 30
                 events_collector._monitoring_client.MonitorKpi(monitor_kpi_request)
     else:
         # Terminate is set, looping terminates
diff --git a/src/monitoring/tests/Messages.py b/src/monitoring/tests/Messages.py
index 94fcc78c1a408f21e1b16316237560e329cb78b9..cf81ceed1e134240415ec1aabe8796cd4486f75f 100644
--- a/src/monitoring/tests/Messages.py
+++ b/src/monitoring/tests/Messages.py
@@ -11,14 +11,12 @@
 # WITHOUT 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 datetime
 
 from common.proto import monitoring_pb2
 from common.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.tools.timestamp.Converters import timestamp_string_to_float, timestamp_utcnow_to_float
 
-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()
@@ -34,16 +32,16 @@ def create_kpi_request():
     _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):
+def monitor_kpi_request(kpi_uuid, monitoring_window_s, sampling_rate_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
+    _monitor_kpi_request.monitoring_window_s = monitoring_window_s
+    _monitor_kpi_request.sampling_rate_s     = sampling_rate_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
+def include_kpi_request(kpi_id):
+    _include_kpi_request                        = monitoring_pb2.Kpi()
+    _include_kpi_request.kpi_id.kpi_id.uuid     = kpi_id.kpi_id.uuid
+    _include_kpi_request.timestamp.timestamp    = timestamp_utcnow_to_float()
+    _include_kpi_request.kpi_value.int32Val     = 500       # pylint: disable=maybe-no-member
     return _include_kpi_request
diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py
index ee7d6f51eb81bbe1c6a7b005f1e02108d14bc65e..b62b5f97f965beb75ddaafa122ac8f026faab686 100644
--- a/src/monitoring/tests/test_unitary.py
+++ b/src/monitoring/tests/test_unitary.py
@@ -12,38 +12,45 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import copy, logging, os, pytest
+import copy, os, pytest
+from time import sleep
 from typing import Tuple
 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.logger import getJSONLogger
 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.proto import monitoring_pb2
+from common.proto.monitoring_pb2 import KpiId, KpiDescriptor
 
 from context.client.ContextClient import ContextClient
 from context.service.grpc_server.ContextService import ContextService
-from common.proto.context_pb2 import EventTypeEnum, DeviceEvent, Device
+from common.proto.context_pb2 import EventTypeEnum, DeviceEvent, Device, Empty
 
 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
 
+os.environ['DEVICE_EMULATED_ONLY'] = 'TRUE'
+from device.service.drivers import DRIVERS  # pylint: disable=wrong-import-position
+
+# pylint: disable=wrong-import-position
 from monitoring.client.MonitoringClient import MonitoringClient
-from common.proto import context_pb2, monitoring_pb2
 from common.proto.kpi_sample_types_pb2 import KpiSampleType
-from monitoring.service import SqliteTools, InfluxTools
+from monitoring.service import SqliteTools, MetricsDBTools
 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.Messages import create_kpi_request, include_kpi_request, monitor_kpi_request
 from monitoring.tests.Objects import DEVICE_DEV1, DEVICE_DEV1_CONNECT_RULES, DEVICE_DEV1_UUID
 
+from monitoring.service.MonitoringServiceServicerImpl import LOGGER
 
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
+# LOGGER = getJSONLogger('monitoringservice-server')
+# LOGGER.setLevel('DEBUG')
 
 ###########################
 # Tests Setup
@@ -63,11 +70,11 @@ MONITORING_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.MONITORI
 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")
-INFLUXDB_USER = os.environ.get("INFLUXDB_USER")
-INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD")
-INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE")
+METRICSDB_HOSTNAME = os.environ.get("METRICSDB_HOSTNAME")
+METRICSDB_ILP_PORT = os.environ.get("METRICSDB_ILP_PORT")
+METRICSDB_REST_PORT = os.environ.get("METRICSDB_REST_PORT")
+METRICSDB_TABLE = os.environ.get("METRICSDB_TABLE")
+
 
 @pytest.fixture(scope='session')
 def context_db_mb() -> Tuple[Database, MessageBroker]:
@@ -149,10 +156,11 @@ def sql_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
+def metrics_db():
+    _metrics_db = MetricsDBTools.MetricsDB(
+        METRICSDB_HOSTNAME, METRICSDB_ILP_PORT, METRICSDB_REST_PORT, METRICSDB_TABLE)
+    return _metrics_db
+
 
 
 ###########################
@@ -160,12 +168,12 @@ def influx_db():
 ###########################
 
 # Test case that makes use of client fixture to test server's CreateKpi method
-def test_create_kpi(monitoring_client): # pylint: disable=redefined-outer-name
+def test_set_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.SetKpi(create_kpi_request())
     LOGGER.debug(str(response))
-    assert isinstance(response, monitoring_pb2.KpiId)
+    assert isinstance(response, KpiId)
 
 # Test case that makes use of client fixture to test server's MonitorKpi method
 def test_monitor_kpi(
@@ -174,7 +182,7 @@ def test_monitor_kpi(
         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')
+    LOGGER.info('test_monitor_kpi begin')
 
     context_database = context_db_mb[0]
 
@@ -196,42 +204,43 @@ def test_monitor_kpi(
     response = device_client.AddDevice(Device(**device_with_connect_rules))
     assert response.device_uuid.uuid == DEVICE_DEV1_UUID
 
-    response = monitoring_client.CreateKpi(create_kpi_request())
+    response = monitoring_client.SetKpi(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)
+    assert isinstance(response, Empty)
 
 
 # Test case that makes use of client fixture to test server's IncludeKpi method
 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())
-    LOGGER.debug(str(response))
-    assert isinstance(response, context_pb2.Empty)
+    kpi_id = monitoring_client.SetKpi(create_kpi_request())
+    response = monitoring_client.IncludeKpi(include_kpi_request(kpi_id))
+    assert isinstance(response, Empty)
 
 # Test case that makes use of client fixture to test server's GetStreamKpi method
 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(monitoring_pb2.Kpi())
     LOGGER.debug(str(response))
-    #assert isinstance(response, monitoring_pb2.Kpi)
+    #assert isinstance(response, Kpi)
 
 # Test case that makes use of client fixture to test server's GetInstantKpi method
-def test_get_instant_kpi(monitoring_client): # pylint: disable=redefined-outer-name
-    LOGGER.warning('test_getinstant_kpi begin')
-    response = monitoring_client.GetInstantKpi(kpi_id())
-    LOGGER.debug(str(response))
-    assert isinstance(response, monitoring_pb2.Kpi)
+# def test_get_instant_kpi(monitoring_client): # pylint: disable=redefined-outer-name
+#     LOGGER.warning('test_getinstant_kpi begin')
+#     response = monitoring_client.GetInstantKpi(kpi_id())
+#     LOGGER.debug(str(response))
+#     # assert isinstance(response, Kpi)
 
 # Test case that makes use of client fixture to test server's GetInstantKpi method
 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.SetKpi(create_kpi_request())
+    # LOGGER.debug(str(response))
     response = monitoring_client.GetKpiDescriptor(response)
-    LOGGER.debug(str(response))
-    assert isinstance(response, monitoring_pb2.KpiDescriptor)
+    # LOGGER.debug(str(response))
+    assert isinstance(response, KpiDescriptor)
 
 def test_sqlitedb_tools_insert_kpi(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_insert_kpi begin')
@@ -300,11 +309,13 @@ def test_sqlitedb_tools_delete_kpid_id(sql_db): # pylint: disable=redefined-oute
     assert response
 
 
-def test_influxdb_tools_write_kpi(influx_db): # pylint: disable=redefined-outer-name
-    LOGGER.warning('test_influxdb_tools_write_kpi begin')
+def test_metrics_db_tools_write_kpi(metrics_db): # pylint: disable=redefined-outer-name
+    LOGGER.warning('test_metric_sdb_tools_write_kpi begin')
+
+
+def test_metrics_db_tools_read_kpi_points(metrics_db): # pylint: disable=redefined-outer-name
+    LOGGER.warning('test_metrics_db_tools_read_kpi_points begin')
 
-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(
@@ -414,6 +425,9 @@ def test_listen_events(
     response = device_client.AddDevice(Device(**device_with_connect_rules))
     assert response.device_uuid.uuid == DEVICE_DEV1_UUID
 
+    sleep(0.1)
+
     kpi_id_list = events_collector.listen_events()
 
     assert len(kpi_id_list) > 0
+    events_collector.stop()
diff --git a/src/pathcomp/.gitignore b/src/pathcomp/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..48a680bf0f45eb556108c349bc45be896f4219aa
--- /dev/null
+++ b/src/pathcomp/.gitignore
@@ -0,0 +1 @@
+backend/wireshark
diff --git a/src/pathcomp/.gitlab-ci.yml b/src/pathcomp/.gitlab-ci.yml
index fd52da6fb7bf8dc556b92e4db080c9927bb58a5d..a45e735e4c07299c4853abdff5b6c39963a87a78 100644
--- a/src/pathcomp/.gitlab-ci.yml
+++ b/src/pathcomp/.gitlab-ci.yml
@@ -21,9 +21,14 @@ build pathcomp:
   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 .
-    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
-    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    # This first build tags the builder resulting image to prevent being removed by dangling image removal command
+    - docker build -t "${IMAGE_NAME}-backend:${IMAGE_TAG}-builder" --target builder -f ./src/$IMAGE_NAME/backend/Dockerfile .
+    - docker build -t "${IMAGE_NAME}-backend:$IMAGE_TAG" -f ./src/$IMAGE_NAME/backend/Dockerfile .
+    - docker build -t "${IMAGE_NAME}-frontend:$IMAGE_TAG" -f ./src/$IMAGE_NAME/frontend/Dockerfile .
+    - docker tag "${IMAGE_NAME}-backend:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG"
+    - docker tag "${IMAGE_NAME}-frontend:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG"
   after_script:
     - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
   rules:
@@ -32,14 +37,18 @@ build pathcomp:
     - changes:
       - src/common/**/*.py
       - proto/*.proto
-      - src/$IMAGE_NAME/**/*.{py,in,yml}
-      - src/$IMAGE_NAME/Dockerfile
-      - src/$IMAGE_NAME/tests/*.py
+      - src/$IMAGE_NAME/.gitlab-ci.yml
+      - src/$IMAGE_NAME/backend/**/*.{c,h,conf}
+      - src/$IMAGE_NAME/backend/Makefile
+      - src/$IMAGE_NAME/backend/Dockerfile
+      - src/$IMAGE_NAME/frontend/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/frontend/Dockerfile
+      - src/$IMAGE_NAME/frontend/tests/*.py
       - manifests/${IMAGE_NAME}service.yaml
       - .gitlab-ci.yml
 
 # Apply unit test to the component
-unit test pathcomp:
+unit test pathcomp-backend:
   variables:
     IMAGE_NAME: 'pathcomp' # name of the microservice
     IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
@@ -49,18 +58,22 @@ unit test pathcomp:
   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
+    - if docker container ls | grep ${IMAGE_NAME}-frontend; then docker rm -f ${IMAGE_NAME}-frontend; else echo "${IMAGE_NAME}-frontend image is not in the system"; fi
+    - if docker container ls | grep ${IMAGE_NAME}-backend; then docker rm -f ${IMAGE_NAME}-backend; else echo "${IMAGE_NAME}-backend image is not in the system"; fi
   script:
-    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
-    - docker run --name $IMAGE_NAME -d -p 10020:10020 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG
+    - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG"
+    #- docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 -v "$PWD/src/${IMAGE_NAME}/backend/tests:/opt/results" --network=teraflowbridge ${IMAGE_NAME}-backend:${IMAGE_TAG}-builder
+    - docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 --network=teraflowbridge ${IMAGE_NAME}-backend:${IMAGE_TAG}-builder
     - 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 report --include='${IMAGE_NAME}/*' --show-missing"
+    - docker logs ${IMAGE_NAME}-backend
+    - docker exec -i ${IMAGE_NAME}-backend bash -c "curl -0 -v -X POST -H 'Expect:' -H 'Content-Type:\ application/json' http://127.0.0.1:8081/pathComp/api/v1/compRoute -d @/var/teraflow/tests/pc-req.json"
+    - docker kill --signal=SIGUSR1 pathcomp-backend
+    - docker exec -i ${IMAGE_NAME}-backend bash -c "gcovr"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
-    - docker rm -f $IMAGE_NAME
+    - docker logs ${IMAGE_NAME}-backend
+    - docker rm -f ${IMAGE_NAME}-backend
     - 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)'
@@ -68,16 +81,71 @@ unit test pathcomp:
     - changes:
       - src/common/**/*.py
       - proto/*.proto
-      - src/$IMAGE_NAME/**/*.{py,in,yml}
-      - src/$IMAGE_NAME/Dockerfile
-      - src/$IMAGE_NAME/tests/*.py
-      - src/$IMAGE_NAME/tests/Dockerfile
+      - src/$IMAGE_NAME/.gitlab-ci.yml
+      - src/$IMAGE_NAME/backend/**/*.{c,h,conf}
+      - src/$IMAGE_NAME/backend/Makefile
+      - src/$IMAGE_NAME/backend/Dockerfile
+      - manifests/${IMAGE_NAME}service.yaml
+      - .gitlab-ci.yml
+  #artifacts:
+  #    when: always
+  #    reports:
+  #      junit: src/$IMAGE_NAME/backend/tests/${IMAGE_NAME}-backend_report.xml
+
+# Apply unit test to the component
+unit test pathcomp-frontend:
+  variables:
+    IMAGE_NAME: 'pathcomp' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: unit_test
+  needs:
+    - build pathcomp
+  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 --driver=bridge --subnet=172.28.0.0/24 --gateway=172.28.0.254 teraflowbridge; fi
+    - if docker container ls | grep ${IMAGE_NAME}-frontend; then docker rm -f ${IMAGE_NAME}-frontend; else echo "${IMAGE_NAME}-frontend image is not in the system"; fi
+    - if docker container ls | grep ${IMAGE_NAME}-backend; then docker rm -f ${IMAGE_NAME}-backend; else echo "${IMAGE_NAME}-backend image is not in the system"; fi
+  script:
+    - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG"
+    - docker pull "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG"
+    - docker run --name ${IMAGE_NAME}-backend -d -p 8081:8081 -v "$PWD/src/${IMAGE_NAME}/backend/tests:/opt/results" --network=teraflowbridge --ip 172.28.0.1 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG
+    - sleep 1
+    - docker run --name ${IMAGE_NAME}-frontend -d -p 10020:10020 --env "PATHCOMP_BACKEND_HOST=172.28.0.1" --env "PATHCOMP_BACKEND_PORT=8081" -v "$PWD/src/${IMAGE_NAME}/frontend/tests:/opt/results" --network=teraflowbridge --ip 172.28.0.2 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$IMAGE_TAG
+    - docker exec -i ${IMAGE_NAME}-frontend bash -c "env"
+    - docker exec -i ${IMAGE_NAME}-backend bash -c "env"
+    - sleep 5
+    - docker ps -a
+    - docker logs ${IMAGE_NAME}-frontend
+    - docker logs ${IMAGE_NAME}-backend
+    - docker exec -i ${IMAGE_NAME}-frontend bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/frontend/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}-frontend_report.xml"
+    - docker exec -i ${IMAGE_NAME}-frontend bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
+  coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  after_script:
+    - docker ps -a
+    - docker logs ${IMAGE_NAME}-frontend
+    - docker logs ${IMAGE_NAME}-backend
+    - docker rm -f ${IMAGE_NAME}-frontend
+    - docker rm -f ${IMAGE_NAME}-backend
+    - 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/common/**/*.py
+      - proto/*.proto
+      - src/$IMAGE_NAME/.gitlab-ci.yml
+      - src/$IMAGE_NAME/frontend/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/frontend/Dockerfile
+      - src/$IMAGE_NAME/frontend/tests/*.py
+      - src/$IMAGE_NAME/backend/**/*.{c,h,conf}
+      - src/$IMAGE_NAME/backend/Makefile
+      - src/$IMAGE_NAME/backend/Dockerfile
       - manifests/${IMAGE_NAME}service.yaml
       - .gitlab-ci.yml
   artifacts:
       when: always
       reports:
-        junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
+        junit: src/$IMAGE_NAME/frontend/tests/${IMAGE_NAME}-frontend_report.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy pathcomp:
@@ -86,7 +154,8 @@ deploy pathcomp:
     IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
   stage: deploy
   needs:
-    - unit test pathcomp
+    - unit test pathcomp-backend
+    - unit test pathcomp-frontend
     # - integ_test execute
   script:
     - 'sed -i "s/$IMAGE_NAME:.*/$IMAGE_NAME:$IMAGE_TAG/" manifests/${IMAGE_NAME}service.yaml'
diff --git a/src/pathcomp/backend/Dockerfile b/src/pathcomp/backend/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..b351d4715d99ee8a9b518a0cfc827c17cf2bba49
--- /dev/null
+++ b/src/pathcomp/backend/Dockerfile
@@ -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.
+
+# Multi-stage Docker image build
+
+# Stage 1
+FROM ubuntu:20.04 AS builder
+ARG DEBIAN_FRONTEND=noninteractive
+
+# Install build software
+RUN apt-get update -y && apt-get install build-essential curl gcovr libglib2.0-dev -y
+RUN apt-get install valgrind -y
+
+# mkdir
+RUN mkdir -p /var/teraflow
+
+# Define working directory
+WORKDIR /var/teraflow
+
+# Copy every file in working directory
+COPY src/pathcomp/backend/. ./
+
+# Build release version and move it to bin folder
+RUN make release
+RUN mkdir /var/teraflow/bin
+RUN mv pathComp /var/teraflow/bin
+
+# Build code coverage version
+RUN make clean
+RUN make coverage
+#RUN make debug
+
+EXPOSE 8081
+
+# builder defines coverage version of pathcomp by default
+# coverage entrypoint:
+ENTRYPOINT [ "./pathComp-cvr", "config/pathcomp.conf", "screen_only" ]
+# debug entrypoint:
+#ENTRYPOINT [ "./pathComp-dbg", "config/pathcomp.conf", "screen_only" ]
+# debug entrypoint with memory tracking:
+#ENTRYPOINT [ "valgrind", "--leak-check=full", "--show-leak-kinds=all", "--track-origins=yes", "--show-error-list=yes", "./pathComp-dbg", "config/pathcomp.conf", "screen_only" ]
+
+
+# Stage 2
+FROM ubuntu:20.04 AS release
+ARG DEBIAN_FRONTEND=noninteractive
+
+# Install build software
+RUN apt-get update -y && apt-get install curl libglib2.0-bin -y
+
+# mkdir
+RUN mkdir -p /var/teraflow/config
+
+# Define working directory
+WORKDIR /var/teraflow
+
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --from=builder /var/teraflow/bin/pathComp .
+COPY --from=builder /var/teraflow/config/pathcomp.conf ./config
+COPY --from=builder /var/teraflow/tests/. ./tests
+
+# release entrypoint:
+ENTRYPOINT [ "./pathComp", "config/pathcomp.conf", "screen_only" ]
diff --git a/src/pathcomp/backend/Dockerfile-gdb b/src/pathcomp/backend/Dockerfile-gdb
new file mode 100644
index 0000000000000000000000000000000000000000..dcf2dbd2fefb22618677b746d1a6cc82a5412e13
--- /dev/null
+++ b/src/pathcomp/backend/Dockerfile-gdb
@@ -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.
+
+# Multi-stage Docker image build
+
+# Stage 1
+FROM ubuntu:20.04 AS builder
+ARG DEBIAN_FRONTEND=noninteractive
+
+# Install build software
+RUN apt-get update -y && apt-get install build-essential libglib2.0-dev -y
+RUN apt-get install gdb gdbserver -y
+
+# mkdir
+RUN mkdir -p /var/teraflow
+
+# Define working directory
+WORKDIR /var/teraflow
+
+# Copy every file in working directory
+COPY src/pathcomp/backend/. ./
+RUN make
+
+EXPOSE 8081
+
+ENTRYPOINT [ "gdb", "--args", "./pathComp", "config/pathcomp.conf", "screen_only" ] 
diff --git a/src/pathcomp/backend/Makefile b/src/pathcomp/backend/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f4fc1996bb32e87515bb6a1145213cd4e74a4f3b
--- /dev/null
+++ b/src/pathcomp/backend/Makefile
@@ -0,0 +1,70 @@
+#
+# 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+
+CC       = gcc
+CFLAGS   = -I. -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/
+LDLIBS   = -lm
+LDFLAGS  = 
+
+all: pathComp
+
+release: CFLAGS += -O6 -Wall -DPOSIX_SOURCE
+release: pathComp
+
+debug: CFLAGS  += -O0 -ggdb -g -DDEBUG
+debug: LDFLAGS += -g
+debug: pathComp-dbg
+
+coverage: CFLAGS  += -O0 -ggdb -g -DDEBUG -fprofile-arcs -ftest-coverage -DGCOV
+coverage: LDFLAGS += -g -lgcov --coverage -fprofile-arcs -ftest-coverage -DGCOV
+coverage: pathComp-cvr
+
+pathComp: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o 
+	gcc -o pathComp pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o \
+		-L/usr/lib/x86_64-linux-gnu/ -lglib-2.0 -luuid $(LDFLAGS) $(LDLIBS)
+
+pathComp-dbg: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o 
+	gcc -o pathComp-dbg pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o \
+		-L/usr/lib/x86_64-linux-gnu/ -lglib-2.0 -luuid $(LDFLAGS) $(LDLIBS)
+
+pathComp-cvr: pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o 
+	gcc -o pathComp-cvr pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.o pathComp_sp.o pathComp_RESTapi.o \
+		-L/usr/lib/x86_64-linux-gnu/ -lglib-2.0 -luuid $(LDFLAGS) $(LDLIBS)
+
+pathComp_log.o: pathComp_log.h pathComp_log.c
+	$(CC) $(CFLAGS) -c pathComp_log.c -o pathComp_log.o  
+
+pathComp_cjson.o: pathComp_log.h pathComp_cjson.h pathComp_cjson.c
+	$(CC) $(CFLAGS) -c pathComp_cjson.c -o pathComp_cjson.o  
+	
+pathComp_tools.o: pathComp_log.h pathComp_tools.h pathComp_tools.c
+	$(CC) $(CFLAGS) -c pathComp_tools.c -o pathComp_tools.o  
+	
+pathComp_ksp.o: pathComp_log.h pathComp_tools.h pathComp_ksp.h pathComp_ksp.c
+	$(CC) $(CFLAGS) -c pathComp_ksp.c -o pathComp_ksp.o
+
+pathComp_sp.o: pathComp_log.h pathComp_tools.h pathComp_sp.h pathComp_sp.c
+	$(CC) $(CFLAGS) -c pathComp_sp.c -o pathComp_sp.o
+	
+pathComp_RESTapi.o: pathComp_tools.h pathComp_log.h pathComp_cjson.h pathComp_ksp.h pathComp_sp.h pathComp_RESTapi.h pathComp_RESTapi.c
+	$(CC) $(CFLAGS) -c pathComp_RESTapi.c -o pathComp_RESTapi.o
+
+pathComp.o: pathComp_log.h pathComp_RESTapi.h pathComp.c pathComp.h
+	$(CC) $(CFLAGS) -c pathComp.c -o pathComp.o 
+
+clean:	
+	rm -f *.o *.gcno *.gcda *.gcov *.log pathComp pathComp-dbg pathComp-cvr
diff --git a/src/pathcomp/backend/config/pathcomp.conf b/src/pathcomp/backend/config/pathcomp.conf
new file mode 100644
index 0000000000000000000000000000000000000000..cd4e677e97fd7c70b74e687fa13e776d47b4d8fb
--- /dev/null
+++ b/src/pathcomp/backend/config/pathcomp.conf
@@ -0,0 +1,2 @@
+PATHCOMP_IP_ADDR 0.0.0.0
+RESTAPI 1
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp.c b/src/pathcomp/backend/pathComp.c
new file mode 100644
index 0000000000000000000000000000000000000000..2a719c92481557424925b09e940dcf73ba09595c
--- /dev/null
+++ b/src/pathcomp/backend/pathComp.c
@@ -0,0 +1,191 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h> 
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+
+#ifdef GCOV
+// Instrumentation to report code coverage live
+// Ref: https://www.osadl.org/fileadmin/dam/interface/docbook/howtos/coverage.pdf
+#include <signal.h>
+
+// Code coverage flush method; used to update code coverage reports while the server is running
+void __gcov_flush(void); /* check in gcc sources gcc/gcov-io.h for the prototype */
+
+void my_gcov_handler(int signum)
+{
+  printf("signal received: running __gcov_flush()\n");
+  __gcov_flush(); /* dump coverage data on receiving SIGUSR1 */
+}
+#endif
+
+#include "pathComp_log.h"
+#include "pathComp_RESTapi.h"
+#include "pathComp.h"
+
+// External Variables
+FILE *logfile = NULL;
+
+// PATH COMP IP address API Client
+struct in_addr pathComp_IpAddr;
+
+// REST API ENABLED
+int RESTAPI_ENABLED = 0;
+
+GMainLoop * loop = NULL;
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp.c
+ * 	@brief Read the pathComp.conf file @ /etc/pathComp/
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void read_pathComp_config_file(FILE *fp)
+{
+    DEBUG_PC ("Processing pathComp.conf");
+    
+    char buff[128], ip[128];   
+    
+    // READ PATH COMP SERVER IP
+    memset (&pathComp_IpAddr, (int)0, sizeof (struct in_addr));
+    fscanf(fp, "%s %s ", buff, ip);
+	pathComp_IpAddr.s_addr = inet_addr(ip);
+    DEBUG_PC("pathComp_IpAddr: %s", inet_ntoa (pathComp_IpAddr));
+    memset (buff, 0, sizeof (buff));
+        
+    // Read REST API 
+    fscanf (fp, "%s %d ", buff, &RESTAPI_ENABLED);
+    if (RESTAPI_ENABLED) DEBUG_PC ("REST API: ON");
+    if (RESTAPI_ENABLED == 0) DEBUG_PC ("REST API: OFF");	
+
+    memset (buff, 0, sizeof (buff));
+    DEBUG_PC ("CommandLine: %s", buff);
+  
+    return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp.c
+ * 	@brief Main function for pathComp server
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+int main(int argc, char *argv[])
+{
+	#ifdef GCOV
+	struct sigaction new_action, old_action;
+	/* setup signal hander */
+ 	new_action.sa_handler = my_gcov_handler;
+ 	sigemptyset(&new_action.sa_mask);
+ 	new_action.sa_flags = 0;
+ 	sigaction(SIGUSR1, NULL, &old_action);
+ 	if (old_action.sa_handler != SIG_IGN)
+ 		sigaction (SIGUSR1, &new_action, NULL);
+	#endif
+
+	DEBUG_PC ("********************************************************************"); 
+	DEBUG_PC ("********************************************************************");
+	DEBUG_PC (" ---------------------- Path Computation Server---------------------");
+	DEBUG_PC ("********************************************************************");
+	DEBUG_PC ("********************************************************************"); 
+
+	// processing input parameters
+	if (argc == 1)
+	{
+		DEBUG_PC ("Arguments are missing ...");
+		exit (-1);		
+	}
+	
+	// argv[1] specifies the folder and the configuration file
+	gchar configFile[50];
+	strcpy (configFile, argv[1]);
+	DEBUG_PC ("Path Computation Server Config File is: %s", configFile);  
+	
+	// argv[2] specifies the folder and the log file
+	gchar log[50];
+	strcpy (log, argv[2]);
+	gint screen = strcmp(log, "screen_only");
+	if (screen == 0) {
+		DEBUG_PC("All logs shown through stdout, i.e.,screen");
+		logfile = NULL;
+	}
+	else {
+		DEBUG_PC("PATH COMP log File: %s", log);
+		// open the log file	
+		logfile = fopen(log, "w");
+		DEBUG_PC("log file is opened");
+	}
+	
+	// Read the pathComp.conf file
+	FILE *pathComp_config = NULL;	
+	pathComp_config = fopen (configFile, "r");
+	if (pathComp_config == NULL)
+	{	
+		DEBUG_PC ("File error\n");
+		exit (-1);
+	}	
+	DEBUG_PC ("pathComp_config.conf is opened");
+	
+	// Check if flag -d for daemonize 
+	if (argc > 3)
+	{
+		gchar options[10];
+		strcpy (options, argv[3]);
+		gint ret = strcmp (options, "-d");
+		if (ret == 0) daemon(0,0);
+	}	
+	
+	// Process the config file
+	read_pathComp_config_file (pathComp_config);
+
+	DEBUG_PC ("\n ---- PATH COMP MAIN LOOP ------");
+	/** Creates a new GMainLoop structure */
+	loop = g_main_loop_new (NULL, FALSE);
+      
+	// Iff RESTAPI_ENABLED is ON
+	if (RESTAPI_ENABLED)
+	{
+		RESTapi_init(PATH_COMP_PORT);
+	}     
+      
+	/** execute loop */
+	g_main_loop_run (loop);
+
+	/** decrease the one reference of loop when it is finished */
+	g_main_loop_unref(loop);
+	loop = NULL;
+    return 0;
+}
diff --git a/src/pathcomp/backend/pathComp.h b/src/pathcomp/backend/pathComp.h
new file mode 100644
index 0000000000000000000000000000000000000000..76b97fd606854f8aee5ecd4536ca9f2da906f9aa
--- /dev/null
+++ b/src/pathcomp/backend/pathComp.h
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+
+#ifndef _PATHCOMP_H
+#define _PATHCOMP_H
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+
+///////////////////////////////////////////////////
+// IP addressing of peer functional entities
+///////////////////////////////////////////////////
+extern struct in_addr pathComp_IpAddr;
+
+// TCP Port for the REST API communication with the PATH COMP process
+#define PATH_COMP_PORT 		8081       
+
+// External Variables
+extern GMainLoop * loop;
+
+#endif
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp_RESTapi.c b/src/pathcomp/backend/pathComp_RESTapi.c
new file mode 100644
index 0000000000000000000000000000000000000000..709d3dc004027e7eb4e847f73ae1bae25653316e
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_RESTapi.c
@@ -0,0 +1,2001 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h> 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <strings.h>
+#include <time.h>
+#include <fcntl.h>
+#include <uuid/uuid.h>
+#include <string.h>
+
+#include "pathComp_log.h"
+#include "pathComp_tools.h"
+#include "pathComp_cjson.h"
+#include "pathComp_ksp.h"
+#include "pathComp_sp.h"
+#include "pathComp_RESTapi.h"
+
+#define ISspace(x) isspace((int)(x))
+
+#define SERVER_STRING "Server: PATHCOMP/0.1.0\r\n"
+
+// List of Clients connected to the PATH COMP
+GList *RESTapi_tcp_client_list = NULL;
+
+// Id for CLient HTTP (REST API) Connection
+guint CLIENT_ID = 0;
+guint32 paId_req = 0;
+
+// Global variables
+struct linkList_t* linkList;
+struct deviceList_t* deviceList;
+struct serviceList_t* serviceList;
+
+gchar algId[MAX_ALG_ID_LENGTH];
+gboolean syncPath = FALSE;
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Seek a connected tcp client by its fd in the RESTapi_tcp_client_list
+ * 	
+ * 	@param data
+ *  @param userdata
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint find_rl_client_by_fd (gconstpointer data, gconstpointer userdata)
+{
+	 /** check values */
+     g_assert(data != NULL);
+     g_assert(userdata != NULL);
+	 
+	 struct pathComp_client *client = (struct pathComp_client*)data;
+     gint fd = *(gint *)userdata; 
+     
+    if (client->fd == fd)	
+		return 0;        
+    return -1;	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to send a message to the corresponding channel
+ * 	
+ * 	@param source
+ *  @param buf
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint rapi_send_message (GIOChannel *channel, char *buf)	{
+	gsize nbytes, buffersize;
+
+	//DEBUG_PC ("Msg prepared to be sent REST API RESPONSE ");
+    gint len = strlen ((const char*) buf);
+    //DEBUG_PC ("Targeted Length of the buffer: %d", len);       
+
+    buffersize = g_io_channel_get_buffer_size (channel);
+    //DEBUG_PC ("GIOChannel with Buffer Size: %d", (gint)buffersize);
+    
+    gsize newBufferSize = MAX_GIO_CHANNEL_BUFFER_SIZE;
+    g_io_channel_set_buffer_size (channel, newBufferSize);
+    
+    buffersize = g_io_channel_get_buffer_size (channel);
+    //DEBUG_PC ("GIOChannel with Buffer Size: %d", (gint)buffersize);
+    
+	/** Send message.  */
+    GError *error = NULL;
+    
+    char *ptr = buf;
+    gint nleft = strlen ((const char *)buf);
+    
+    while (nleft > 0) {
+        g_io_channel_write_chars (channel, (void *)ptr, nleft, &nbytes, &error);
+        if (error) {
+            DEBUG_PC ("Error sending the message to TCP Client");
+            return (-1);
+        }
+        
+        //DEBUG_PC ("Sent %d bytes", (gint)nbytes);        
+        nleft = nleft - nbytes;
+        //DEBUG_PC ("Remaining to be sent %d", nleft);
+        ptr += nbytes;        
+    } 
+	DEBUG_PC("RESPONSE MSG SENT");
+	return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to return when something goes wrong when processing the REST API Command
+ * 	
+ * 	@param source
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void RESTapi_unimplemented (GIOChannel *source)
+{
+	gint ret = 0;
+	guchar buftmp[1024];
+	char *buf = g_malloc0 (sizeof (char) * 2048000); 
+	sprintf((char *)buf, "HTTP/1.1 400 Bad request\r\n");
+
+	sprintf((char *)buftmp, SERVER_STRING);
+	strcat ((char *)buf, (const char *)buftmp);
+
+	sprintf((char *)buftmp, "Content-Type: text/plain\r\n");
+	strcat ((char *)buf, (const char *)buftmp);
+
+	sprintf((char *)buftmp, "\r\n");
+	strcat ((char *)buf, (const char *)buftmp);
+	      
+	sprintf((char *)buftmp, "<HTML><HEAD><TITLE>Method Not Implemented\r\n");
+	strcat ((char *)buf, (const char *)buftmp);
+
+	sprintf((char *)buftmp, "</TITLE></HEAD>\r\n");
+	strcat ((char *)buf, (const char *)buftmp);
+
+	sprintf((char *)buftmp, "<BODY><P>HTTP request method not supported.\r\n");
+	strcat ((char *)buf, (const char *)buftmp);	
+
+	sprintf((char *)buftmp, "</BODY></HTML>\r\n");
+	strcat ((char *)buf, (const char *)buftmp);
+
+	ret = rapi_send_message (source, buf);
+	g_free (buf);
+	(void)ret;
+
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to put in the buffer the date according to RFC 1123
+ * 	
+ * 	@param date
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void rapi_add_date_header (char *date)
+{
+    static const char *DAYS[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+    static const char *MONTHS[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+    time_t t = time(NULL);
+    struct tm *tm = NULL;
+    struct tm sys;
+    gmtime_r(&t, &sys);
+    tm = &sys;
+
+    sprintf((char *)date, "DATE: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", DAYS[tm->tm_wday], tm->tm_mday, 
+								      MONTHS[tm->tm_mon], 1900 + tm->tm_year, 
+								      tm->tm_hour, tm->tm_min, tm->tm_sec);
+    
+    return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to add DeviceId and EndpointId forming the computed path
+ *
+ * 	@param pathObj
+ *  @param p
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void add_comp_path_deviceId_endpointId_json(cJSON* pathObj, struct path_t* p, struct compRouteOutput_t* oElem) {
+	g_assert(p);
+	g_assert(pathObj);
+
+	// add array for the devideId and endpointIds
+	cJSON* devicesArray = cJSON_CreateArray();
+	cJSON_AddItemToObject(pathObj, "devices", devicesArray);
+
+	// Add the source endpoint
+	cJSON* sEndPointIdObj;
+	cJSON_AddItemToArray(devicesArray, sEndPointIdObj = cJSON_CreateObject());
+	// Add the topology Id Object containing the topology uuid and context uuid
+	cJSON* stopIdObj;
+	cJSON_AddItemToObject(sEndPointIdObj, "topology_id", stopIdObj = cJSON_CreateObject());
+	cJSON_AddItemToObject(stopIdObj, "contextId", cJSON_CreateString(oElem->service_endpoints_id[0].topology_id.contextId));
+	cJSON_AddItemToObject(stopIdObj, "topology_uuid", cJSON_CreateString(oElem->service_endpoints_id[0].topology_id.topology_uuid));
+
+	// Add the device Id (uuid) 
+	cJSON_AddItemToObject(sEndPointIdObj, "device_id", cJSON_CreateString(oElem->service_endpoints_id[0].device_uuid));
+	// Add the endpoint Id (uuid)
+	cJSON_AddItemToObject(sEndPointIdObj, "endpoint_uuid", cJSON_CreateString(oElem->service_endpoints_id[0].endpoint_uuid));
+
+
+	for (gint i = 0; i < p->numPathLinks; i++) {
+		struct pathLink_t* pL = &(p->pathLinks[i]);
+		cJSON* dElemObj; // Device Element Object of the array
+		cJSON_AddItemToArray(devicesArray, dElemObj = cJSON_CreateObject());
+
+		// Add the topologyId with the topologyuuid and contextId
+		cJSON* tIdObj;
+		cJSON_AddItemToObject(dElemObj, "topology_id", tIdObj = cJSON_CreateObject());
+		cJSON_AddItemToObject(tIdObj, "contextId", cJSON_CreateString(pL->topologyId.contextId));
+		cJSON_AddItemToObject(tIdObj, "topology_uuid", cJSON_CreateString(pL->topologyId.topology_uuid));
+
+		// Add Device Id
+		cJSON_AddItemToObject(dElemObj, "device_id", cJSON_CreateString(pL->aDeviceId));
+
+		// Add endpoint Id
+		cJSON_AddItemToObject(dElemObj, "endpoint_uuid", cJSON_CreateString(pL->aEndPointId));  
+	}
+	
+	// Add the sink	endpoint
+	cJSON* sinkEndPointIdObj;
+	cJSON_AddItemToArray(devicesArray, sinkEndPointIdObj = cJSON_CreateObject());
+	// Add the topology Id Object containing the topology uuid and context uuid
+	cJSON* sinkTopIdObj;
+	cJSON_AddItemToObject(sinkEndPointIdObj, "topology_id", sinkTopIdObj = cJSON_CreateObject());
+	cJSON_AddItemToObject(sinkTopIdObj, "contextId", cJSON_CreateString(oElem->service_endpoints_id[1].topology_id.contextId));
+	cJSON_AddItemToObject(sinkTopIdObj, "topology_uuid", cJSON_CreateString(oElem->service_endpoints_id[1].topology_id.topology_uuid));
+
+	// Add the device Id (uuid) 
+	cJSON_AddItemToObject(sinkEndPointIdObj, "device_id", cJSON_CreateString(oElem->service_endpoints_id[1].device_uuid));
+	// Add the endpoint Id (uuid)
+	cJSON_AddItemToObject(sinkEndPointIdObj, "endpoint_uuid", cJSON_CreateString(oElem->service_endpoints_id[1].endpoint_uuid));
+	
+	return;				 
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to add the links forming the computed path
+ *
+ * 	@param pathObj
+ *  @param p
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void add_comp_path_link_json(cJSON* pathObj, struct path_t* p) {
+	g_assert(p);
+	g_assert(pathObj);
+
+	// Add array for the links
+	cJSON* linkArray = cJSON_CreateArray();
+	cJSON_AddItemToObject(pathObj, "link", linkArray);
+
+	for (gint i = 0; i < p->numPathLinks; i++) {
+		struct pathLink_t* pL = &(p->pathLinks[i]);
+		cJSON* lElemObj; // Link Element Object of the array
+		cJSON_AddItemToArray(linkArray, lElemObj = cJSON_CreateObject());
+
+		// Add link Id
+		cJSON_AddItemToObject(lElemObj, "link_Id", cJSON_CreateString(pL->linkId));
+
+		// Add link topologies
+		cJSON* linkTopoArray = cJSON_CreateArray();
+		cJSON_AddItemToObject(lElemObj, "topology", linkTopoArray);
+
+		for (gint j = 0; j < pL->numLinkTopologies; j++) {
+			struct linkTopology_t* linkTopo = &(pL->linkTopologies[j]);
+			cJSON* lTopoElemObj;
+			cJSON_AddItemToArray(linkTopoArray, lTopoElemObj = cJSON_CreateObject());
+			cJSON_AddItemToObject(lTopoElemObj, "topology_uuid", cJSON_CreateString(linkTopo->topologyId));
+		}
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Compose the JSON Body of the succesfully network connectivity service
+ * 	
+ * 	@param body
+ *  @param length
+ *  @param compRouteOutputList
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void rapi_response_json_contents (char *body, gint *length, struct compRouteOutputList_t *compRouteOutputList)
+{
+    char *buftmp;    
+    cJSON *root = cJSON_CreateObject();     
+	DEBUG_PC ("Creating the JSON body of the response"); 
+
+	// Create response-list array
+	cJSON *responseListArray = cJSON_CreateArray();
+	cJSON_AddItemToObject(root, "response-list", responseListArray);
+	
+	// Add computed routes to the response-list
+	for (gint i = 0; i < compRouteOutputList->numCompRouteConnList; i++) {
+		struct compRouteOutput_t *oElem = &(compRouteOutputList->compRouteConnection[i]); // reference to output element from the list of computed routes
+		cJSON *oElemObj;
+		cJSON_AddItemToArray (responseListArray, oElemObj = cJSON_CreateObject());
+		
+		// Add the service Id Object
+		cJSON* servIdObj;
+		cJSON_AddItemToObject(oElemObj, "serviceId", servIdObj = cJSON_CreateObject());
+		cJSON_AddItemToObject(servIdObj, "contextId", cJSON_CreateString(oElem->serviceId.contextId));
+		cJSON_AddItemToObject(servIdObj, "service_uuid", cJSON_CreateString(oElem->serviceId.service_uuid));
+
+		// Add the service endpoints ids array
+		cJSON* sEndpointIdsArray = cJSON_CreateArray();
+		cJSON_AddItemToObject(oElemObj, "service_endpoints_ids", sEndpointIdsArray);
+
+		for (gint j = 0; j < oElem->num_service_endpoints_id; j++) {
+			//DEBUG_PC("parsing service endpoints ids");
+			//DEBUG_PC("endpoint: %s [%s]", oElem->service_endpoints_id[j].device_uuid, oElem->service_endpoints_id[j].endpoint_uuid);
+			//struct service_endpoints_id_t* sEndPointId = &(oElem->service_endpoints_id[j]);
+			cJSON* sEndPointIdObj;
+			cJSON_AddItemToArray(sEndpointIdsArray, sEndPointIdObj = cJSON_CreateObject());
+			// Add the topology Id Object containing the topology uuid and context uuid
+			cJSON* topIdObj;
+			cJSON_AddItemToObject(sEndPointIdObj, "topology_id", topIdObj = cJSON_CreateObject());
+			cJSON_AddItemToObject(topIdObj, "contextId", cJSON_CreateString(oElem->service_endpoints_id[j].topology_id.contextId));
+			cJSON_AddItemToObject(topIdObj, "topology_uuid", cJSON_CreateString(oElem->service_endpoints_id[j].topology_id.topology_uuid));
+
+			// Add the device Id (uuid) 
+			cJSON_AddItemToObject(sEndPointIdObj, "device_id", cJSON_CreateString(oElem->service_endpoints_id[j].device_uuid));
+			// Add the endpoint Id (uuid)
+			cJSON_AddItemToObject(sEndPointIdObj, "endpoint_uuid", cJSON_CreateString(oElem->service_endpoints_id[j].endpoint_uuid));
+		}
+		// Add no path issue
+		if (oElem->noPathIssue == NO_PATH_CONS_ISSUE) { // Error on finding the route, e.g., no feasible path
+			DEBUG_PC("NO PATH FOUND, AN ISSUE OCCURRED: %d", oElem->noPathIssue);
+			cJSON* noPathObj;
+			cJSON_AddItemToObject(oElemObj, "noPath", noPathObj = cJSON_CreateObject());
+			char str[5];
+			sprintf(str, "%d", oElem->noPathIssue);
+			cJSON_AddItemToObject(noPathObj, "issue", cJSON_CreateString(str));
+			continue;
+		}
+		
+		// Create the array to parse the computed path from the oElemObj
+		cJSON* pathArray = cJSON_CreateArray();
+		cJSON_AddItemToObject(oElemObj, "path", pathArray);
+		for (gint k = 0; k < oElem->numPaths; k++) {
+			struct path_t* p = &(oElem->paths[k]);
+			cJSON* pathObj;
+			cJSON_AddItemToArray(pathArray, pathObj = cJSON_CreateObject());
+
+			// Add path capacity
+			cJSON* pathCapObj;
+			cJSON_AddItemToObject(pathObj, "path-capacity", pathCapObj = cJSON_CreateObject());
+			cJSON* totalSizeObj;
+			cJSON_AddItemToObject(pathCapObj, "total-size", totalSizeObj = cJSON_CreateObject());
+			cJSON_AddItemToObject(totalSizeObj, "value", cJSON_CreateNumber(p->path_capacity.value));
+			cJSON_AddItemToObject(totalSizeObj, "unit", cJSON_CreateNumber(p->path_capacity.unit));
+
+			// Add path latency
+			cJSON* pathLatObj;
+			char lat[16];
+			sprintf(lat, "%lf", p->path_latency.fixed_latency);
+			cJSON_AddItemToObject(pathObj, "path-latency", pathLatObj= cJSON_CreateObject());
+			cJSON_AddItemToObject(pathLatObj, "fixed-latency-characteristic", cJSON_CreateString(lat));
+
+			// Add path cost
+			cJSON* pathCostObj;
+			cJSON_AddItemToObject(pathObj, "path-cost", pathCostObj = cJSON_CreateObject());
+			cJSON_AddItemToObject(pathCostObj, "cost-name", cJSON_CreateString(p->path_cost.cost_name));
+			char value[16];
+			sprintf(value, "%lf", p->path_cost.cost_value);
+			cJSON_AddItemToObject(pathCostObj, "cost-value", cJSON_CreateString(value));
+			char algorithm[16];
+			sprintf(algorithm, "%lf", p->path_cost.cost_algorithm);
+			cJSON_AddItemToObject(pathCostObj, "cost-algorithm", cJSON_CreateString(algorithm));
+
+			// Add the links
+			//add_comp_path_link_json(pathObj, p);
+			// Add deviceId, endpointId
+			add_comp_path_deviceId_endpointId_json(pathObj, p, oElem);
+		}	
+	}
+	
+    //DEBUG_PC ("JSON Body Response DONE");	
+    buftmp = (char *)cJSON_Print(root);
+    strcat (body, (const char*) buftmp);
+    *length = strlen ((const char*)body);    
+    //DEBUG_PC ("JSON Body (length: %d)", *length);
+    //DEBUG_PC ("%s", body);    
+	cJSON_Delete (root);
+	g_free(buftmp);
+    return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to return response OK via REST API with the computed serviceId
+ * 	
+ * 	@param source
+ *  @param httpCode
+ *  @param compRouteOutputList
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void rapi_response_ok (GIOChannel *source, gint httpCode, struct compRouteOutputList_t *compRouteOutputList) {
+    
+	gint ret = 0;
+    
+    //DEBUG_PC ("Creating the JSON Body and sending the response of the computed Route List");
+    
+    char buftmp[1024];
+    char *buf = g_malloc0 (sizeof (char) * 2048000); 
+    // Create the Body of the Response 
+    char * msgBody = g_malloc0 (sizeof (char) * 2048000);    
+    gint length = 0;
+	
+	//  If path computation was requested, the resulting computation is returned in the msg body
+	if (compRouteOutputList != NULL) {
+		rapi_response_json_contents(msgBody, &length, compRouteOutputList);
+	}
+	// no path computation was requested, then a basic msg is just added
+	else {
+		cJSON* root = cJSON_CreateObject();
+		char status[3];
+		sprintf(status, "OK");
+		cJSON_AddItemToObject(root, "Status", cJSON_CreateString(status));
+		msgBody = (char*)cJSON_Print(root);
+		length = strlen((const char*)msgBody);
+		cJSON_Delete(root);
+	}
+		
+	sprintf((char *)buf, "HTTP/1.1 200 OK\r\n");    
+	
+    sprintf((char *)buftmp, SERVER_STRING);
+    strcat ((char *)buf, (const char *)buftmp);    
+  
+    sprintf ((char *)buftmp, "Content-Type: application/json\r\n");
+    strcat ((char *)buf, (const char *)buftmp);    
+    
+    // Add the length of the JSON enconding to the Content_Length
+    char buff_length[16];    
+    sprintf(buff_length, "%d", length);
+    
+    sprintf ((char *)buftmp, "Content-Length: ");
+    strcat ((char *)buftmp, (const char *)buff_length);
+    strcat ((char *)buftmp, "\r\n");
+    strcat ((char *)buf, (const char *)buftmp);    
+    
+    // Add DATE header
+    rapi_add_date_header ((char *)buftmp);
+    strcat ((char *)buf, (const char *)buftmp);     
+    sprintf((char *)buftmp, "\r\n");
+    strcat ((char *)buf, (const char *)buftmp);
+
+	strcat((char*)buf, (const char*)msgBody);
+			
+	//DEBUG_PC ("%s", buf);	    
+    ret = rapi_send_message (source, buf);    
+    g_free (buf);
+    memset (buftmp, '\0', sizeof ( buftmp));    
+    g_free (msgBody);
+    (void)ret;    
+    return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to return response OK via REST API
+ * 	
+ * 	@param source
+ *  @param error
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void rapi_response (GIOChannel *source, gint error)
+{
+	 int ret = 0;	
+	 guchar buftmp[1024];
+	 char * buf = g_malloc0 (sizeof (char) * 2048000);
+	 if (error == HTTP_RETURN_CODE_BAD_REQUEST)
+		sprintf((char *)buf, "HTTP/1.1 400 BAD REQUEST\r\n");
+	 else if (error == HTTP_RETURN_CODE_UNAUTHORIZED)
+		sprintf((char *)buf, "HTTP/1.1 401 UNAUTHORIZED\r\n");
+	 else if (error == HTTP_RETURN_CODE_FORBIDDEN)
+		sprintf((char *)buf, "HTTP/1.1 403 FORBIDDEN\r\n");    
+	 else if (error == HTTP_RETURN_CODE_NOT_FOUND)
+		sprintf((char *)buf, "HTTP/1.1 404 NOT FOUND\r\n");
+	 
+	 sprintf((char *)buftmp, SERVER_STRING);
+	 strcat ((char *)buf, (const char *)buftmp);    
+	
+	 sprintf((char *)buftmp, "Content-Type: text/plain\r\n");
+	 strcat ((char *)buf, (const char *)buftmp);    
+	 
+	 sprintf((char *)buftmp, "Content-Length: 0/plain\r\n");
+	 strcat ((char *)buf, (const char *)buftmp);    
+	 
+	 // Add DATE header
+	 rapi_add_date_header ((char *)buftmp);
+	 strcat ((char *)buf, (const char *)buftmp);     
+	     
+	 sprintf((char *)buftmp, "\r\n");
+	 strcat ((char *)buf, (const char *)buftmp);
+	 // Print the prepared message
+	 DEBUG_PC ("%s", buf);
+	 
+	 // Send the message
+	 ret = rapi_send_message (source, buf);	 
+	 g_free (buf);	 
+	 (void)ret;
+	
+	 return;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the array of Endpoint Ids
+ *
+ * 	@param endPointArray
+ *  @param s
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parse_service_endPointsIds_array(cJSON* endPointIdArray, struct service_t* s) {
+
+	for (gint i = 0; i < cJSON_GetArraySize(endPointIdArray); i++) {
+		s->num_service_endpoints_id++;
+		struct service_endpoints_id_t* serviceEndPointId = &(s->service_endpoints_id[i]);
+
+		cJSON* item = cJSON_GetArrayItem(endPointIdArray, i);
+
+		// Get the topology Id Object
+		cJSON* topologyIdObj = cJSON_GetObjectItem(item, "topology_id");
+		if (cJSON_IsObject(topologyIdObj)) {
+			// Get the context Id (UUID) from the topologyIdObj
+			cJSON* contextIdObj = cJSON_GetObjectItem(topologyIdObj, "contextId");
+			if (cJSON_IsString(contextIdObj)) {					
+				duplicate_string(serviceEndPointId->topology_id.contextId, contextIdObj->valuestring);
+				//DEBUG_PC("Service EndPoint [%d]-- ContextId: %s (uuid string format)", i + 1, serviceEndPointId->topology_id.contextId);
+			}
+			// Get the topologyId (UUID) from the topologyIdObj
+			cJSON* topologyUuidObj = cJSON_GetObjectItem(topologyIdObj, "topology_uuid");
+			if (cJSON_IsString(topologyUuidObj)) {				
+				duplicate_string(serviceEndPointId->topology_id.topology_uuid, topologyUuidObj->valuestring);
+				//DEBUG_PC("Service Endpoint (%d) -- TopologyId: %s (uuid string format)", i + 1, serviceEndPointId->topology_id.topology_uuid);
+			}			
+		}
+		// Get the deviceId (UUID)
+		cJSON* deviceIdObj = cJSON_GetObjectItem(item, "device_id");
+		if (cJSON_IsString(deviceIdObj)) {			
+			duplicate_string(serviceEndPointId->device_uuid, deviceIdObj->valuestring);
+			DEBUG_PC("[%d] - DeviceId: %s", i + 1, serviceEndPointId->device_uuid);
+		}
+		// Get the endpointId (UUID)
+		cJSON* endPointIdObj = cJSON_GetObjectItem(item, "endpoint_uuid");
+		if (cJSON_IsString(endPointIdObj)) {
+			duplicate_string(serviceEndPointId->endpoint_uuid, endPointIdObj->valuestring);
+			DEBUG_PC("[%d] EndPointId: %s", i + 1, serviceEndPointId->endpoint_uuid);
+		}		
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the array with the required service constraints
+ *
+ * 	@param constraintArray
+ *  @param s
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parse_service_constraints(cJSON* constraintArray, struct service_t* s) {
+
+	for (gint i = 0; i < cJSON_GetArraySize(constraintArray); i++) {
+
+		s->num_service_constraints++;
+
+		struct constraint_t* constraint = &(s->constraints[i]);
+
+		cJSON* item = cJSON_GetArrayItem(constraintArray, i);
+
+		// Get the constraint type
+		cJSON* typeObj = cJSON_GetObjectItem(item, "constraint_type");
+		if (cJSON_IsString(typeObj)) {
+			duplicate_string(constraint->constraint_type, typeObj->valuestring);
+		}
+		// Get the constraint value
+		cJSON* valueObj = cJSON_GetObjectItem(item, "constraint_value");
+		if (cJSON_IsString(valueObj)) {
+			 duplicate_string(constraint->constraint_value, valueObj->valuestring);
+		} 
+		DEBUG_PC("Service Reqs [%d] -- Type: %s | Value: %s", i+1, constraint->constraint_type, constraint->constraint_value);
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the array with the different
+ * network services
+ *
+ * 	@param serviceArray
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parsing_json_serviceList_array(cJSON* serviceArray) {
+
+	for (gint i = 0; i < cJSON_GetArraySize(serviceArray); i++)
+	{
+		serviceList->numServiceList++;
+		struct service_t* service = &(serviceList->services[i]); 
+
+		cJSON* item = cJSON_GetArrayItem(serviceArray, i);
+		
+		// Get the algorithm Id
+		cJSON* algIdItem = cJSON_GetObjectItem(item, "algId");
+		if (cJSON_IsString(algIdItem))
+		{
+			duplicate_string(service->algId, algIdItem->valuestring);
+			DEBUG_PC ("algId: %s", service->algId);
+			// assumed that all the services request the same algId
+			duplicate_string(algId, service->algId);
+		}
+
+		// Get the syncPaths
+		cJSON* synchPathObj = cJSON_GetObjectItemCaseSensitive(item, "syncPaths");
+		if (cJSON_IsBool(synchPathObj))
+		{
+			// Check Synchronization of multiple Paths to attain e.g. global concurrent optimization
+			if (cJSON_IsTrue(synchPathObj))
+			{
+				syncPath = TRUE;
+				DEBUG_PC("Path Synchronization is required");
+			}
+			if (cJSON_IsFalse(synchPathObj))
+			{
+				syncPath = FALSE;
+				DEBUG_PC("No Path Synchronization");
+			}
+		}
+
+		// Get service Id in terms of contextId and service uuids
+		cJSON* serviceIdObj = cJSON_GetObjectItem(item, "serviceId");
+		if (cJSON_IsObject(serviceIdObj)) {
+			// Get context Id uuid
+			cJSON* contextIdObj = cJSON_GetObjectItem(serviceIdObj, "contextId");
+			if (cJSON_IsString(contextIdObj)) {
+				// convert the string in contextId->valuestring in uuid binary format
+				duplicate_string(service->serviceId.contextId, contextIdObj->valuestring);
+				DEBUG_PC("ContextId: %s (uuid string format)", service->serviceId.contextId);
+			}
+			// Get service Id uuid
+			cJSON* serviceUuidObj = cJSON_GetObjectItem(serviceIdObj, "service_uuid");
+			if (cJSON_IsString(serviceUuidObj)) {				
+				duplicate_string(service->serviceId.service_uuid, serviceUuidObj->valuestring);
+				DEBUG_PC("Service UUID: %s (uuid string format)", service->serviceId.service_uuid);
+			}				
+		}		
+
+		// Get de service type
+		cJSON* serviceTypeObj = cJSON_GetObjectItem(item, "serviceType");
+		if (cJSON_IsNumber(serviceTypeObj))
+		{
+			service->service_type = (guint)(serviceTypeObj->valuedouble);
+			print_service_type(service->service_type);
+		}
+
+		// Get the endPoints array of the service
+		cJSON* endPointIdsArray = cJSON_GetObjectItem(item, "service_endpoints_ids");
+		if (cJSON_IsArray(endPointIdsArray)) {
+			parse_service_endPointsIds_array(endPointIdsArray, service);
+		}	
+
+		// Get the service constraints
+		cJSON* constraintArray = cJSON_GetObjectItem(item, "service_constraints");
+		if (cJSON_IsArray(constraintArray)) {
+			parse_service_constraints(constraintArray, service);
+		}		
+
+		// Get the maximum number of paths to be computed (kPaths)
+		cJSON* kPathsObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths");
+		if (cJSON_IsNumber(kPathsObj)){
+			service->kPaths = (guint)(kPathsObj->valuedouble);
+		}
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function parsing the capacity attributes in the endpoint
+ *
+ * 	@param capacity
+ *  @param c
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parse_capacity_object(cJSON* capacity, struct capacity_t* c) {
+
+	cJSON* totalSizeObj = cJSON_GetObjectItem(capacity, "total-size");
+	if (cJSON_IsObject(totalSizeObj)) {
+		//Get the capacity value
+		cJSON* valueObj = cJSON_GetObjectItem(totalSizeObj, "value");
+		if (cJSON_IsNumber(valueObj)) {
+			memcpy(&c->value, &valueObj->valuedouble, sizeof (gdouble));
+		}
+		// Get the Units
+		cJSON* unitObj = cJSON_GetObjectItem(totalSizeObj, "unit");
+		if (cJSON_IsNumber(unitObj)) {
+			c->unit = (guint)(unitObj->valuedouble);
+		}	
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function parsing the device endpoints
+ *
+ * 	@param endPointsArray
+ *  @param d
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parse_json_device_endpoints_array(cJSON* endPointsArray, struct device_t* d) {
+
+	for (gint i = 0; i < cJSON_GetArraySize(endPointsArray); i++) {
+		d->numEndPoints++;
+		struct endPoint_t* endpoint = &(d->endPoints[i]);
+
+		cJSON* item = cJSON_GetArrayItem(endPointsArray, i);
+
+		// Get the Endpoint Identifier: topology, context, device and endpointId
+		cJSON* endPointIdObj = cJSON_GetObjectItem(item, "endpoint_id");
+		if (cJSON_IsObject(endPointIdObj)) {
+			// Get the topology Id Object
+			cJSON* topologyIdObj = cJSON_GetObjectItem(endPointIdObj, "topology_id");
+			if (cJSON_IsObject(topologyIdObj)) {
+				// Get the context Id (UUID) from the topologyIdObj
+				cJSON* contextIdObj = cJSON_GetObjectItem(topologyIdObj, "contextId");
+				if (cJSON_IsString(contextIdObj)) {
+					duplicate_string(endpoint->endPointId.topology_id.contextId, contextIdObj->valuestring);
+					//DEBUG_PC("Device EndPoint (%d)-- ContextId: %s (uuid string format)", i + 1, endpoint->endPointId.topology_id.contextId);
+				}
+				// Get the topologyId (UUID) from the topologyIdObj
+				cJSON* topologyUuidObj = cJSON_GetObjectItem(topologyIdObj, "topology_uuid");
+				if (cJSON_IsString(topologyUuidObj)) {					
+					duplicate_string(endpoint->endPointId.topology_id.topology_uuid, topologyUuidObj->valuestring);
+					//DEBUG_PC("Device Endpoint (%d) -- TopologyId: %s (uuid string format)", i + 1, endpoint->endPointId.topology_id.topology_uuid);
+				}
+			}
+			// Get the deviceId
+			cJSON* deviceIdObj = cJSON_GetObjectItem(endPointIdObj, "device_id");
+			if (cJSON_IsString(deviceIdObj)) {				
+				duplicate_string(endpoint->endPointId.device_id, deviceIdObj->valuestring);
+				//DEBUG_PC("Device Endpoint (%d) -- Device Id: %s (uuid)", i + 1, endpoint->endPointId.device_id);
+			}
+			// Get the endpoint_uuid
+			cJSON* endPointUuidObj = cJSON_GetObjectItem(endPointIdObj, "endpoint_uuid");
+			if (cJSON_IsString(endPointUuidObj)) {				
+				duplicate_string(endpoint->endPointId.endpoint_uuid, endPointUuidObj->valuestring);
+				//DEBUG_PC("Device Endpoint (%d) -- EndPoint Uuid: %s (uuid)", i + 1, endpoint->endPointId.endpoint_uuid);
+			}
+		}
+		// Get the EndPoint Type
+		cJSON* endPointTypeObj = cJSON_GetObjectItem(item, "endpoint_type");
+		if (cJSON_IsString(endPointTypeObj)) {
+			duplicate_string(endpoint->endpointType, endPointTypeObj->valuestring);
+			//DEBUG_PC("Device Endpoint (%d) -- EndPoint Type: %s", i + 1, endpoint->endpointType);
+		}
+		// Link Port Direction
+		cJSON* linkPortDirectionObj = cJSON_GetObjectItem(item, "link_port_direction");
+		if (cJSON_IsNumber(linkPortDirectionObj)) {
+			endpoint->link_port_direction = (guint)(linkPortDirectionObj->valuedouble);
+			print_link_port_direction(endpoint->link_port_direction);
+		}
+		// EndPoint Termination Direction
+		cJSON* terminationDirectionObj = cJSON_GetObjectItem(item, "termination-direction");
+		if (cJSON_IsNumber(terminationDirectionObj)) {
+			endpoint->termination_direction = (guint)(terminationDirectionObj->valuedouble);
+			print_termination_direction(endpoint->termination_direction);
+		}
+		// Endpoint Termination State
+		cJSON* terminationStateObj = cJSON_GetObjectItem(item, "termination-state");
+		if (cJSON_IsNumber(terminationStateObj)) {
+			endpoint->termination_state = (guint)(terminationStateObj->valuedouble);
+			print_termination_state(endpoint->termination_state);
+		}
+		// total potential capacity
+		cJSON* totalPotentialCapacityObj = cJSON_GetObjectItem(item, "total-potential-capacity");
+		if (cJSON_IsObject(totalPotentialCapacityObj))
+		{
+			parse_capacity_object(totalPotentialCapacityObj, &endpoint->potential_capacity);
+			//DEBUG_PC("Device Endpoint (%d) -- Potential Capacity: %f", i + 1, endpoint->potential_capacity.value);
+			print_capacity_unit(endpoint->potential_capacity.unit);
+		}
+		// total available capacity
+		cJSON* availableCapacityObj = cJSON_GetObjectItem(item, "available-capacity");
+		if (cJSON_IsObject(availableCapacityObj))
+		{
+			parse_capacity_object(availableCapacityObj, &endpoint->available_capacity);
+			//DEBUG_PC("Device Endpoint (%d) -- Available Capacity: %f", i + 1, endpoint->available_capacity.value);
+			print_capacity_unit(endpoint->available_capacity.unit);
+		}
+		// inter-domain plug-in
+		cJSON* interDomainPlugInObj = cJSON_GetObjectItem(item, "inter-domain-plug-in");
+		if (cJSON_IsObject(interDomainPlugInObj)) {
+			// Get the local
+			cJSON* idInterDomainLocal = cJSON_GetObjectItem(interDomainPlugInObj, "plug-id-inter-domain-local-id");
+			if (cJSON_IsString(idInterDomainLocal)) {
+				duplicate_string(endpoint->inter_domain_plug_in.inter_domain_plug_in_local_id, idInterDomainLocal->valuestring);
+				//DEBUG_PC("Inter-Domain Local Id: %s", endpoint->inter_domain_plug_in.inter_domain_plug_in_local_id);				
+			}
+			// Get the remote
+			cJSON* idInterDomainRemote = cJSON_GetObjectItem(interDomainPlugInObj, "plug-id-inter-domain-remote-id");
+			if (cJSON_IsString(idInterDomainRemote)) {
+				duplicate_string(endpoint->inter_domain_plug_in.inter_domain_plug_in_remote_id, idInterDomainRemote->valuestring);
+				//DEBUG_PC("Inter-Domain Remote Id: %s", endpoint->inter_domain_plug_in.inter_domain_plug_in_remote_id);
+			}
+		}
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the set/list of devices forming the context/topology
+ *
+ * 	@param deviceArray
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parsing_json_deviceList_array(cJSON* deviceArray) {
+	DEBUG_PC("");
+	DEBUG_PC("========= PARSING DEVICE LIST ============");
+	for (gint i = 0; i < cJSON_GetArraySize(deviceArray); i++) {
+		deviceList->numDevices++;
+		struct device_t* d = &(deviceList->devices[i]);
+		cJSON* item = cJSON_GetArrayItem(deviceArray, i);
+
+		// Get the device UUID
+		cJSON* deviceUuidObj = cJSON_GetObjectItem(item, "device_Id");
+		if (cJSON_IsString(deviceUuidObj)) {
+			duplicate_string(d->deviceId, deviceUuidObj->valuestring);
+			DEBUG_PC("Device (%d) -- Id: %s (uuid string format)", i + 1, d->deviceId);
+		}
+
+		// Get the device Type
+		cJSON* deviceTypeObj = cJSON_GetObjectItem(item, "device_type");
+		if (cJSON_IsString(deviceTypeObj)) {
+			duplicate_string(d->deviceType, deviceTypeObj->valuestring);
+			//DEBUG_PC("  Device Type: %s ---", d->deviceType);
+		}
+		DEBUG_PC("DeviceId: %s, Device Type: %s", d->deviceId, d->deviceType);
+
+		// get the device endPoints
+		cJSON* deviceEndpointsArray = cJSON_GetObjectItem(item, "device_endpoints");
+		if (cJSON_IsArray(deviceEndpointsArray)) {
+			parse_json_device_endpoints_array(deviceEndpointsArray, d);
+		}
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the JSON objects the endPoint of a link
+ *
+ * 	@param endPointsLinkObj
+ *  @param l
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parse_json_link_endpoints_array(cJSON *endPointsLinkObj, struct link_t* l) {
+
+	for (gint i = 0; i < cJSON_GetArraySize(endPointsLinkObj); i++) {
+		//DEBUG_PC("link: %s has %d endPointIds", l->linkId, l->numLinkEndPointIds);
+		l->numLinkEndPointIds++;
+		struct link_endpointId_t* endPointLink = &(l->linkEndPointId[i]);
+
+		cJSON* item = cJSON_GetArrayItem(endPointsLinkObj, i);
+
+		// Get endPoint attributes (topologyId, deviceId, endpoint_uuid)
+		cJSON* endPointIdObj = cJSON_GetObjectItem(item, "endpoint_id");
+		if (cJSON_IsObject(endPointIdObj)) {
+			// Get the topology Id Object
+			cJSON* topologyIdObj = cJSON_GetObjectItem(endPointIdObj, "topology_id");
+			if (cJSON_IsObject(topologyIdObj)) {
+				// Get the context Id (UUID) from the topologyIdObj
+				cJSON* contextIdObj = cJSON_GetObjectItem(topologyIdObj, "contextId");
+				if (cJSON_IsString(contextIdObj)) {					
+					duplicate_string(endPointLink->topology_id.contextId, contextIdObj->valuestring);
+					//DEBUG_PC("Link EndPoint (%d)-- ContextId: %s (uuid string format)", i + 1, endPointLink->topology_id.contextId);
+				}
+				// Get the topologyId (UUID) from the topologyIdObj
+				cJSON* topologyUuidObj = cJSON_GetObjectItem(topologyIdObj, "topology_uuid");
+				if (cJSON_IsString(topologyUuidObj)) {
+					duplicate_string(endPointLink->topology_id.topology_uuid, topologyUuidObj->valuestring);
+					//DEBUG_PC("Link Endpoint (%d) -- TopologyId: %s (uuid string format)", i + 1, endPointLink->topology_id.topology_uuid);
+				}
+			}
+			// Get the deviceId
+			cJSON* deviceIdObj = cJSON_GetObjectItem(endPointIdObj, "device_id");
+			if (cJSON_IsString(deviceIdObj)) {
+				duplicate_string(endPointLink->deviceId, deviceIdObj->valuestring);
+				DEBUG_PC("   Link Endpoint[%d] -- DeviceId: %s", i + 1, endPointLink->deviceId);
+			}
+			// Get the endpoint_uuid
+			cJSON* endPointUuidObj = cJSON_GetObjectItem(endPointIdObj, "endpoint_uuid");
+			if (cJSON_IsString(endPointUuidObj)) {
+				duplicate_string(endPointLink->endPointId, endPointUuidObj->valuestring);
+				//DEBUG_PC("Link Endpoint (%d) -- EndPoint Uuid: %s (uuid)", i + 1, endPointLink->endPointId);
+			}
+		}
+	}
+	//DEBUG_PC("link id: %s has %d endpoints", l->linkId, l->numLinkEndPointIds);
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the JSON objects describing the set of links
+ *
+ * 	@param linkListArray
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void parsing_json_linkList_array(cJSON* linkListArray) {
+
+	DEBUG_PC("");
+	DEBUG_PC("======= PARSING OF THE LINK LIST ARRAY ==========");
+	for (gint i = 0; i < cJSON_GetArraySize(linkListArray); i++) {
+		linkList->numLinks++;
+		struct link_t* l = &(linkList->links[i]);
+		//l->numLinkEndPointIds = 0;
+
+		cJSON* item = cJSON_GetArrayItem(linkListArray, i);
+		// Get the link Id (uuid)
+		cJSON* linkIdObj = cJSON_GetObjectItem(item, "link_Id");
+		if (cJSON_IsString(linkIdObj)) {
+			duplicate_string(l->linkId, linkIdObj->valuestring);
+			DEBUG_PC(" * Link (%d) -- Id: %s (uuid)", i + 1, l->linkId);
+		}
+		// Get the link endpoints (assumed to be p2p)
+		cJSON* endPointsLinkObj = cJSON_GetObjectItem(item, "link_endpoint_ids");
+		if (cJSON_IsArray(endPointsLinkObj)) {
+			//DEBUG_PC("number linkEndPointIds: %d", l->numLinkEndPointIds);
+			parse_json_link_endpoints_array(endPointsLinkObj, l);
+		}
+		// get the fowarding direction
+		cJSON* fwdDirObj = cJSON_GetObjectItem(item, "forwarding_direction");
+		if (cJSON_IsNumber(fwdDirObj)) {
+			l->forwarding_direction = (guint)(fwdDirObj->valuedouble);
+			print_link_forwarding_direction(l->forwarding_direction);
+		}
+		// total potential capacity
+		cJSON* totalPotentialCapacityObj = cJSON_GetObjectItem(item, "total-potential-capacity");
+		if (cJSON_IsObject(totalPotentialCapacityObj))
+		{
+			parse_capacity_object(totalPotentialCapacityObj, &l->potential_capacity);
+			//DEBUG_PC("Link (%d) -- Potential Capacity: %f", i + 1, l->potential_capacity.value);
+			print_capacity_unit(l->potential_capacity.unit);
+		}
+		// total available capacity
+		cJSON* availableCapacityObj = cJSON_GetObjectItem(item, "available-capacity");
+		if (cJSON_IsObject(availableCapacityObj))
+		{
+			parse_capacity_object(availableCapacityObj, &l->available_capacity);
+			//DEBUG_PC("Link (%d) -- Available Capacity: %f", i + 1, l->available_capacity.value);
+			print_capacity_unit(l->available_capacity.unit);
+		}
+		// Cost Characteristics
+		cJSON* costCharacObj = cJSON_GetObjectItem(item, "cost-characteristics");
+		if (cJSON_IsObject(costCharacObj)) {
+			// Cost Name
+			cJSON* costNameObj = cJSON_GetObjectItem(costCharacObj, "cost-name");
+			if (cJSON_IsString(costNameObj)) {
+				duplicate_string(l->cost_characteristics.cost_name, costNameObj->valuestring);
+				//DEBUG_PC("Link (%d) -- Cost Name: %s", i + 1, l->cost_characteristics.cost_name);
+			}
+			// Cost value
+			cJSON* costValueObj = cJSON_GetObjectItem(costCharacObj, "cost-value");
+			if (cJSON_IsString(costValueObj)) {
+				char* endpr;
+				l->cost_characteristics.cost_value = (gdouble)(strtod(costValueObj->valuestring, &endpr));
+				//DEBUG_PC("Link (%d) -- Cost Value: %f", i + 1, l->cost_characteristics.cost_value);
+			}
+			// Cost Algorithm
+			cJSON* costAlgObj = cJSON_GetObjectItem(costCharacObj, "cost-algorithm");
+			if (cJSON_IsString(costAlgObj)) {
+				char* endpr;
+				l->cost_characteristics.cost_algorithm = (gdouble)(strtod(costAlgObj->valuestring, &endpr));
+				//DEBUG_PC("Link (%d) -- Cost Algorithm: %f", i + 1, l->cost_characteristics.cost_algorithm);
+			}
+		}
+		// Latency Characteristics
+		cJSON* latencyCharacObj = cJSON_GetObjectItem(item, "latency-characteristics");
+		if (cJSON_IsObject(latencyCharacObj)) {
+			cJSON* fixedLatencyCharacObj = cJSON_GetObjectItem(latencyCharacObj, "fixed-latency-characteristic");
+			if (cJSON_IsString(fixedLatencyCharacObj)) {
+				char* endpr;
+				l->latency_characteristics.fixed_latency = (gdouble)(strtod(fixedLatencyCharacObj->valuestring, &endpr));
+				//DEBUG_PC("Link (%d) -- Latency: %f", i + 1, l->latency_characteristics.fixed_latency);
+			}	
+		}
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to generate the reverse (unidirecitonal) link from those being learnt
+ *  from the received context
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+void generate_reverse_linkList() {
+	DEBUG_PC("");
+	DEBUG_PC("CREATION OF REVERSE LINKS");
+	gint numLinks = linkList->numLinks;
+	
+	for (gint i = 0; i < numLinks; i++) {
+		struct link_t* refLink = &(linkList->links[i]);
+		struct link_t* newLink = &(linkList->links[numLinks + i]);
+		linkList->numLinks++;
+		// Copy the linkId + appending "_rev"
+		duplicate_string(newLink->linkId, refLink->linkId);
+		strcat(newLink->linkId, "_rev");
+
+		//DEBUG_PC("refLink: %s // newLink: %s", refLink->linkId, newLink->linkId);
+
+		// Assumption: p2p links. The newLink endpoints are the reversed ones form the reference Link (refLink)
+		// i.e., refLink A->B, then newLink B->A
+		//DEBUG_PC("ref: %s has %d endpoints", refLink->linkId, refLink->numLinkEndPointIds);
+#if 1
+		if (refLink->numLinkEndPointIds != 2) {
+			DEBUG_PC("To construct the new Link from ref: %s, 2 EndPoints are a MUST", refLink->linkId);
+			exit(-1);
+		}
+#endif
+		DEBUG_PC(" * Link[%d] -- Id: %s", numLinks + i, newLink->linkId);
+
+		//DEBUG_PC("Number of Endpoints in Link: %d", refLink->numLinkEndPointIds);
+		for (gint j = refLink->numLinkEndPointIds - 1, m = 0; j >= 0; j--, m++) {			
+			struct link_endpointId_t* refEndPId = &(refLink->linkEndPointId[j]);
+			struct link_endpointId_t* newEndPId = &(newLink->linkEndPointId[m]);
+			// Duplicate the topologyId information, i.e., contextId and topology_uuid
+			duplicate_string(newEndPId->topology_id.contextId, refEndPId->topology_id.contextId);
+			duplicate_string(newEndPId->topology_id.topology_uuid, refEndPId->topology_id.topology_uuid);
+			//duplicate the deviceId and endPoint_uuid
+			duplicate_string(newEndPId->deviceId, refEndPId->deviceId);
+			duplicate_string(newEndPId->endPointId, refEndPId->endPointId);
+			DEBUG_PC("refLink Endpoint[%d]: %s(%s)", j, refEndPId->deviceId, refEndPId->endPointId);
+			//DEBUG_PC("newLink Endpoint[%d]: %s(%s)", m, newEndPId->deviceId, newEndPId->endPointId);
+			newLink->numLinkEndPointIds++;
+		}
+
+		// duplicate forwarding direction
+		newLink->forwarding_direction = refLink->forwarding_direction;
+
+		// duplicate capacity attributes
+		memcpy(&newLink->potential_capacity.value, &refLink->potential_capacity.value, sizeof(gdouble));
+		newLink->potential_capacity.unit = refLink->potential_capacity.unit;
+
+		memcpy(&newLink->available_capacity.value, &refLink->available_capacity.value, sizeof(gdouble));
+		newLink->available_capacity.unit = refLink->available_capacity.unit;
+
+		// duplicate cost characteristics
+		memcpy(&newLink->cost_characteristics.cost_value, &refLink->cost_characteristics.cost_value, sizeof(gdouble));
+		memcpy(&newLink->cost_characteristics.cost_algorithm, &refLink->cost_characteristics.cost_algorithm, sizeof(gdouble));
+		duplicate_string(newLink->cost_characteristics.cost_name, refLink->cost_characteristics.cost_name);
+
+		// duplicate latency characteristics
+		memcpy(&newLink->latency_characteristics.fixed_latency, &refLink->latency_characteristics.fixed_latency, sizeof(gdouble));
+	}
+	DEBUG_PC("Terminating Reverse Links [total: %d]", linkList->numLinks);
+	return;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to parse the JSON object/s for the PATH COMP request (i.e. service
+ *  requests, device and links)
+ * 	
+ * 	@param root
+ * 	@param source
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void parsing_json_obj_pathComp_request(cJSON * root, GIOChannel * source)
+{
+	//DEBUG_PC("**");
+	if (deviceList == NULL){	
+	  	DEBUG_PC ("Device List does not exist ... STOP");
+	  	exit(-1);
+	}
+
+	if (linkList == NULL) {
+		DEBUG_PC("Link List does not exist ... STOP")
+	}
+	
+	if (serviceList == NULL)
+	{
+		DEBUG_PC ("Service List does not exist ... STOP");
+		exit(-1);       
+	} 
+
+	// Set of services to seek their path and resource selection
+	cJSON* serviceListArray = cJSON_GetObjectItem(root, "serviceList");
+	if (cJSON_IsArray(serviceListArray)) {
+		parsing_json_serviceList_array(serviceListArray);
+	}   
+    
+	// Get the deviceList
+	cJSON* deviceListArray = cJSON_GetObjectItem(root, "deviceList");
+	if (cJSON_IsArray(deviceListArray)) {
+		parsing_json_deviceList_array(deviceListArray);
+	}
+
+	// Get the linkList
+	cJSON* linkListArray = cJSON_GetObjectItem(root, "linkList");
+	if (cJSON_IsArray(linkListArray)) {
+		parsing_json_linkList_array(linkListArray);
+
+		// In the context information, if solely the list of links are passed for a single direction, 
+		// the reverse direction MUST be created sythetically 
+		generate_reverse_linkList();
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used parse the JSON object/s 
+ * 	
+ * 	@param data
+ *  @param source
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint parsing_json_obj (guchar *data, GIOChannel *source) {
+    cJSON * root = cJSON_Parse((const char *)data);
+    char * print = cJSON_Print(root);  
+
+	DEBUG_PC("STARTING PARSING JSON CONTENTS");
+	parsing_json_obj_pathComp_request (root, source);	
+	// Release the root JSON object variable
+	cJSON_free (root);
+	g_free(print);
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Create new tcp client connected to PATH COMP
+ * 
+ * 	@param channel_client, GIOChannel
+ *  @param fd
+ * 	
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct pathComp_client * RESTapi_client_create (GIOChannel * channel_client, gint fd) {
+	/** check values */
+	g_assert(channel_client != NULL); 
+
+	struct pathComp_client* client = g_malloc0 (sizeof (struct pathComp_client));
+	if (client == NULL )
+	{
+		DEBUG_PC ("Malloc for the client failed");
+		exit(-1);
+	}  
+
+	/** Make client input/output buffer. */
+	client->channel = channel_client;	
+	client->obuf = stream_new(MAXLENGTH);
+	client->ibuf = stream_new(MAXLENGTH);
+	client->fd = fd;
+
+	// Clients connected to the PATH COMP SERVER
+	CLIENT_ID++;
+	client->type = CLIENT_ID;
+
+	//DEBUG_PC ("Client Id: %u is created (%p)", client->type, client);
+	//DEBUG_PC ("Client ibuf: %p || obuf: %p", client->ibuf, client->obuf);
+
+	// Add the tcp client to the list
+	RESTapi_tcp_client_list = g_list_append (RESTapi_tcp_client_list, client);
+	//DEBUG_PC ("Num of TCP Clients: %d", g_list_length (RESTapi_tcp_client_list));
+	return client;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Close the tcp client, removing from the rapi_tcp_client_list
+ * 
+ * 	@param client
+ * 	
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void RESTapi_client_close (struct pathComp_client* client)
+{
+	//DEBUG_PC("Closing the client (Id: %d) %p", client->type, client);
+	//DEBUG_PC("Client ibuf: %p || obuf: %p", client->ibuf, client->obuf);
+	
+	if (client->ibuf != NULL)
+	{
+		//DEBUG_PC("Client ibuf: %p", client->ibuf);
+		stream_free(client->ibuf);
+		client->ibuf = NULL;
+	}
+	if (client->obuf != NULL)
+	{
+		//DEBUG_PC("Client obuf: %p", client->obuf);
+		stream_free(client->obuf);
+		client->obuf = NULL;
+	}
+	// Remove from the list
+	RESTapi_tcp_client_list = g_list_remove (RESTapi_tcp_client_list, client);
+	//DEBUG_PC ("TCP Client List: %d", g_list_length(RESTapi_tcp_client_list));
+	 
+	g_free (client);
+	client = NULL;	 
+	DEBUG_PC ("client has been removed ...");	 
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Close operations over the passed tcp channel
+ * 
+ * 	@param source
+ * 	
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void RESTapi_close_operations (GIOChannel * source)
+{
+	gint fd = g_io_channel_unix_get_fd (source);
+	
+	//DEBUG_PC ("Stop all the operations over the fd: %d", fd);	
+	g_io_channel_flush(source, NULL);
+	GError *error = NULL;    
+	g_io_channel_shutdown (source, TRUE, &error);
+	if(error)
+	{
+		DEBUG_PC ("An error occurred ...");
+	}
+	g_io_channel_unref (source);
+	return;	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Remove the client and close operations over the TCP connection
+ * 
+ * 	@param client
+ *  @param source
+ *  @param fd
+ * 	
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void RESTapi_stop (struct pathComp_client* client, GIOChannel * source, gint fd)
+{
+	
+	DEBUG_PC("Client Socket: %d is Stopped", fd);
+	// remove client
+	RESTapi_client_close(client);
+	// Stop operations over that channel
+	RESTapi_close_operations(source);
+	close (fd);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used read the different lines ending up in \r\n
+ * 	
+ * 	@param s
+ * 	@param buf
+ * 	@param size
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint RESTapi_get_line (GIOChannel *channel, gchar *buf, gint size)
+{
+    gint i = 0;
+    //DEBUG_PC ("\n");
+    //DEBUG_PC ("----- Read REST API Line(\r\n) ------");
+    gint n = 0;
+    guchar c = '\0'; // END OF FILE    
+    gboolean cr = FALSE;
+    while (i < size - 1)
+    {
+		n = read_channel (channel, &c, 1);		
+		if (n == -1)
+		{
+			//DEBUG_PC ("Close the channel and eliminate the client");
+			return -1;			
+		}	
+		if (n > 0)
+		{
+			//DEBUG_PC ("%c", c);
+			buf[i] = c;
+			i++;	
+			if (c == '\r')
+			{
+				cr = TRUE;	      
+			}	  
+			if ((c == '\n') && (cr == TRUE))
+			{	   
+				break;
+			}	        
+		} 
+		else
+		{
+			c = '\n';
+			buf[i] = c;
+			i++;
+			break;
+		}
+    }
+    buf[i] = '\0';    
+    //DEBUG_PC ("Line (size: %d) buf: %s", i, buf);
+    return i;
+}  
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used read the HTTP method
+ * 	
+ * 	@param buf
+ * 	@param j
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+guint RESTapi_get_method (gchar *buf, gint *j)
+{
+	guint RestApiMethod = 0;
+	gchar method[255];
+	gint i = 0;	
+	while (!ISspace(buf[*j]) && (i < sizeof(method) - 1))
+	{
+		method[i] = buf[*j];
+		i++; 
+		*j = *j + 1;
+	}
+	method[i] = '\0';
+	DEBUG_PC ("REST API METHOD: %s", method);	
+	
+	// Check that the methods are GET, POST or PUT
+	if (strcasecmp((const char *)method, "GET") && strcasecmp((const char *)method, "POST") && 
+		strcasecmp ((const char *)method, "HTTP/1.1") && strcasecmp ((const char *)method, "PUT"))
+	{
+		DEBUG_PC ("The method: %s is not currently supported ...", method);
+		return RestApiMethod;	
+	}
+	// Method selector
+	if (strncmp ((const char*)method, "GET", 3) == 0)
+	{
+		RestApiMethod = REST_API_METHOD_GET;		
+	}
+	else if (strncmp ((const char*)method, "POST", 4) == 0)
+	{
+		RestApiMethod = REST_API_METHOD_POST;
+	}	
+	else if (strncmp ((const char *)method, "HTTP/1.1", 8) == 0)
+	{
+		RestApiMethod = REST_API_METHOD_HTTP;
+	}
+	else if (strncmp ((const char *)method, "PUT", 3) == 0)
+	{
+		RestApiMethod = REST_API_METHOD_PUT;
+	}
+	
+	return RestApiMethod;	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used read the url
+ * 	
+ * 	@param buf
+ * 	@param j
+ *  @param url
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint get_url (gchar *buf, gint *j, gchar *url)
+{
+	// Skip space char
+	while (ISspace(buf[*j]) && (*j < strlen(buf))) {
+		*j = *j + 1;
+	}
+	
+	//DEBUG_PC ("buf[%d]: %c", *j, buf[*j]);
+	int result = isspace (buf[*j]);	
+	*buf = *buf + *j;
+	gint numChar = 0;
+	gint initChar = *j;
+	result = 0;
+	while (result == 0)	{
+		*j = *j + 1;
+		result = isspace (buf[*j]);
+		numChar++;
+	}
+	//DEBUG_PC ("numChar: %d", numChar);
+	memcpy (url, buf + initChar, numChar);
+	url[numChar] = '\0';
+	//DEBUG_PC ("url: %s", url);
+	return numChar;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used read the version
+ * 	
+ * 	@param buf
+ * 	@param j
+ *  @param version
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint get_version (gchar *buf, gint *j, gchar *version) {
+	// Skip space char
+	while (ISspace(buf[*j]) && (*j < strlen(buf)))
+	{
+		*j = *j + 1;
+	}	
+	//DEBUG_PC ("buf[%d]: %c", *j, buf[*j]);
+	int result = isspace (buf[*j]);	
+	*buf = *buf + *j;
+	gint numChar = 0;
+	gint initChar = *j;
+	result = 0;
+	while (result == 0)	{
+		*j = *j + 1;
+		result = isspace (buf[*j]);
+		numChar++;
+	}
+	//DEBUG_PC ("numChar: %d", numChar);
+	memcpy (version, buf + initChar, numChar);
+	version[numChar] = '\0';
+	//DEBUG_PC ("version: %s", version);	
+	return numChar;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to trigger the route computation for the network connectivity service
+ *  List and retrieve the result
+ * 	
+ * 	@param compRouteList
+ * 	@param raId
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint triggering_routeComp (struct compRouteOutputList_t *compRouteList, gchar *algId) {
+	g_assert (compRouteList);	
+	gint httpCode = HTTP_RETURN_CODE_OK;
+	DEBUG_PC("Requested Algorithm: %s", algId);
+	//////////////////// Algorithm Selector (RAId)//////////////////////////////////////	
+	// KSP algorithm
+	if (strncmp ((const char*)algId, "KSP", 3) == 0)
+	{
+		DEBUG_PC ("Alg Id: KSP");
+		httpCode = pathComp_ksp_alg(compRouteList);
+	}
+	// simple SP algorithm
+	else if (strncmp((const char*)algId, "SP", 2) == 0) {
+		DEBUG_PC("Alg Id: SP");
+		httpCode = pathComp_sp_alg(compRouteList);
+	}
+#if 0
+	// Infrastructure Abstraction (InA)
+	else if (strncmp ((const char*)raId, "InA", 3) == 0) 
+	{
+		//DEBUG_PC ("RA: InA");
+		httpCode = ra_InA_alg (compRouteList);
+	}
+	// Global Concurrent Optimization (GCO): Resoration / Re-Allocation / Re-Optimization
+	else if (strncmp ((const char*)raId, "GCO", 3) == 0)
+	{
+		//DEBUG_PC ("RA: GCO");
+		httpCode = ra_GCO_alg (compRouteList);	
+	}
+#endif
+	return httpCode;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to process the REST API commands
+ * 	
+ * 	@param source
+ * 	@param cond
+ * 	@param data
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gboolean RESTapi_activity(GIOChannel *source, GIOCondition cond, gpointer data)
+{  
+	/** some checks */
+	g_assert(source != NULL);
+	g_assert(data != NULL);	
+	
+	gchar buf[1024];
+	gchar version[255];
+	gchar http_result[255];
+	gint body_length = 0;	
+
+	struct pathComp_client *client = (struct pathComp_client*)(data);
+	DEBUG_PC (" ************************************************************************** ");    
+	DEBUG_PC ("                      REST API ACTIVITY Triggered ");
+	DEBUG_PC (" ************************************************************************** ");   
+
+	gint fd = g_io_channel_unix_get_fd (source);
+	DEBUG_PC ("fd: %d, cond: %d", fd, cond);
+
+	if (cond != G_IO_IN)
+	{
+		DEBUG_PC ("Something happening with the channel and fd ... (cond: %d)", cond);
+		RESTapi_stop(client, source, fd);
+		return FALSE;
+	}	
+	/** Clear input buffer. */
+	stream_reset (client->ibuf);
+
+	// get line
+	gint nbytes = RESTapi_get_line (source, buf, sizeof (buf));
+	if (nbytes == -1)
+	{
+		DEBUG_PC ("nbytes -1 ... CLOSE CLIENT FD and eliminate CLIENT");						
+		RESTapi_stop(client, source, fd);
+		return FALSE;						
+	}		
+	
+	if ((buf[0] == '\n') && (nbytes  == 1))
+	{
+		//DEBUG_PC (" -- buf[0] = newline --");
+		RESTapi_stop(client, source, fd);
+		return FALSE;
+	}
+	
+	gint i = 0, j = 0;
+	// Get the REST Method
+	guint RestApiMethod = RESTapi_get_method (buf, &j);
+	if (RestApiMethod == 0) 	{
+		DEBUG_PC ("The method is NOT supported ...");
+		RESTapi_unimplemented (source);
+		RESTapi_stop(client, source, fd);
+		return FALSE;
+	}
+
+	// get the REST url
+	gchar url[255];
+	i = get_url (buf, &j, url);	
+	url[i] = '\0';	
+
+	// GET - used for checking status of pathComp ... used url /pathComp/api/v1/health
+	if (RestApiMethod == REST_API_METHOD_GET) {
+		if (strncmp((const char*)url, "/health", 7) != 0) {
+			DEBUG_PC("unknown url [%s] for GET method -- Heatlh function", url);
+			RESTapi_stop(client, source, fd);
+			exit(-1);
+		}
+		else {
+			DEBUG_PC("Sending API Response OK to health requests");
+			rapi_response_ok(source, HTTP_RETURN_CODE_OK, NULL);
+			return TRUE;
+		}
+	}
+
+	// for method POST, PUT check that the url is "/pathComp"
+	if (RestApiMethod == REST_API_METHOD_POST) {
+		if (strncmp((const char*)url, "/pathComp/api/v1/compRoute", 26) != 0)
+		{
+			DEBUG_PC("Unknown url: %s", url);
+			RESTapi_stop(client, source, fd);
+			exit(-1);
+		}
+	}
+	
+	// get the version	
+	i = get_version (buf, &j, version);
+	version[i] = '\0';		
+
+	// Assume HTTP/1.1, then there is Host Header
+	memset(buf, '\0', sizeof(buf));        
+	nbytes = RESTapi_get_line(source, buf, sizeof (buf));
+	if (nbytes == -1)
+	{
+		DEBUG_PC ("nbytes -1 ... then close the fd and eliminate associated client");			
+		RESTapi_stop(client, source, fd);
+		return FALSE;					
+	}
+
+	//DEBUG_PC ("Header: %s", buf);	
+	
+	// Headers --- The Header Fields ends up with a void line (i.e., \r\n)
+	while ((nbytes > 0) && (strcmp ("\r\n", (const char *)buf) != 0))
+	{	
+		/* read & discard headers */
+		memset(buf, '\0', sizeof(buf));  
+		nbytes = RESTapi_get_line (source, buf, sizeof (buf));
+		if (nbytes == -1)
+		{
+			DEBUG_PC ("nbytes -1 ... then close the fd and eliminate associated client");	
+			RESTapi_stop(client, source, fd);
+			return FALSE;
+		}
+		//DEBUG_PC ("Header: %s", buf);	  
+		if (strncmp ((const char *)buf, "Content-Length:", 15) == 0)
+		{
+			//DEBUG_PC ("Header Content-Length Found");
+			gchar str[20];
+	  
+			gint i = 15, k = 0;  // "Content-Length:" We skip the first 16 characters to directly retrieve the length in bytes of the Body of Request
+			gchar contentLength[255];
+			memset (contentLength, '\0', sizeof (contentLength));			
+			while (buf[i] != '\r')
+			{
+				//DEBUG_PC ("%c", buf[i]);
+				str[k] = buf[i];
+				k++, i++;
+			}
+			str[k] = '\0';			
+			j = 0, i = 0;
+			while (ISspace(str[j]) && (j < strlen(str)))
+			{
+				j++;
+			}
+			while (j < strlen(str))
+			{
+				contentLength[i] = str[j];
+				i++; j++;
+			}
+			contentLength[i] = '\0';			
+			body_length = atoi (contentLength);
+			//DEBUG_PC ("Body length: %d (%s) in Bytes", body_length, contentLength);	      
+		}	  
+	}
+	//DEBUG_PC("Read Entire HTTP Header");
+	if (body_length == 0)
+	{
+		DEBUG_PC ("--- NO REST API Body length (length = %d) ---", body_length);
+		return TRUE;
+	}       
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// Processing Body of the Request
+	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	//DEBUG_PC ("REST API Request - Body -");
+	nbytes = read_channel (source, (guchar *)(client->ibuf->data + client->ibuf->putp), body_length);
+	if ((nbytes < 0) && (body_length > 0))
+	{
+		DEBUG_PC ("nbytes: %d; body_length: %d", nbytes, body_length);
+		exit (-1);
+	}
+	
+	client->ibuf->putp += nbytes;
+	client->ibuf->endp += nbytes;		
+	///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// Parsing the contents of the Request
+	///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// build the device list
+	deviceList = create_device_list();
+	// build the link list
+	linkList = create_link_list();
+	// Create the network connectivity service list
+	serviceList = create_service_list();
+	
+	// Process the json contents and store relevant information at Device, Link,
+	// and network connectivity service
+	gint ret = parsing_json_obj (client->ibuf->data, source);	
+	if (ret == -1) 	{
+		DEBUG_PC ("Something wrong with the JSON Objects ... ");		
+		RESTapi_stop(client, source, fd);
+		return FALSE;
+	}	
+	
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////////		
+	// Trigger the path computation	
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	//DEBUG_PC ("Triggering the computation");
+	struct compRouteOutputList_t *compRouteOutputList = create_route_list ();
+	gint httpCode = triggering_routeComp (compRouteOutputList, algId);	
+
+	// Send the response to the REST  API Client
+	if (httpCode != HTTP_RETURN_CODE_OK)
+	{            
+		DEBUG_PC ("HTTP CODE: %d -- NO OK", httpCode);
+		rapi_response (source, httpCode);
+	}
+	else
+	{
+		DEBUG_PC ("HTTP CODE: %d -- OK", httpCode);
+		rapi_response_ok (source, httpCode, compRouteOutputList);            
+	}
+	
+	// Release the variables		
+	g_free (compRouteOutputList);
+	g_free(linkList);
+	g_free(deviceList);
+	g_free(serviceList);
+	return TRUE;  
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Function used to accept a new connection and add the client to list of clients
+ * 
+ * 	@param source, GIOChannel
+ * 	@param cond, GIOCondition
+ * 	@param data, gpointer
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gboolean RESTapi_tcp_new_connection(GIOChannel *source, GIOCondition cond, gpointer data)
+{
+	DEBUG_PC (" ****** New TCP Connection (REST API) ******");
+	/** get size of client_addre structure */
+	struct sockaddr_in client_addr;
+	socklen_t client = sizeof(client_addr);
+	
+	if ((cond == G_IO_HUP) || (cond == G_IO_ERR) || (G_IO_NVAL))
+	{
+		//DEBUG_PC ("Something happening with the channel and fd ... cond: %d", cond);		
+		// Find the associated client (by the fd) and remove from PATH COMP client list. 
+		// Stop all the operations over that PATH COMP client bound channel
+		struct pathComp_client *pathComp_client = NULL;
+		gint fd = g_io_channel_unix_get_fd (source);
+		GList *found = g_list_find_custom (RESTapi_tcp_client_list, &fd, find_rl_client_by_fd);
+		if (found != NULL)
+		{
+			pathComp_client = (struct pathComp_client*)(found->data);
+			// remove client
+			RESTapi_client_close(pathComp_client);
+			// Stop operations over that channel
+			RESTapi_close_operations(source);
+			close (fd);
+			return FALSE;
+		}		
+	}
+	if (cond == G_IO_IN)
+	{
+		gint new = accept(g_io_channel_unix_get_fd(source), (struct sockaddr*)&client_addr, &client);
+		if (new < 0)
+		{
+			//DEBUG_PC ("Unable to accept new connection");
+			return FALSE;
+		}
+
+		/** new channel */
+		GIOChannel * new_channel = g_io_channel_unix_new (new);		
+		//DEBUG_PC ("TCP Connection (REST API) is UP; (socket: %d)", new);
+
+		/** create pathComp client */		
+		struct pathComp_client *new_client = RESTapi_client_create (new_channel, new);
+		
+		/** 
+		* force binary encoding with NULL
+		*/
+		GError *error = NULL;
+		if ( g_io_channel_set_encoding (new_channel, NULL, &error) != G_IO_STATUS_NORMAL)
+		{		
+			DEBUG_PC ("Error: %s", error->message);
+			exit (-1);
+		}
+		g_io_channel_set_close_on_unref (new_channel, TRUE);
+		// On unbuffered channels, it is safe to mix read
+		// & write calls from the new and old APIs.
+		g_io_channel_set_buffered (new_channel, FALSE);
+		if (g_io_channel_set_flags (new_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL )
+		{
+			DEBUG_PC ("Error: %s", error->message);
+			exit (-1);
+		}
+		//Adds the new channel into the main event loop.
+		g_io_add_watch (new_channel, G_IO_IN, RESTapi_activity, new_client);
+    }	
+	return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief enabling the reuse of the addr for the Server TCP
+ * 	
+ * 	@param sock
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void RESTapi_tcp_enable_reuseaddr (gint sock)
+{
+	gint tmp = 1;
+	if (sock < 0)
+	{
+		DEBUG_PC (" socket: %d !!!",sock);
+		exit (-1);
+	}
+	if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (gchar *)&tmp, sizeof (tmp)) == -1)
+	{
+		DEBUG_PC ("bad setsockopt ...");
+		exit (-1);
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_RESTapi.c
+ * 	@brief Main function for the creating / maintaining TCP session for the REST API
+ *
+ *  @ port 
+ * 
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void RESTapi_init(gint port)
+{     
+    DEBUG_PC ("REST API PORT (listening): %d", port);     
+	
+	// File Descriptor - FD - for the socket
+	gint s = socket (AF_INET, SOCK_STREAM, 0);
+	if (s == -1)
+	{
+		DEBUG_PC ("Socket creation: FAILED!!");
+		exit (-1);
+	}
+	DEBUG_PC (" CREATED TCP Connection [@fd: %d]", s);
+
+	// Re-bind
+	RESTapi_tcp_enable_reuseaddr(s);	
+	struct sockaddr_in addr;
+	memset (&addr, 0, sizeof (addr));
+	addr.sin_family       = AF_INET;
+	addr.sin_port         = htons ((u_short)port);
+	addr.sin_addr.s_addr  = INADDR_ANY;      
+
+	// Associate IP address and Port to the created socket
+	if (bind (s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
+	{
+		close (s);
+		DEBUG_PC ("Socket bind: FAILED!!");
+		exit (-1);
+	}
+	DEBUG_PC ("Bind to Fd: %d DONE!!", s);
+
+	/** Set up queue for incoming connections */
+	if (listen (s, 10) == -1)
+	{
+		close (s);
+		DEBUG_PC ("Socket listen: FAILED!!");
+		exit (-1);
+	}
+	
+	//DEBUG_PC ("Listen (up to 10) to Fd: %d Done", s);
+
+	/** Create NEW channel to handle the socket operations*/
+	GIOChannel *channel = g_io_channel_unix_new (s);
+	gsize buffersize = g_io_channel_get_buffer_size (channel);
+	//DEBUG_PC ("GIOChannel with Buffer Size: %d", (gint)buffersize);
+
+	gsize newBufferSize = MAX_GIO_CHANNEL_BUFFER_SIZE;
+	g_io_channel_set_buffer_size (channel, newBufferSize);
+	buffersize = g_io_channel_get_buffer_size (channel);
+
+	//DEBUG_PC ("GIOChannel with Buffer Size: %d", (gint)buffersize);
+	//DEBUG_PC ("Channel associated to fd: %d is created", s);
+	
+	// Adds the new channel into the main event loop.
+	g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, RESTapi_tcp_new_connection, NULL);
+	return;     
+}
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp_RESTapi.h b/src/pathcomp/backend/pathComp_RESTapi.h
new file mode 100644
index 0000000000000000000000000000000000000000..80e63da7c13c353592931be9d72f53e30a8aca5b
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_RESTapi.h
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+
+#ifndef _PATH_COMP_REST_API_H
+#define _PATH_COMP_REST_API_H
+
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+
+
+#define MAX_GIO_CHANNEL_BUFFER_SIZE     131072
+
+// HTTP RETURN CODES
+#define HTTP_RETURN_CODE_OK				200
+#define HTTP_RETURN_CODE_CREATED 		201
+#define HTTP_RETURN_CODE_BAD_REQUEST    400
+#define HTTP_RETURN_CODE_UNAUTHORIZED   401
+#define HTTP_RETURN_CODE_FORBIDDEN      403
+#define HTTP_RETURN_CODE_NOT_FOUND		404
+#define HTTP_RETURN_CODE_NOT_ACCEPTABLE	406
+
+// REST API METHODS (SIMPLY INT ENCODING)
+#define REST_API_METHOD_GET		1
+#define REST_API_METHOD_POST	2
+#define REST_API_METHOD_HTTP	3
+#define REST_API_METHOD_PUT		4
+
+#define MAXLENGTH				131072
+
+////////////////////////////////////////////////////
+// Client Struct for connecting to PATH COMP SERVER
+////////////////////////////////////////////////////
+// List of tcp clients connected to PATH COMP
+
+#define PATH_COMP_CLIENT_TYPE	1000
+struct pathComp_client
+{
+	/** IO Channel from client. */
+	GIOChannel *channel;
+
+	/** Input/output buffer to the client. */    
+	struct stream *obuf;
+	struct stream *ibuf;
+
+	gint fd; // file descriptor     
+    guint type;     
+};
+
+void RESTapi_init (gint);
+#endif
diff --git a/src/pathcomp/backend/pathComp_cjson.c b/src/pathcomp/backend/pathComp_cjson.c
new file mode 100644
index 0000000000000000000000000000000000000000..093d80a6d5a342c7719b231cf1aeb8dcc2e90956
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_cjson.c
@@ -0,0 +1,2732 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h> 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <strings.h>
+#include <time.h>
+#include <math.h>
+#include <float.h>
+#include <limits.h>
+#include <fcntl.h>
+
+
+#include "pathComp_log.h"
+#include "pathComp_cjson.h"
+
+/* define our own boolean type */
+#define true ((cJSON_bool)1)
+#define false ((cJSON_bool)0)
+
+typedef struct 
+{
+    const unsigned char *json;
+    size_t position;
+} error;
+
+static error global_error = { NULL, 0 };
+
+CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
+{
+    return (const char*) (global_error.json + global_error.position);
+}
+
+/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
+static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
+{
+    if ((string1 == NULL) || (string2 == NULL))
+    {
+        return 1;
+    }
+
+    if (string1 == string2)
+    {
+        return 0;
+    }
+
+    for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
+    {
+        if (*string1 == '\0')
+        {
+            return 0;
+        }
+    }
+
+    return tolower(*string1) - tolower(*string2);
+}
+
+typedef struct internal_hooks
+{
+    void *(*allocate)(size_t size);
+    void (*deallocate)(void *pointer);
+    void *(*reallocate)(void *pointer, size_t size);
+} internal_hooks;
+
+
+#define internal_malloc malloc
+#define internal_free free
+#define internal_realloc realloc
+
+
+static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
+
+static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
+{
+    size_t length = 0;
+    unsigned char *copy = NULL;
+
+    if (string == NULL)
+    {
+        return NULL;
+    }
+
+    length = strlen((const char*)string) + sizeof("");
+    copy = (unsigned char*)hooks->allocate(length);
+    if (copy == NULL)
+    {
+        return NULL;
+    }
+    memcpy(copy, string, length);
+
+    return copy;
+}
+
+CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
+{
+    if (hooks == NULL)
+    {
+        /* Reset hooks */
+        global_hooks.allocate = malloc;
+        global_hooks.deallocate = free;
+        global_hooks.reallocate = realloc;
+        return;
+    }
+
+    global_hooks.allocate = malloc;
+    if (hooks->malloc_fn != NULL)
+    {
+        global_hooks.allocate = hooks->malloc_fn;
+    }
+
+    global_hooks.deallocate = free;
+    if (hooks->free_fn != NULL)
+    {
+        global_hooks.deallocate = hooks->free_fn;
+    }
+
+    /* use realloc only if both free and malloc are used */
+    global_hooks.reallocate = NULL;
+    if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
+    {
+        global_hooks.reallocate = realloc;
+    }
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
+{
+    cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
+    if (node)
+    {
+        memset(node, '\0', sizeof(cJSON));
+    }
+
+    return node;
+}
+
+/* Delete a cJSON structure. */
+CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
+{
+    cJSON *next = NULL;
+    while (item != NULL)
+    {
+        next = item->next;
+        if (!(item->type & cJSON_IsReference) && (item->child != NULL))
+        {
+            cJSON_Delete(item->child);
+        }
+        if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
+        {
+            global_hooks.deallocate(item->valuestring);
+        }
+        if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
+        {
+            global_hooks.deallocate(item->string);
+        }
+        global_hooks.deallocate(item);
+        item = next;
+    }
+}
+
+/* get the decimal point character of the current locale */
+static unsigned char get_decimal_point(void)
+{
+  return '.';
+
+}
+
+typedef struct
+{
+    const unsigned char *content;
+    size_t length;
+    size_t offset;
+    size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
+    internal_hooks hooks;
+} parse_buffer;
+
+/* check if the given size is left to read in a given parse buffer (starting with 1) */
+#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
+/* check if the buffer can be accessed at the given index (starting with 0) */
+#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
+#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
+/* get a pointer to the buffer at the position */
+#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
+
+/* Parse the input text to generate a number, and populate the result into item. */
+static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
+{
+    double number = 0;
+    unsigned char *after_end = NULL;
+    unsigned char number_c_string[64];
+    unsigned char decimal_point = get_decimal_point();
+    size_t i = 0;
+
+    if ((input_buffer == NULL) || (input_buffer->content == NULL))
+    {
+        return false;
+    }
+
+    /* copy the number into a temporary buffer and replace '.' with the decimal point
+     * of the current locale (for strtod)
+     * This also takes care of '\0' not necessarily being available for marking the end of the input */
+    for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
+    {
+        switch (buffer_at_offset(input_buffer)[i])
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case '+':
+            case '-':
+            case 'e':
+            case 'E':
+                number_c_string[i] = buffer_at_offset(input_buffer)[i];
+                break;
+
+            case '.':
+                number_c_string[i] = decimal_point;
+                break;
+
+            default:
+                goto loop_end;
+        }
+    }
+loop_end:
+    number_c_string[i] = '\0';
+
+    number = strtod((const char*)number_c_string, (char**)&after_end);
+    if (number_c_string == after_end)
+    {
+        return false; /* parse_error */
+    }
+
+    item->valuedouble = number;
+
+    /* use saturation in case of overflow */
+    if (number >= INT_MAX)
+    {
+        item->valueint = INT_MAX;
+    }
+    else if (number <= INT_MIN)
+    {
+        item->valueint = INT_MIN;
+    }
+    else
+    {
+        item->valueint = (int)number;
+    }
+
+    item->type = cJSON_Number;
+
+    input_buffer->offset += (size_t)(after_end - number_c_string);
+    return true;
+}
+
+/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
+CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
+{
+    if (number >= INT_MAX)
+    {
+        object->valueint = INT_MAX;
+    }
+    else if (number <= INT_MIN)
+    {
+        object->valueint = INT_MIN;
+    }
+    else
+    {
+        object->valueint = (int)number;
+    }
+
+    return object->valuedouble = number;
+}
+
+typedef struct
+{
+    unsigned char *buffer;
+    size_t length;
+    size_t offset;
+    size_t depth; /* current nesting depth (for formatted printing) */
+    cJSON_bool noalloc;
+    cJSON_bool format; /* is this print a formatted print */
+    internal_hooks hooks;
+} printbuffer;
+
+/* realloc printbuffer if necessary to have at least "needed" bytes more */
+static unsigned char* ensure(printbuffer * const p, size_t needed)
+{
+    unsigned char *newbuffer = NULL;
+    size_t newsize = 0;
+
+    if ((p == NULL) || (p->buffer == NULL))
+    {
+        return NULL;
+    }
+
+    if ((p->length > 0) && (p->offset >= p->length))
+    {
+        /* make sure that offset is valid */
+        return NULL;
+    }
+
+    if (needed > INT_MAX)
+    {
+        /* sizes bigger than INT_MAX are currently not supported */
+        return NULL;
+    }
+
+    needed += p->offset + 1;
+    if (needed <= p->length)
+    {
+        return p->buffer + p->offset;
+    }
+
+    if (p->noalloc) {
+        return NULL;
+    }
+
+    /* calculate new buffer size */
+    if (needed > (INT_MAX / 2))
+    {
+        /* overflow of int, use INT_MAX if possible */
+        if (needed <= INT_MAX)
+        {
+            newsize = INT_MAX;
+        }
+        else
+        {
+            return NULL;
+        }
+    }
+    else
+    {
+        newsize = needed * 2;
+    }
+
+    if (p->hooks.reallocate != NULL)
+    {
+        /* reallocate with realloc if available */
+        newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
+        if (newbuffer == NULL)
+        {
+            p->hooks.deallocate(p->buffer);
+            p->length = 0;
+            p->buffer = NULL;
+
+            return NULL;
+        }
+    }
+    else
+    {
+        /* otherwise reallocate manually */
+        newbuffer = (unsigned char*)p->hooks.allocate(newsize);
+        if (!newbuffer)
+        {
+            p->hooks.deallocate(p->buffer);
+            p->length = 0;
+            p->buffer = NULL;
+
+            return NULL;
+        }
+        if (newbuffer)
+        {
+            memcpy(newbuffer, p->buffer, p->offset + 1);
+        }
+        p->hooks.deallocate(p->buffer);
+    }
+    p->length = newsize;
+    p->buffer = newbuffer;
+
+    return newbuffer + p->offset;
+}
+
+/* calculate the new length of the string in a printbuffer and update the offset */
+static void update_offset(printbuffer * const buffer)
+{
+    const unsigned char *buffer_pointer = NULL;
+    if ((buffer == NULL) || (buffer->buffer == NULL))
+    {
+        return;
+    }
+    buffer_pointer = buffer->buffer + buffer->offset;
+
+    buffer->offset += strlen((const char*)buffer_pointer);
+}
+
+/* Render the number nicely from the given item into a string. */
+static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output_pointer = NULL;
+    double d = item->valuedouble;
+    int length = 0;
+    size_t i = 0;
+    unsigned char number_buffer[26]; /* temporary buffer to print the number into */
+    unsigned char decimal_point = get_decimal_point();
+    double test;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* This checks for NaN and Infinity */
+    if ((d * 0) != 0)
+    {
+        length = sprintf((char*)number_buffer, "null");
+    }
+    else
+    {
+        /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
+        length = sprintf((char*)number_buffer, "%1.15g", d);
+
+        /* Check whether the original double can be recovered */
+        if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
+        {
+            /* If not, print with 17 decimal places of precision */
+            length = sprintf((char*)number_buffer, "%1.17g", d);
+        }
+    }
+
+    /* sprintf failed or buffer overrun occured */
+    if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
+    {
+        return false;
+    }
+
+    /* reserve appropriate space in the output */
+    output_pointer = ensure(output_buffer, (size_t)length);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+
+    /* copy the printed number to the output and replace locale
+     * dependent decimal point with '.' */
+    for (i = 0; i < ((size_t)length); i++)
+    {
+        if (number_buffer[i] == decimal_point)
+        {
+            output_pointer[i] = '.';
+            continue;
+        }
+
+        output_pointer[i] = number_buffer[i];
+    }
+    output_pointer[i] = '\0';
+
+    output_buffer->offset += (size_t)length;
+
+    return true;
+}
+
+/* parse 4 digit hexadecimal number */
+static unsigned parse_hex4(const unsigned char * const input)
+{
+    unsigned int h = 0;
+    size_t i = 0;
+
+    for (i = 0; i < 4; i++)
+    {
+        /* parse digit */
+        if ((input[i] >= '0') && (input[i] <= '9'))
+        {
+            h += (unsigned int) input[i] - '0';
+        }
+        else if ((input[i] >= 'A') && (input[i] <= 'F'))
+        {
+            h += (unsigned int) 10 + input[i] - 'A';
+        }
+        else if ((input[i] >= 'a') && (input[i] <= 'f'))
+        {
+            h += (unsigned int) 10 + input[i] - 'a';
+        }
+        else /* invalid */
+        {
+            return 0;
+        }
+
+        if (i < 3)
+        {
+            /* shift left to make place for the next nibble */
+            h = h << 4;
+        }
+    }
+
+    return h;
+}
+
+/* converts a UTF-16 literal to UTF-8
+ * A literal can be one or two sequences of the form \uXXXX */
+static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
+{
+    long unsigned int codepoint = 0;
+    unsigned int first_code = 0;
+    const unsigned char *first_sequence = input_pointer;
+    unsigned char utf8_length = 0;
+    unsigned char utf8_position = 0;
+    unsigned char sequence_length = 0;
+    unsigned char first_byte_mark = 0;
+
+    if ((input_end - first_sequence) < 6)
+    {
+        /* input ends unexpectedly */
+        goto fail;
+    }
+
+    /* get the first utf16 sequence */
+    first_code = parse_hex4(first_sequence + 2);
+
+    /* check that the code is valid */
+    if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
+    {
+        goto fail;
+    }
+
+    /* UTF16 surrogate pair */
+    if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
+    {
+        const unsigned char *second_sequence = first_sequence + 6;
+        unsigned int second_code = 0;
+        sequence_length = 12; /* \uXXXX\uXXXX */
+
+        if ((input_end - second_sequence) < 6)
+        {
+            /* input ends unexpectedly */
+            goto fail;
+        }
+
+        if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
+        {
+            /* missing second half of the surrogate pair */
+            goto fail;
+        }
+
+        /* get the second utf16 sequence */
+        second_code = parse_hex4(second_sequence + 2);
+        /* check that the code is valid */
+        if ((second_code < 0xDC00) || (second_code > 0xDFFF))
+        {
+            /* invalid second half of the surrogate pair */
+            goto fail;
+        }
+
+
+        /* calculate the unicode codepoint from the surrogate pair */
+        codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
+    }
+    else
+    {
+        sequence_length = 6; /* \uXXXX */
+        codepoint = first_code;
+    }
+
+    /* encode as UTF-8
+     * takes at maximum 4 bytes to encode:
+     * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+    if (codepoint < 0x80)
+    {
+        /* normal ascii, encoding 0xxxxxxx */
+        utf8_length = 1;
+    }
+    else if (codepoint < 0x800)
+    {
+        /* two bytes, encoding 110xxxxx 10xxxxxx */
+        utf8_length = 2;
+        first_byte_mark = 0xC0; /* 11000000 */
+    }
+    else if (codepoint < 0x10000)
+    {
+        /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
+        utf8_length = 3;
+        first_byte_mark = 0xE0; /* 11100000 */
+    }
+    else if (codepoint <= 0x10FFFF)
+    {
+        /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
+        utf8_length = 4;
+        first_byte_mark = 0xF0; /* 11110000 */
+    }
+    else
+    {
+        /* invalid unicode codepoint */
+        goto fail;
+    }
+
+    /* encode as utf8 */
+    for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
+    {
+        /* 10xxxxxx */
+        (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
+        codepoint >>= 6;
+    }
+    /* encode first byte */
+    if (utf8_length > 1)
+    {
+        (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
+    }
+    else
+    {
+        (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
+    }
+
+    *output_pointer += utf8_length;
+
+    return sequence_length;
+
+fail:
+    return 0;
+}
+
+/* Parse the input text into an unescaped cinput, and populate item. */
+static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
+{
+    const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
+    const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
+    unsigned char *output_pointer = NULL;
+    unsigned char *output = NULL;
+
+    /* not a string */
+    if (buffer_at_offset(input_buffer)[0] != '\"')
+    {
+        goto fail;
+    }
+
+    {
+        /* calculate approximate size of the output (overestimate) */
+        size_t allocation_length = 0;
+        size_t skipped_bytes = 0;
+        while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
+        {
+            /* is escape sequence */
+            if (input_end[0] == '\\')
+            {
+                if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
+                {
+                    /* prevent buffer overflow when last input character is a backslash */
+                    goto fail;
+                }
+                skipped_bytes++;
+                input_end++;
+            }
+            input_end++;
+        }
+        if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
+        {
+            goto fail; /* string ended unexpectedly */
+        }
+
+        /* This is at most how much we need for the output */
+        allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
+        output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
+        if (output == NULL)
+        {
+            goto fail; /* allocation failure */
+        }
+    }
+
+    output_pointer = output;
+    /* loop through the string literal */
+    while (input_pointer < input_end)
+    {
+        if (*input_pointer != '\\')
+        {
+            *output_pointer++ = *input_pointer++;
+        }
+        /* escape sequence */
+        else
+        {
+            unsigned char sequence_length = 2;
+            if ((input_end - input_pointer) < 1)
+            {
+                goto fail;
+            }
+
+            switch (input_pointer[1])
+            {
+                case 'b':
+                    *output_pointer++ = '\b';
+                    break;
+                case 'f':
+                    *output_pointer++ = '\f';
+                    break;
+                case 'n':
+                    *output_pointer++ = '\n';
+                    break;
+                case 'r':
+                    *output_pointer++ = '\r';
+                    break;
+                case 't':
+                    *output_pointer++ = '\t';
+                    break;
+                case '\"':
+                case '\\':
+                case '/':
+                    *output_pointer++ = input_pointer[1];
+                    break;
+
+                /* UTF-16 literal */
+                case 'u':
+                    sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
+                    if (sequence_length == 0)
+                    {
+                        /* failed to convert UTF16-literal to UTF-8 */
+                        goto fail;
+                    }
+                    break;
+
+                default:
+                    goto fail;
+            }
+            input_pointer += sequence_length;
+        }
+    }
+
+    /* zero terminate the output */
+    *output_pointer = '\0';
+
+    item->type = cJSON_String;
+    item->valuestring = (char*)output;
+
+    input_buffer->offset = (size_t) (input_end - input_buffer->content);
+    input_buffer->offset++;
+
+    return true;
+
+fail:
+    if (output != NULL)
+    {
+        input_buffer->hooks.deallocate(output);
+    }
+
+    if (input_pointer != NULL)
+    {
+        input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
+    }
+
+    return false;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
+{
+    const unsigned char *input_pointer = NULL;
+    unsigned char *output = NULL;
+    unsigned char *output_pointer = NULL;
+    size_t output_length = 0;
+    /* numbers of additional characters needed for escaping */
+    size_t escape_characters = 0;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* empty string */
+    if (input == NULL)
+    {
+        output = ensure(output_buffer, sizeof("\"\""));
+        if (output == NULL)
+        {
+            return false;
+        }
+        strcpy((char*)output, "\"\"");
+
+        return true;
+    }
+
+    /* set "flag" to 1 if something needs to be escaped */
+    for (input_pointer = input; *input_pointer; input_pointer++)
+    {
+        switch (*input_pointer)
+        {
+            case '\"':
+            case '\\':
+            case '\b':
+            case '\f':
+            case '\n':
+            case '\r':
+            case '\t':
+                /* one character escape sequence */
+                escape_characters++;
+                break;
+            default:
+                if (*input_pointer < 32)
+                {
+                    /* UTF-16 escape sequence uXXXX */
+                    escape_characters += 5;
+                }
+                break;
+        }
+    }
+    output_length = (size_t)(input_pointer - input) + escape_characters;
+
+    output = ensure(output_buffer, output_length + sizeof("\"\""));
+    if (output == NULL)
+    {
+        return false;
+    }
+
+    /* no characters have to be escaped */
+    if (escape_characters == 0)
+    {
+        output[0] = '\"';
+        memcpy(output + 1, input, output_length);
+        output[output_length + 1] = '\"';
+        output[output_length + 2] = '\0';
+
+        return true;
+    }
+
+    output[0] = '\"';
+    output_pointer = output + 1;
+    /* copy the string */
+    for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
+    {
+        if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
+        {
+            /* normal character, copy */
+            *output_pointer = *input_pointer;
+        }
+        else
+        {
+            /* character needs to be escaped */
+            *output_pointer++ = '\\';
+            switch (*input_pointer)
+            {
+                case '\\':
+                    *output_pointer = '\\';
+                    break;
+                case '\"':
+                    *output_pointer = '\"';
+                    break;
+                case '\b':
+                    *output_pointer = 'b';
+                    break;
+                case '\f':
+                    *output_pointer = 'f';
+                    break;
+                case '\n':
+                    *output_pointer = 'n';
+                    break;
+                case '\r':
+                    *output_pointer = 'r';
+                    break;
+                case '\t':
+                    *output_pointer = 't';
+                    break;
+                default:
+                    /* escape and print as unicode codepoint */
+                    sprintf((char*)output_pointer, "u%04x", *input_pointer);
+                    output_pointer += 4;
+                    break;
+            }
+        }
+    }
+    output[output_length + 1] = '\"';
+    output[output_length + 2] = '\0';
+
+    return true;
+}
+
+/* Invoke print_string_ptr (which is useful) on an item. */
+static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
+{
+    return print_string_ptr((unsigned char*)item->valuestring, p);
+}
+
+/* Predeclare these prototypes. */
+static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
+static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
+static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
+static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
+static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
+static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
+
+/* Utility to jump whitespace and cr/lf */
+static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
+{
+    if ((buffer == NULL) || (buffer->content == NULL))
+    {
+        return NULL;
+    }
+
+    while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
+    {
+       buffer->offset++;
+    }
+
+    if (buffer->offset == buffer->length)
+    {
+        buffer->offset--;
+    }
+
+    return buffer;
+}
+
+/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
+static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
+{
+    if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
+    {
+        return NULL;
+    }
+
+    if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
+    {
+        buffer->offset += 3;
+    }
+
+    return buffer;
+}
+
+/* Parse an object - create a new root, and populate. */
+CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
+{
+    parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
+    cJSON *item = NULL;
+
+    /* reset error position */
+    global_error.json = NULL;
+    global_error.position = 0;
+
+    if (value == NULL)
+    {
+        goto fail;
+    }
+
+    buffer.content = (const unsigned char*)value;
+    buffer.length = strlen((const char*)value) + sizeof("");
+    buffer.offset = 0;
+    buffer.hooks = global_hooks;
+
+    item = cJSON_New_Item(&global_hooks);
+    if (item == NULL) /* memory fail */
+    {
+        goto fail;
+    }
+
+    if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
+    {
+        /* parse failure. ep is set. */
+        goto fail;
+    }
+
+    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
+    if (require_null_terminated)
+    {
+        buffer_skip_whitespace(&buffer);
+        if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
+        {
+            goto fail;
+        }
+    }
+    if (return_parse_end)
+    {
+        *return_parse_end = (const char*)buffer_at_offset(&buffer);
+    }
+
+    return item;
+
+fail:
+    if (item != NULL)
+    {
+        cJSON_Delete(item);
+    }
+
+    if (value != NULL)
+    {
+        error local_error;
+        local_error.json = (const unsigned char*)value;
+        local_error.position = 0;
+
+        if (buffer.offset < buffer.length)
+        {
+            local_error.position = buffer.offset;
+        }
+        else if (buffer.length > 0)
+        {
+            local_error.position = buffer.length - 1;
+        }
+
+        if (return_parse_end != NULL)
+        {
+            *return_parse_end = (const char*)local_error.json + local_error.position;
+        }
+ 
+        global_error = local_error;
+    }
+
+    return NULL;
+}
+
+/* Default options for cJSON_Parse */
+CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
+{
+    return cJSON_ParseWithOpts(value, 0, 0);
+}
+
+#define cjson_min(a, b) ((a < b) ? a : b)
+
+static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
+{
+    printbuffer buffer[1];
+    unsigned char *printed = NULL;
+
+    memset(buffer, 0, sizeof(buffer));
+
+    /* create buffer */
+    buffer->buffer = (unsigned char*) hooks->allocate(256);
+    buffer->format = format;
+    buffer->hooks = *hooks;
+    if (buffer->buffer == NULL)
+    {
+        goto fail;
+    }
+
+    /* print the value */
+    if (!print_value(item, buffer))
+    {
+        goto fail;
+    }
+    update_offset(buffer);
+
+    /* check if reallocate is available */
+    if (hooks->reallocate != NULL)
+    {
+        printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->length);
+        buffer->buffer = NULL;
+        if (printed == NULL) {
+            goto fail;
+        }
+    }
+    else /* otherwise copy the JSON over to a new buffer */
+    {
+        printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
+        if (printed == NULL)
+        {
+            goto fail;
+        }
+        memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
+        printed[buffer->offset] = '\0'; /* just to be sure */
+
+        /* free the buffer */
+        hooks->deallocate(buffer->buffer);
+    }
+
+    return printed;
+
+fail:
+    if (buffer->buffer != NULL)
+    {
+        hooks->deallocate(buffer->buffer);
+    }
+
+    if (printed != NULL)
+    {
+        hooks->deallocate(printed);
+    }
+
+    return NULL;
+}
+
+/* Render a cJSON item/entity/structure to text. */
+CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
+{
+    return (char*)print(item, true, &global_hooks);
+}
+
+CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
+{
+    return (char*)print(item, false, &global_hooks);
+}
+
+CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
+{
+    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
+
+    if (prebuffer < 0)
+    {
+        return NULL;
+    }
+
+    p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
+    if (!p.buffer)
+    {
+        return NULL;
+    }
+
+    p.length = (size_t)prebuffer;
+    p.offset = 0;
+    p.noalloc = false;
+    p.format = fmt;
+    p.hooks = global_hooks;
+
+    if (!print_value(item, &p))
+    {
+        global_hooks.deallocate(p.buffer);
+        return NULL;
+    }
+
+    return (char*)p.buffer;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt)
+{
+    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
+
+    if ((len < 0) || (buf == NULL))
+    {
+        return false;
+    }
+
+    p.buffer = (unsigned char*)buf;
+    p.length = (size_t)len;
+    p.offset = 0;
+    p.noalloc = true;
+    p.format = fmt;
+    p.hooks = global_hooks;
+
+    return print_value(item, &p);
+}
+
+/* Parser core - when encountering text, process appropriately. */
+static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
+{
+    if ((input_buffer == NULL) || (input_buffer->content == NULL))
+    {
+        return false; /* no input */
+    }
+
+    /* parse the different types of values */
+    /* null */
+    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
+    {
+        item->type = cJSON_NULL;
+        input_buffer->offset += 4;
+        return true;
+    }
+    /* false */
+    if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
+    {
+        item->type = cJSON_False;
+        input_buffer->offset += 5;
+        return true;
+    }
+    /* true */
+    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
+    {
+        item->type = cJSON_True;
+        item->valueint = 1;
+        input_buffer->offset += 4;
+        return true;
+    }
+    /* string */
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
+    {
+        return parse_string(item, input_buffer);
+    }
+    /* number */
+    if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
+    {
+        return parse_number(item, input_buffer);
+    }
+    /* array */
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
+    {
+        return parse_array(item, input_buffer);
+    }
+    /* object */
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
+    {
+        return parse_object(item, input_buffer);
+    }
+
+    return false;
+}
+
+/* Render a value to text. */
+static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output = NULL;
+
+    if ((item == NULL) || (output_buffer == NULL))
+    {
+        return false;
+    }
+
+    switch ((item->type) & 0xFF)
+    {
+        case cJSON_NULL:
+            output = ensure(output_buffer, 5);
+            if (output == NULL)
+            {
+                return false;
+            }
+            strcpy((char*)output, "null");
+            return true;
+
+        case cJSON_False:
+            output = ensure(output_buffer, 6);
+            if (output == NULL)
+            {
+                return false;
+            }
+            strcpy((char*)output, "false");
+            return true;
+
+        case cJSON_True:
+            output = ensure(output_buffer, 5);
+            if (output == NULL)
+            {
+                return false;
+            }
+            strcpy((char*)output, "true");
+            return true;
+
+        case cJSON_Number:
+            return print_number(item, output_buffer);
+
+        case cJSON_Raw:
+        {
+            size_t raw_length = 0;
+            if (item->valuestring == NULL)
+            {
+                if (!output_buffer->noalloc)
+                {
+                    output_buffer->hooks.deallocate(output_buffer->buffer);
+                }
+                return false;
+            }
+
+            raw_length = strlen(item->valuestring) + sizeof("");
+            output = ensure(output_buffer, raw_length);
+            if (output == NULL)
+            {
+                return false;
+            }
+            memcpy(output, item->valuestring, raw_length);
+            return true;
+        }
+
+        case cJSON_String:
+            return print_string(item, output_buffer);
+
+        case cJSON_Array:
+            return print_array(item, output_buffer);
+
+        case cJSON_Object:
+            return print_object(item, output_buffer);
+
+        default:
+            return false;
+    }
+}
+
+/* Build an array from input text. */
+static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
+{
+    cJSON *head = NULL; /* head of the linked list */
+    cJSON *current_item = NULL;
+
+    if (input_buffer->depth >= CJSON_NESTING_LIMIT)
+    {
+        return false; /* to deeply nested */
+    }
+    input_buffer->depth++;
+
+    if (buffer_at_offset(input_buffer)[0] != '[')
+    {
+        /* not an array */
+        goto fail;
+    }
+
+    input_buffer->offset++;
+    buffer_skip_whitespace(input_buffer);
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
+    {
+        /* empty array */
+        goto success;
+    }
+
+    /* check if we skipped to the end of the buffer */
+    if (cannot_access_at_index(input_buffer, 0))
+    {
+        input_buffer->offset--;
+        goto fail;
+    }
+
+    /* step back to character in front of the first element */
+    input_buffer->offset--;
+    /* loop through the comma separated array elements */
+    do
+    {
+        /* allocate next item */
+        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
+        if (new_item == NULL)
+        {
+            goto fail; /* allocation failure */
+        }
+
+        /* attach next item to list */
+        if (head == NULL)
+        {
+            /* start the linked list */
+            current_item = head = new_item;
+        }
+        else
+        {
+            /* add to the end and advance */
+            current_item->next = new_item;
+            new_item->prev = current_item;
+            current_item = new_item;
+        }
+
+        /* parse next value */
+        input_buffer->offset++;
+        buffer_skip_whitespace(input_buffer);
+        if (!parse_value(current_item, input_buffer))
+        {
+            goto fail; /* failed to parse value */
+        }
+        buffer_skip_whitespace(input_buffer);
+    }
+    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
+
+    if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
+    {
+        goto fail; /* expected end of array */
+    }
+
+success:
+    input_buffer->depth--;
+
+    item->type = cJSON_Array;
+    item->child = head;
+
+    input_buffer->offset++;
+
+    return true;
+
+fail:
+    if (head != NULL)
+    {
+        cJSON_Delete(head);
+    }
+
+    return false;
+}
+
+/* Render an array to text */
+static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output_pointer = NULL;
+    size_t length = 0;
+    cJSON *current_element = item->child;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* Compose the output array. */
+    /* opening square bracket */
+    output_pointer = ensure(output_buffer, 1);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+
+    *output_pointer = '[';
+    output_buffer->offset++;
+    output_buffer->depth++;
+
+    while (current_element != NULL)
+    {
+        if (!print_value(current_element, output_buffer))
+        {
+            return false;
+        }
+        update_offset(output_buffer);
+        if (current_element->next)
+        {
+            length = (size_t) (output_buffer->format ? 2 : 1);
+            output_pointer = ensure(output_buffer, length + 1);
+            if (output_pointer == NULL)
+            {
+                return false;
+            }
+            *output_pointer++ = ',';
+            if(output_buffer->format)
+            {
+                *output_pointer++ = ' ';
+            }
+            *output_pointer = '\0';
+            output_buffer->offset += length;
+        }
+        current_element = current_element->next;
+    }
+
+    output_pointer = ensure(output_buffer, 2);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+    *output_pointer++ = ']';
+    *output_pointer = '\0';
+    output_buffer->depth--;
+
+    return true;
+}
+
+/* Build an object from the text. */
+static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
+{
+    cJSON *head = NULL; /* linked list head */
+    cJSON *current_item = NULL;
+
+    if (input_buffer->depth >= CJSON_NESTING_LIMIT)
+    {
+        return false; /* to deeply nested */
+    }
+    input_buffer->depth++;
+
+    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
+    {
+        goto fail; /* not an object */
+    }
+
+    input_buffer->offset++;
+    buffer_skip_whitespace(input_buffer);
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
+    {
+        goto success; /* empty object */
+    }
+
+    /* check if we skipped to the end of the buffer */
+    if (cannot_access_at_index(input_buffer, 0))
+    {
+        input_buffer->offset--;
+        goto fail;
+    }
+
+    /* step back to character in front of the first element */
+    input_buffer->offset--;
+    /* loop through the comma separated array elements */
+    do
+    {
+        /* allocate next item */
+        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
+        if (new_item == NULL)
+        {
+            goto fail; /* allocation failure */
+        }
+
+        /* attach next item to list */
+        if (head == NULL)
+        {
+            /* start the linked list */
+            current_item = head = new_item;
+        }
+        else
+        {
+            /* add to the end and advance */
+            current_item->next = new_item;
+            new_item->prev = current_item;
+            current_item = new_item;
+        }
+
+        /* parse the name of the child */
+        input_buffer->offset++;
+        buffer_skip_whitespace(input_buffer);
+        if (!parse_string(current_item, input_buffer))
+        {
+            goto fail; /* faile to parse name */
+        }
+        buffer_skip_whitespace(input_buffer);
+
+        /* swap valuestring and string, because we parsed the name */
+        current_item->string = current_item->valuestring;
+        current_item->valuestring = NULL;
+
+        if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
+        {
+            goto fail; /* invalid object */
+        }
+
+        /* parse the value */
+        input_buffer->offset++;
+        buffer_skip_whitespace(input_buffer);
+        if (!parse_value(current_item, input_buffer))
+        {
+            goto fail; /* failed to parse value */
+        }
+        buffer_skip_whitespace(input_buffer);
+    }
+    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
+
+    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
+    {
+        goto fail; /* expected end of object */
+    }
+
+success:
+    input_buffer->depth--;
+
+    item->type = cJSON_Object;
+    item->child = head;
+
+    input_buffer->offset++;
+    return true;
+
+fail:
+    if (head != NULL)
+    {
+        cJSON_Delete(head);
+    }
+
+    return false;
+}
+
+/* Render an object to text. */
+static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output_pointer = NULL;
+    size_t length = 0;
+    cJSON *current_item = item->child;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* Compose the output: */
+    length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
+    output_pointer = ensure(output_buffer, length + 1);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+
+    *output_pointer++ = '{';
+    output_buffer->depth++;
+    if (output_buffer->format)
+    {
+        *output_pointer++ = '\n';
+    }
+    output_buffer->offset += length;
+
+    while (current_item)
+    {
+        if (output_buffer->format)
+        {
+            size_t i;
+            output_pointer = ensure(output_buffer, output_buffer->depth);
+            if (output_pointer == NULL)
+            {
+                return false;
+            }
+            for (i = 0; i < output_buffer->depth; i++)
+            {
+                *output_pointer++ = '\t';
+            }
+            output_buffer->offset += output_buffer->depth;
+        }
+
+        /* print key */
+        if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
+        {
+            return false;
+        }
+        update_offset(output_buffer);
+
+        length = (size_t) (output_buffer->format ? 2 : 1);
+        output_pointer = ensure(output_buffer, length);
+        if (output_pointer == NULL)
+        {
+            return false;
+        }
+        *output_pointer++ = ':';
+        if (output_buffer->format)
+        {
+            *output_pointer++ = '\t';
+        }
+        output_buffer->offset += length;
+
+        /* print value */
+        if (!print_value(current_item, output_buffer))
+        {
+            return false;
+        }
+        update_offset(output_buffer);
+
+        /* print comma if not last */
+        length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
+        output_pointer = ensure(output_buffer, length + 1);
+        if (output_pointer == NULL)
+        {
+            return false;
+        }
+        if (current_item->next)
+        {
+            *output_pointer++ = ',';
+        }
+
+        if (output_buffer->format)
+        {
+            *output_pointer++ = '\n';
+        }
+        *output_pointer = '\0';
+        output_buffer->offset += length;
+
+        current_item = current_item->next;
+    }
+
+    output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+    if (output_buffer->format)
+    {
+        size_t i;
+        for (i = 0; i < (output_buffer->depth - 1); i++)
+        {
+            *output_pointer++ = '\t';
+        }
+    }
+    *output_pointer++ = '}';
+    *output_pointer = '\0';
+    output_buffer->depth--;
+
+    return true;
+}
+
+/* Get Array size/item / object item. */
+CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
+{
+    cJSON *child = NULL;
+    size_t size = 0;
+
+    if (array == NULL)
+    {
+        return 0;
+    }
+
+    child = array->child;
+
+    while(child != NULL)
+    {
+        size++;
+        child = child->next;
+    }
+
+    /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
+
+    return (int)size;
+}
+
+static cJSON* get_array_item(const cJSON *array, size_t index)
+{
+    cJSON *current_child = NULL;
+
+    if (array == NULL)
+    {
+        return NULL;
+    }
+
+    current_child = array->child;
+    while ((current_child != NULL) && (index > 0))
+    {
+        index--;
+        current_child = current_child->next;
+    }
+
+    return current_child;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
+{
+    if (index < 0)
+    {
+        return NULL;
+    }
+
+    return get_array_item(array, (size_t)index);
+}
+
+static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
+{
+    cJSON *current_element = NULL;
+
+    if ((object == NULL) || (name == NULL))
+    {
+        return NULL;
+    }
+
+    current_element = object->child;
+    if (case_sensitive)
+    {
+        while ((current_element != NULL) && (strcmp(name, current_element->string) != 0))
+        {
+            current_element = current_element->next;
+        }
+    }
+    else
+    {
+        while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
+        {
+            current_element = current_element->next;
+        }
+    }
+
+    return current_element;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
+{
+    return get_object_item(object, string, false);
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
+{
+    return get_object_item(object, string, true);
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
+{
+    return cJSON_GetObjectItem(object, string) ? 1 : 0;
+}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev, cJSON *item)
+{
+    prev->next = item;
+    item->prev = prev;
+}
+
+/* Utility for handling references. */
+static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
+{
+    cJSON *reference = NULL;
+    if (item == NULL)
+    {
+        return NULL;
+    }
+
+    reference = cJSON_New_Item(hooks);
+    if (reference == NULL)
+    {
+        return NULL;
+    }
+
+    memcpy(reference, item, sizeof(cJSON));
+    reference->string = NULL;
+    reference->type |= cJSON_IsReference;
+    reference->next = reference->prev = NULL;
+    return reference;
+}
+
+/* Add item to array/object. */
+CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
+{
+    cJSON *child = NULL;
+
+    if ((item == NULL) || (array == NULL))
+    {
+        return;
+    }
+
+    child = array->child;
+
+    if (child == NULL)
+    {
+        /* list is empty, start new one */
+        array->child = item;
+    }
+    else
+    {
+        /* append to the end */
+        while (child->next)
+        {
+            child = child->next;
+        }
+        suffix_object(child, item);
+    }
+}
+
+CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
+{
+    if (item == NULL)
+    {
+        return;
+    }
+
+    /* call cJSON_AddItemToObjectCS for code reuse */
+    cJSON_AddItemToObjectCS(object, (char*)cJSON_strdup((const unsigned char*)string, &global_hooks), item);
+    /* remove cJSON_StringIsConst flag */
+    item->type &= ~cJSON_StringIsConst;
+}
+
+#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
+    #pragma GCC diagnostic push
+#endif
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+
+/* Add an item to an object with constant string as key */
+CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
+{
+    if ((item == NULL) || (string == NULL))
+    {
+        return;
+    }
+    if (!(item->type & cJSON_StringIsConst) && item->string)
+    {
+        global_hooks.deallocate(item->string);
+    }
+    item->string = (char*)string;
+    item->type |= cJSON_StringIsConst;
+    cJSON_AddItemToArray(object, item);
+}
+#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
+    #pragma GCC diagnostic pop
+#endif
+
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
+{
+    if (array == NULL)
+    {
+        return;
+    }
+
+    cJSON_AddItemToArray(array, create_reference(item, &global_hooks));
+}
+
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
+{
+    if ((object == NULL) || (string == NULL))
+    {
+        return;
+    }
+
+    cJSON_AddItemToObject(object, string, create_reference(item, &global_hooks));
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
+{
+    if ((parent == NULL) || (item == NULL))
+    {
+        return NULL;
+    }
+
+    if (item->prev != NULL)
+    {
+        /* not the first element */
+        item->prev->next = item->next;
+    }
+    if (item->next != NULL)
+    {
+        /* not the last element */
+        item->next->prev = item->prev;
+    }
+
+    if (item == parent->child)
+    {
+        /* first element */
+        parent->child = item->next;
+    }
+    /* make sure the detached item doesn't point anywhere anymore */
+    item->prev = NULL;
+    item->next = NULL;
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
+{
+    if (which < 0)
+    {
+        return NULL;
+    }
+
+    return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
+}
+
+CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
+{
+    cJSON_Delete(cJSON_DetachItemFromArray(array, which));
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
+{
+    cJSON *to_detach = cJSON_GetObjectItem(object, string);
+
+    return cJSON_DetachItemViaPointer(object, to_detach);
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
+{
+    cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
+
+    return cJSON_DetachItemViaPointer(object, to_detach);
+}
+
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
+{
+    cJSON_Delete(cJSON_DetachItemFromObject(object, string));
+}
+
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
+{
+    cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
+}
+
+/* Replace array/object items with new ones. */
+CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
+{
+    cJSON *after_inserted = NULL;
+
+    if (which < 0)
+    {
+        return;
+    }
+
+    after_inserted = get_array_item(array, (size_t)which);
+    if (after_inserted == NULL)
+    {
+        cJSON_AddItemToArray(array, newitem);
+        return;
+    }
+
+    newitem->next = after_inserted;
+    newitem->prev = after_inserted->prev;
+    after_inserted->prev = newitem;
+    if (after_inserted == array->child)
+    {
+        array->child = newitem;
+    }
+    else
+    {
+        newitem->prev->next = newitem;
+    }
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
+{
+    if ((parent == NULL) || (replacement == NULL) || (item == NULL))
+    {
+        return false;
+    }
+
+    if (replacement == item)
+    {
+        return true;
+    }
+
+    replacement->next = item->next;
+    replacement->prev = item->prev;
+
+    if (replacement->next != NULL)
+    {
+        replacement->next->prev = replacement;
+    }
+    if (replacement->prev != NULL)
+    {
+        replacement->prev->next = replacement;
+    }
+    if (parent->child == item)
+    {
+        parent->child = replacement;
+    }
+
+    item->next = NULL;
+    item->prev = NULL;
+    cJSON_Delete(item);
+
+    return true;
+}
+
+CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
+{
+    if (which < 0)
+    {
+        return;
+    }
+
+    cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
+}
+
+static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
+{
+    if ((replacement == NULL) || (string == NULL))
+    {
+        return false;
+    }
+
+    /* replace the name in the replacement */
+    if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
+    {
+        cJSON_free(replacement->string);
+    }
+    replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
+    replacement->type &= ~cJSON_StringIsConst;
+
+    cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
+
+    return true;
+}
+
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
+{
+    replace_item_in_object(object, string, newitem, false);
+}
+
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
+{
+    replace_item_in_object(object, string, newitem, true);
+}
+
+/* Create basic types: */
+CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_NULL;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_True;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_False;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = b ? cJSON_True : cJSON_False;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_Number;
+        item->valuedouble = num;
+
+        /* use saturation in case of overflow */
+        if (num >= INT_MAX)
+        {
+            item->valueint = INT_MAX;
+        }
+        else if (num <= INT_MIN)
+        {
+            item->valueint = INT_MIN;
+        }
+        else
+        {
+            item->valueint = (int)num;
+        }
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_String;
+        item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
+        if(!item->valuestring)
+        {
+            cJSON_Delete(item);
+            return NULL;
+        }
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_Raw;
+        item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
+        if(!item->valuestring)
+        {
+            cJSON_Delete(item);
+            return NULL;
+        }
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type=cJSON_Array;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if (item)
+    {
+        item->type = cJSON_Object;
+    }
+
+    return item;
+}
+
+/* Create Arrays: */
+CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (numbers == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+    for(i = 0; a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateNumber(numbers[i]);
+        if (!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p, n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (numbers == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+
+    for(i = 0; a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateNumber((double)numbers[i]);
+        if(!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p, n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (numbers == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+
+    for(i = 0;a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateNumber(numbers[i]);
+        if(!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p, n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (strings == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+
+    for (i = 0; a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateString(strings[i]);
+        if(!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p,n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+/* Duplication */
+CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
+{
+    cJSON *newitem = NULL;
+    cJSON *child = NULL;
+    cJSON *next = NULL;
+    cJSON *newchild = NULL;
+
+    /* Bail on bad ptr */
+    if (!item)
+    {
+        goto fail;
+    }
+    /* Create new item */
+    newitem = cJSON_New_Item(&global_hooks);
+    if (!newitem)
+    {
+        goto fail;
+    }
+    /* Copy over all vars */
+    newitem->type = item->type & (~cJSON_IsReference);
+    newitem->valueint = item->valueint;
+    newitem->valuedouble = item->valuedouble;
+    if (item->valuestring)
+    {
+        newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
+        if (!newitem->valuestring)
+        {
+            goto fail;
+        }
+    }
+    if (item->string)
+    {
+        newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
+        if (!newitem->string)
+        {
+            goto fail;
+        }
+    }
+    /* If non-recursive, then we're done! */
+    if (!recurse)
+    {
+        return newitem;
+    }
+    /* Walk the ->next chain for the child. */
+    child = item->child;
+    while (child != NULL)
+    {
+        newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
+        if (!newchild)
+        {
+            goto fail;
+        }
+        if (next != NULL)
+        {
+            /* If newitem->child already set, then crosswire ->prev and ->next and move on */
+            next->next = newchild;
+            newchild->prev = next;
+            next = newchild;
+        }
+        else
+        {
+            /* Set newitem->child and move to it */
+            newitem->child = newchild;
+            next = newchild;
+        }
+        child = child->next;
+    }
+
+    return newitem;
+
+fail:
+    if (newitem != NULL)
+    {
+        cJSON_Delete(newitem);
+    }
+
+    return NULL;
+}
+
+CJSON_PUBLIC(void) cJSON_Minify(char *json)
+{
+    unsigned char *into = (unsigned char*)json;
+
+    if (json == NULL)
+    {
+        return;
+    }
+
+    while (*json)
+    {
+        if (*json == ' ')
+        {
+            json++;
+        }
+        else if (*json == '\t')
+        {
+            /* Whitespace characters. */
+            json++;
+        }
+        else if (*json == '\r')
+        {
+            json++;
+        }
+        else if (*json=='\n')
+        {
+            json++;
+        }
+        else if ((*json == '/') && (json[1] == '/'))
+        {
+            /* double-slash comments, to end of line. */
+            while (*json && (*json != '\n'))
+            {
+                json++;
+            }
+        }
+        else if ((*json == '/') && (json[1] == '*'))
+        {
+            /* multiline comments. */
+            while (*json && !((*json == '*') && (json[1] == '/')))
+            {
+                json++;
+            }
+            json += 2;
+        }
+        else if (*json == '\"')
+        {
+            /* string literals, which are \" sensitive. */
+            *into++ = (unsigned char)*json++;
+            while (*json && (*json != '\"'))
+            {
+                if (*json == '\\')
+                {
+                    *into++ = (unsigned char)*json++;
+                }
+                *into++ = (unsigned char)*json++;
+            }
+            *into++ = (unsigned char)*json++;
+        }
+        else
+        {
+            /* All other characters. */
+            *into++ = (unsigned char)*json++;
+        }
+    }
+
+    /* and null-terminate. */
+    *into = '\0';
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Invalid;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_False;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xff) == cJSON_True;
+}
+
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & (cJSON_True | cJSON_False)) != 0;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_NULL;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file transponder_agent/agent_cjson.c
+ * 	@brief Check if the item is a number (double)
+ * 
+ * 	@param item
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2017
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Number;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file transponder_agent/agent_cjson.c
+ * 	@brief Check if the item is a string
+ * 
+ * 	@param item
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2017
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_String;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Array;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Object;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Raw;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
+{
+    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
+    {
+        return false;
+    }
+
+    /* check if type is valid */
+    switch (a->type & 0xFF)
+    {
+        case cJSON_False:
+        case cJSON_True:
+        case cJSON_NULL:
+        case cJSON_Number:
+        case cJSON_String:
+        case cJSON_Raw:
+        case cJSON_Array:
+        case cJSON_Object:
+            break;
+
+        default:
+            return false;
+    }
+
+    /* identical objects are equal */
+    if (a == b)
+    {
+        return true;
+    }
+
+    switch (a->type & 0xFF)
+    {
+        /* in these cases and equal type is enough */
+        case cJSON_False:
+        case cJSON_True:
+        case cJSON_NULL:
+            return true;
+
+        case cJSON_Number:
+            if (a->valuedouble == b->valuedouble)
+            {
+                return true;
+            }
+            return false;
+
+        case cJSON_String:
+        case cJSON_Raw:
+            if ((a->valuestring == NULL) || (b->valuestring == NULL))
+            {
+                return false;
+            }
+            if (strcmp(a->valuestring, b->valuestring) == 0)
+            {
+                return true;
+            }
+
+            return false;
+
+        case cJSON_Array:
+        {
+            cJSON *a_element = a->child;
+            cJSON *b_element = b->child;
+
+            for (; (a_element != NULL) && (b_element != NULL);)
+            {
+                if (!cJSON_Compare(a_element, b_element, case_sensitive))
+                {
+                    return false;
+                }
+
+                a_element = a_element->next;
+                b_element = b_element->next;
+            }
+
+            /* one of the arrays is longer than the other */
+            if (a_element != b_element) {
+                return false;
+            }
+
+            return true;
+        }
+
+        case cJSON_Object:
+        {
+            cJSON *a_element = NULL;
+            cJSON *b_element = NULL;
+            cJSON_ArrayForEach(a_element, a)
+            {
+                /* TODO This has O(n^2) runtime, which is horrible! */
+                b_element = get_object_item(b, a_element->string, case_sensitive);
+                if (b_element == NULL)
+                {
+                    return false;
+                }
+
+                if (!cJSON_Compare(a_element, b_element, case_sensitive))
+                {
+                    return false;
+                }
+            }
+
+            /* doing this twice, once on a and b to prevent true comparison if a subset of b
+             * TODO: Do this the proper way, this is just a fix for now */
+            cJSON_ArrayForEach(b_element, b)
+            {
+                a_element = get_object_item(a, b_element->string, case_sensitive);
+                if (a_element == NULL)
+                {
+                    return false;
+                }
+
+                if (!cJSON_Compare(b_element, a_element, case_sensitive))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        default:
+            return false;
+    }
+}
+
+CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
+{
+    return global_hooks.allocate(size);
+}
+
+CJSON_PUBLIC(void) cJSON_free(void *object)
+{
+    global_hooks.deallocate(object);
+}
diff --git a/src/pathcomp/backend/pathComp_cjson.h b/src/pathcomp/backend/pathComp_cjson.h
new file mode 100644
index 0000000000000000000000000000000000000000..47c2830ef3cb1bf6c72c5e3897a066035936b247
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_cjson.h
@@ -0,0 +1,214 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PATHCOMP_CJSON_H
+#define _PATHCOMP_CJSON_H
+
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+
+#include <stddef.h>
+
+/* project version */
+#define CJSON_VERSION_MAJOR 1
+#define CJSON_VERSION_MINOR 6
+#define CJSON_VERSION_PATCH 0
+
+
+/* cJSON Types: */
+#define cJSON_Invalid (0)
+#define cJSON_False  (1 << 0)
+#define cJSON_True   (1 << 1)
+#define cJSON_NULL   (1 << 2)
+#define cJSON_Number (1 << 3)
+#define cJSON_String (1 << 4)
+#define cJSON_Array  (1 << 5)
+#define cJSON_Object (1 << 6)
+#define cJSON_Raw    (1 << 7) /* raw json */
+
+#define cJSON_IsReference 256
+#define cJSON_StringIsConst 512
+
+#define CJSON_PUBLIC(type) type
+
+#define CJSON_NESTING_LIMIT 1000
+
+/* The cJSON structure: */
+typedef struct cJSON
+{
+    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+    struct cJSON *next;
+    struct cJSON *prev;
+    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+    struct cJSON *child;
+
+    /* The type of the item, as above. */
+    int type;
+
+    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
+    char *valuestring;
+    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
+    int valueint;
+    /* The item's number, if type==cJSON_Number */
+    double valuedouble;
+
+    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+    char *string;
+} cJSON;
+
+typedef struct cJSON_Hooks
+{
+      void *(*malloc_fn)(size_t sz);
+      void (*free_fn)(void *ptr);
+} cJSON_Hooks;
+
+typedef int cJSON_bool;
+
+/* returns the version of cJSON as a string */
+CJSON_PUBLIC(const char*) cJSON_Version(void);
+
+/* Supply malloc, realloc and free functions to cJSON */
+CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
+
+/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
+CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
+/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
+/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
+CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
+
+/* Render a cJSON entity to text for transfer/storage. */
+CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. */
+CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
+/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
+CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
+/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
+/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
+CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
+/* Delete a cJSON entity and all subentities. */
+CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
+
+/* Returns the number of items in an array (or object). */
+CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
+/* Get item "string" from object. Case insensitive. */
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
+CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
+
+/* These functions check the type of an item */
+CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
+
+/* These calls create a cJSON item of the appropriate type. */
+CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
+CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
+CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
+/* raw json */
+CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
+CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
+
+/* These utilities create an Array of count items. */
+CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
+CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
+CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
+CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
+
+/* Append item to the specified array/object. */
+CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
+CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
+/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
+ * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
+ * writing to `item->string` */
+CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
+
+/* Update array items. */
+CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
+CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
+CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
+
+/* Duplicate a cJSON item */
+CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
+/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
+need to be released. With recurse!=0, it will duplicate any children connected to the item.
+The item->next and ->prev pointers are always zero on return from Duplicate. */
+/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
+ * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
+CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
+
+
+CJSON_PUBLIC(void) cJSON_Minify(char *json);
+
+/* Macros for creating things quickly. */
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
+
+/* When assigning an integer value, it needs to be propagated to valuedouble too. */
+#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
+/* helper for the cJSON_SetNumberValue macro */
+CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
+#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
+
+/* Macro for iterating over an array or object */
+#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
+
+/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
+CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
+CJSON_PUBLIC(void) cJSON_free(void *object);
+
+
+#endif
diff --git a/src/pathcomp/backend/pathComp_ksp.c b/src/pathcomp/backend/pathComp_ksp.c
new file mode 100644
index 0000000000000000000000000000000000000000..85c5e750506d56fb7c5511f6c675598adea49ee8
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_ksp.c
@@ -0,0 +1,545 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h> 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <strings.h>
+#include <time.h>
+#include <math.h>
+#include <fcntl.h>
+
+#include "pathComp_log.h"
+#include "pathComp_tools.h"
+#include "pathComp_ksp.h"
+
+// Global Variables
+struct map_nodes_t *mapNodes;
+struct graph_t *graph;
+struct contextSet_t* contextSet;
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_ksp.c
+ * 	@brief Dijkstra algorithm
+ *
+ *  @param srcMapIndex
+ *  @param dstMapIndex
+ *	@param g
+ *	@param s
+ *	@param SN
+ *	@param RP
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void sp_comp(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct service_t* s,
+	struct nodes_t* SN, struct compRouteOutputItem_t* RP) {
+	g_assert(s);
+	g_assert(g);
+
+	// Set params into mapNodes related to the source nodes of the request
+	mapNodes->map[srcMapIndex].distance = 0.0;
+	mapNodes->map[srcMapIndex].latency = 0.0;
+	mapNodes->map[srcMapIndex].avaiBandwidth = 0.0;
+
+	// Initialize the set Q and S
+	GList* S = NULL, * Q = NULL;
+	gint indexVertice = -1;
+
+	//  Add the source into the Q
+	struct nodeItem_t* nodeItem = g_malloc0(sizeof(struct nodeItem_t));
+	if (nodeItem == NULL) {
+		DEBUG_PC("memory allocation failed\n");
+		exit(-1);
+	}
+	// initialize some nodeItem attributes
+	nodeItem->distance = 0.0;
+	nodeItem->latency = 0.0;
+	duplicate_node_id(&mapNodes->map[srcMapIndex].verticeId, &nodeItem->node);
+	Q = g_list_insert_sorted(Q, nodeItem, sort_by_distance);
+
+	// Check whether there is spurNode (SN) and rootPath (RP)
+	if (SN != NULL && RP != NULL) {
+		struct routeElement_t* re;
+		for (gint j = 0; j < RP->numRouteElements; j++)
+		{
+			// Get the source and target Nodes of the routeElement within the rootPath
+			re = &RP->routeElement[j];
+			DEBUG_PC ("root Link: aNodeId: %s (%s) --> zNodeiId: %s (%s)", re->aNodeId.nodeId, re->aEndPointId, re->zNodeId.nodeId, re->zEndPointId);
+
+			// if ingress of the root link (aNodeId) is the spurNode, then stops
+			if (compare_node_id(&re->aNodeId, SN) == 0)
+			{
+				DEBUG_PC ("root Link: aNodeId: %s and spurNode: %s -- stop exploring the rootPath (RP)", re->aNodeId.nodeId, SN->nodeId);
+				break;
+			}
+			// Extract from Q
+			GList* listnode = g_list_first(Q);
+			struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data);
+			Q = g_list_remove(Q, node);
+
+			//DEBUG_RL_RA ("Exploring node %s", node->node.nodeId);
+			indexVertice = graph_vertice_lookup(node->node.nodeId, g);
+			g_assert(indexVertice >= 0);
+
+			// Get the indexTargetedVertice
+			gint indexTVertice = -1;
+			indexTVertice = graph_targeted_vertice_lookup(indexVertice, re->zNodeId.nodeId, g);
+			gint done = check_link(node, indexVertice, indexTVertice, g, s, &S, &Q, mapNodes);
+			(void)done;
+
+			// Add to the S list
+			S = g_list_append(S, node);    
+		}
+
+		// Check that the first node in Q set is SpurNode, otherwise something went wrong ...
+		if (compare_node_id(&re->aNodeId, SN) != 0) {
+			//DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId);
+			g_list_free_full(S, g_free);
+			g_list_free_full(Q, g_free);
+			return;
+		}
+	}		
+	while (g_list_length(Q) > 0) {
+		//Extract from Q set
+		GList* listnode = g_list_first(Q);
+		struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data);
+		Q = g_list_remove(Q, node);
+		DEBUG_PC ("Q length: %d", g_list_length (Q)); 
+		DEBUG_PC ("DeviceId: %s", node->node.nodeId);            
+
+		// visit all the links from u within the graph
+		indexVertice = graph_vertice_lookup(node->node.nodeId, g);
+		g_assert(indexVertice >= 0);
+
+		// Check the targeted vertices from u
+		for (gint i = 0; i < g->vertices[indexVertice].numTargetedVertices; i++)  {                
+			gint done = check_link(node, indexVertice, i, g, s, &S, &Q, mapNodes);
+			(void)done;
+		}
+		// Add node into the S Set
+		S = g_list_append(S, node);
+		//DEBUG_PC ("S length: %d", g_list_length (S));              
+	}
+	g_list_free_full(S, g_free);
+	g_list_free_full(Q, g_free);
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_ksp.c
+ * 	@brief KSP computation using Dijkstra algorithm
+ *
+ *  @param pred
+ *  @param g
+ *	@param s
+  *	@param SN
+ *	@param RP
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, 
+				struct nodes_t *SN, struct compRouteOutputItem_t *RP) {
+	g_assert(pred);
+	g_assert(g);
+	g_assert(s);
+
+	// Check the both ingress src and dst endpoints are in the graph
+	gint srcMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[0].device_uuid, mapNodes);
+	if (srcMapIndex == -1) {
+		DEBUG_PC("ingress DeviceId: %s NOT in the graph", s->service_endpoints_id[0].device_uuid);
+		return -1;
+	}
+
+	gint dstMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes);
+	if (dstMapIndex == -1) {
+		DEBUG_PC("egress DeviceId: %s NOT in the graph", s->service_endpoints_id[1].device_uuid);
+		return -1;
+	}
+
+	// Compute the shortest path route
+	sp_comp(srcMapIndex, dstMapIndex, g, s, SN, RP);
+		
+	// Check that a feasible solution in term of latency and bandwidth is found
+	gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes);
+	struct map_t* dest_map = &mapNodes->map[map_dstIndex];
+	if (!(dest_map->distance < INFINITY_COST)) 	{
+		DEBUG_PC("destination: %s NOT reachable", s->service_endpoints_id[1].device_uuid);
+		return -1;
+	}
+
+	DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth);
+	// Check that the computed available bandwidth is larger than 0.0
+	if (dest_map->avaiBandwidth <= (gfloat)0.0) {
+		DEBUG_PC("dst: %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid);
+		return -1;
+	}
+	DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid);
+	// Handle predecessors
+	build_predecessors(pred, s, mapNodes);
+	return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_ksp.c
+ * 	@brief K-CSPF algorithm execution (YEN algorithm)
+ *
+ *  @param s
+ *  @param path
+ *  @param g
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_t *g) {
+	g_assert(s);
+	g_assert(path);
+	g_assert(g);
+
+	// create map of devices/nodes to handle the path computation using the context
+	mapNodes = create_map_node();
+	build_map_node(mapNodes, g);
+
+	// predecessors to store the computed path    
+	struct pred_t* predecessors = create_predecessors();
+
+	struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]);
+	struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]);
+
+	// Compute the 1st KSP path
+	gint done = ksp_comp (predecessors, g, s, NULL, NULL);
+	if (done == -1) {
+		DEBUG_PC("NO PATH FOUND %s[%s] ---> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid);
+		comp_route_connection_issue_handler(path, s);
+		g_free(mapNodes); g_free(predecessors);
+		return;
+	}
+
+	// Construct the path from the computed predecessors
+	struct compRouteOutputItem_t* p = create_path_item();
+	//print_predecessors(predecessors);
+	build_path(p, predecessors, s);
+	//DEBUG_PC ("Path is constructed");
+
+	gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes);
+	struct map_t* dst_map = &mapNodes->map[indexDest];
+	// Get the delay and cost
+	memcpy(&p->cost, &dst_map->distance, sizeof(gdouble));
+	memcpy(&p->availCap, &dst_map->avaiBandwidth, sizeof(dst_map->avaiBandwidth));
+	memcpy(&p->delay, &dst_map->latency, sizeof(mapNodes->map[indexDest].latency));
+	DEBUG_PC ("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay);
+	print_path(p);
+
+	// If 1st SP satisfies the requirements from the req, STOP
+	gboolean feasibleRoute = check_computed_path_feasability(s, p);
+	if (feasibleRoute == TRUE) 	{
+		DEBUG_PC("1st K-CSPF FEASIBLE, STOP!");
+		print_path (p);		
+		path->numPaths++;
+
+		// Copy the serviceId
+		DEBUG_PC("contextId: %s", s->serviceId.contextId);
+		copy_service_id(&path->serviceId, &s->serviceId);
+
+		// copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services)
+		for (gint i = 0; i < s->num_service_endpoints_id; i++) {
+			struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]);
+			struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]);
+			copy_service_endpoint_id(oEp, iEp);
+		}
+		path->num_service_endpoints_id = s->num_service_endpoints_id;
+
+		// Copy the computed path
+		struct path_t* targetedPath = &(path->paths[path->numPaths - 1]);
+		duplicate_path_t(p, targetedPath);		
+		print_path_t (targetedPath);
+		g_free(predecessors);
+		g_free(p);
+		g_free(mapNodes);
+		return;
+	}
+
+	DEBUG_PC("1st CSPF COMPUTATION IS NOT FEASIBLE --> TRIGGER K COMPUTATIONS");
+	// Create A and B sets of paths to handle the YEN algorithm
+	struct path_set_t* A = create_path_set();
+	struct path_set_t* B = create_path_set();
+
+	// Add the previously computed path into A->paths[0]	
+	duplicate_path(p, &A->paths[0]);
+
+	A->numPaths++;
+	g_free(predecessors);
+	g_free(p);
+	for (gint k = 1; k < MAX_KSP_VALUE; k++) {
+		DEBUG_PC("------------ kth (%d) ---------------------", k);
+		struct compRouteOutputItem_t* p = create_path_item();
+		duplicate_path(&A->paths[k - 1], p);
+		// The spurNode ranges from near-end node of the first link to the near-end of the last link forming the kth path
+		gint i = 0;
+		struct compRouteOutputItem_t* rootPath = create_path_item();
+		for (i = 0; i < p->numRouteElements; i++) {
+			struct nodes_t* spurNode = create_node();
+			struct nodes_t* nextSpurNode = create_node();
+			struct routeElement_t* re = &(p->routeElement[i]);
+			// Create predecessors to store the computed path
+			struct pred_t* predecessors = create_predecessors();
+			// Clear previous mapNodes, i.e. create it again
+			g_free(mapNodes);
+			mapNodes = create_map_node();
+			build_map_node(mapNodes, g);
+			struct nodes_t* n = &re->aNodeId;
+			duplicate_node_id(n, spurNode);
+			n = &re->zNodeId;
+			duplicate_node_id(n, nextSpurNode);
+			DEBUG_PC("spurNode: %s --> nextSpurNode: %s", spurNode->nodeId, nextSpurNode->nodeId);
+
+			// rootPath contains a set of links of A[k-1] from the source Node till the SpurNode -> NextSpurNode
+			// Example: A[k-1] = {L1, L2, L3, L4}, i.e. " Node_a -- L1 --> Node_b -- L2 --> Node_c -- L3 --> Node_d -- L4 --> Node_e "
+			// E.g., for the ith iteration if the spurNode = Node_c and NextSpurNode = Node_d; then rootPath = {L1, L2, L3}			
+			add_routeElement_path_back(re, rootPath);
+			DEBUG_PC("rootPath:");
+			print_path(rootPath);
+
+			// For all existing and computed paths p in A check if from the source to the NextSpurNode
+			// the set of links matches with those contained in the rootPath
+			// If YES, remove from the auxiliary graph the next link in p from NextSpurNode
+			// Otherwise do nothing 
+			struct graph_t* gAux = create_graph();
+			// Baseline graph 
+			//build_graph (gAux);
+			duplicate_graph(g, gAux);
+			// Modified graph
+			modify_targeted_graph(gAux, A, rootPath, spurNode);
+
+			// Trigger the computation of the path from src to dst constrained to traverse all the links from src 
+			// to spurNode contained into rootPath over the resulting graph			
+			if (ksp_comp(predecessors, gAux, s, spurNode, rootPath) == -1) {
+				DEBUG_PC("FAILED SP from %s via spurNode: %s to %s", iEp->device_uuid, spurNode->nodeId, eEp->device_uuid);
+				g_free(nextSpurNode);
+				g_free(spurNode);
+				g_free(gAux);
+				g_free(predecessors);
+				continue;
+			}
+			DEBUG_PC("SUCCESFUL SP from %s via spurNode: %s to %s", iEp->device_uuid, spurNode->nodeId, eEp->device_uuid);
+			// Create the node list from the predecessors
+			struct compRouteOutputItem_t* newKpath = create_path_item();
+			build_path(newKpath, predecessors, s);
+			DEBUG_PC("new K (for k: %d) Path is built", k);
+			gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes);
+			struct map_t* dst_map = &mapNodes->map[indexDest];
+
+			memcpy(&newKpath->cost, &dst_map->distance, sizeof(gdouble));
+			memcpy(&newKpath->availCap, &dst_map->avaiBandwidth, sizeof(dst_map->avaiBandwidth));
+			memcpy(&newKpath->delay, &dst_map->latency, sizeof(mapNodes->map[indexDest].latency));			
+			DEBUG_PC("New PATH (@ kth: %d) ADDED to B[%d] - {Path Cost: %f, e2e latency: %f, bw: %f ", k, B->numPaths, newKpath->cost, newKpath->delay, newKpath->availCap);
+			// Add the computed kth SP to the heap B
+			duplicate_path(newKpath, &B->paths[B->numPaths]);
+			B->numPaths++;
+			DEBUG_PC("Number of B paths: %d", B->numPaths);
+
+			g_free(newKpath);
+			g_free(nextSpurNode);
+			g_free(spurNode);
+			g_free(gAux);
+			g_free(predecessors);
+		}
+
+		// If B is empty then stops
+		if (B->numPaths == 0) {
+			DEBUG_PC("B does not have any path ... the stops kth computation");
+			break;
+		}
+
+		// Sort the potential paths contained in B by cost and latency and available bandwidth
+		sort_path_set(B);
+
+		// Add the lowest path into A[k]		
+		DEBUG_PC("-------------------------------------------------------------");
+		DEBUG_PC("To Add SP from B[0] to A[%d] --- Path Cost: %f, e2e Latency: %f", A->numPaths, B->paths[0].cost, B->paths[0].delay);
+		duplicate_path(&B->paths[0], &A->paths[A->numPaths]);
+		A->numPaths++;
+		DEBUG_PC("A Set size: %d", A->numPaths);
+		DEBUG_PC("-------------------------------------------------------------");
+
+		// Remove/pòp front element from the path set B (i.e. remove B[0])
+		pop_front_path_set(B);
+		DEBUG_PC("B Set Size: %d", B->numPaths);
+	}
+
+	// Copy the serviceId
+	copy_service_id(&path->serviceId, &s->serviceId);
+	// copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services)
+	for (gint m = 0; m < s->num_service_endpoints_id; m++) {
+		struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[m]);
+		struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[m]);
+		copy_service_endpoint_id(oEp, iEp);
+	}
+
+	for (gint ksp = 1; ksp < A->numPaths; ksp++){
+		if (ksp >= MAX_KSP_VALUE) {
+			DEBUG_PC("Number Requested paths (%d) REACHED - STOP", ksp);
+			break;
+		}
+		gdouble feasibleRoute = check_computed_path_feasability(s, &A->paths[ksp]);
+		if (feasibleRoute == TRUE) {
+			DEBUG_PC("A[k-th%d] available: %f, pathCost: %f; latency: %f", ksp, A->paths[ksp].availCap, A->paths[ksp].cost, A->paths[ksp].delay);
+			struct compRouteOutputItem_t* pathaux = &A->paths[ksp];
+			path->numPaths++;
+			struct path_t* targetedPath = &path->paths[path->numPaths - 1];
+			duplicate_path_t(pathaux, targetedPath);		
+			print_path_t(targetedPath);
+			remove_path_set(A);
+			remove_path_set(B);
+			return;
+		}
+	}
+	remove_path_set(A);
+	remove_path_set(B);
+	// No paths found --> Issue	
+	DEBUG_PC("K-SP failed!!!");
+	comp_route_connection_issue_handler(path, s);
+
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_ksp.c
+ * 	@brief Iterates over the list of network connectivity service requests 
+ * to compute their own paths fulfilling the constraints
+ *
+ *  @param outputList
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) {
+	g_assert(outputList);
+	g_assert(contextSet);
+	g_assert(serviceList);
+
+	DEBUG_PC("----- Starting the KSP Computation ------");
+
+	// Iterate over the list of requested network connectivity services
+	for (gint i = 0; i < serviceList->numServiceList; i++) {
+		struct service_t* service = &(serviceList->services[i]);
+
+		DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId);
+		struct compRouteOutput_t* pathService = &(outputList->compRouteConnection[i]);
+		// check endpoints of the service are different (PE devices/nodes are different)
+		if (same_src_dst_pe_nodeid(service) == 0) {
+			DEBUG_PC("PEs are the same... no path computation");
+			comp_route_connection_issue_handler(pathService, service);
+			outputList->numCompRouteConnList++;
+			continue;
+		}
+		// get the graph associated to the contextId in the contextSet, if no then error
+		struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId);
+		if (g == NULL) {
+			DEBUG_PC("The targeted contextId is NOT in the ContextSet ... then NO graph");
+			comp_route_connection_issue_handler(pathService, service);
+			outputList->numCompRouteConnList++;
+			continue;
+		}
+		alg_comp(service, pathService, g);
+		outputList->numCompRouteConnList++;
+
+		// for each network connectivity service, a single computed path (out of the KCSP) is retuned
+		// If path is found, then the selected resources must be pre-assigned into the context information
+		if (pathService->noPathIssue == NO_PATH_CONS_ISSUE)
+		{
+			continue;
+		}
+		struct path_t* path = &(pathService->paths[pathService->numPaths - 1]);
+		allocate_graph_resources(path, service, g);
+		allocate_graph_reverse_resources(path, service, g);
+		print_graph(g);
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_ksp.c
+ * 	@brief handles the path computation triggering k-cspf algorithm
+ *
+ *  @param compRouteOutput
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList)
+{   	
+	g_assert(routeConnList);
+	gint numSuccesPathComp = 0, numPathCompIntents = 0;
+	
+	DEBUG_PC ("================================================================");
+	DEBUG_PC ("===========================   KSP   =========================");
+	DEBUG_PC ("================================================================");
+	// increase the number of Path Comp. Intents
+	numPathCompIntents++;
+	gint http_code = HTTP_CODE_OK;
+
+	// timestamp t0
+	struct timeval t0;
+	gettimeofday(&t0, NULL);	
+	
+	// Allocate memory for the context
+	contextSet = create_contextSet();
+	// Build up the contextSet (>= 1)
+	build_contextSet(contextSet);
+	print_contextSet(contextSet);	
+#if 1	
+	//Triggering the path computation for each specific network connectivity service
+	ksp_alg_execution_services (routeConnList);
+
+	// -- timestamp t1
+	struct timeval t1, delta;
+	gettimeofday(&t1, NULL);
+	delta.tv_sec = t1.tv_sec - t0.tv_sec;
+	delta.tv_usec = t1.tv_usec - t0.tv_usec;
+	delta = tv_adjust(delta);
+
+	numSuccesPathComp++;
+	update_stats_path_comp(routeConnList, delta, numSuccesPathComp, numPathCompIntents);
+	print_path_connection_list(routeConnList);
+#endif
+
+	g_free(contextSet);
+	return http_code;
+}
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp_ksp.h b/src/pathcomp/backend/pathComp_ksp.h
new file mode 100644
index 0000000000000000000000000000000000000000..d542c493143ffe2187164c19711425aca7b7fcdf
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_ksp.h
@@ -0,0 +1,31 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+
+#ifndef  _PATHCOMP_KSP_H
+#define  _PATHCOMP_KSP_H
+
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+
+// Prototype of external declaration of functions
+gint pathComp_ksp_alg (struct compRouteOutputList_t *);
+
+#endif
diff --git a/src/pathcomp/backend/pathComp_log.c b/src/pathcomp/backend/pathComp_log.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f66e5a1edc8538dffcb20d89cbe2028a08d64d0
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_log.c
@@ -0,0 +1,189 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h> 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+#include "pathComp_log.h"
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+ /**
+  * 	@file pathComp_log.c
+  * 	@brief Create a new variable
+  *
+  * 	@param size
+  *
+  *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+  *	@date 2022
+  */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct stream* stream_new(size_t size)
+{
+	/** check values */
+	g_assert(size > 0);
+
+	struct stream* stream = g_malloc0(sizeof(struct stream));
+	if (stream == NULL)
+	{
+		DEBUG_PC("%s memory failed\n", __FUNCTION__);
+		exit(-1);
+	}
+
+	stream->data = g_malloc0(size);
+	if (stream->data == NULL)
+	{
+		DEBUG_PC("%s memory failed\n", __FUNCTION__);
+		exit(-1);
+	}
+	stream->size = size;
+
+	/** check values */
+	g_assert(stream != NULL);
+
+	return stream;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_log.c
+ * 	@brief removal of a stream variable
+ *
+ * 	@param stream
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+  /////////////////////////////////////////////////////////////////////////////////////////
+void stream_free(struct stream* s)
+{
+	/** check values */
+	g_assert(s != NULL);
+
+	//DEBUG_PC("s: %p, s->data: %p", s, s->data);
+	/** free data */
+	g_free(s->data);
+	g_free(s);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_log.c
+ * 	@brief reset the contents of the stream
+ *
+ * 	@param stream
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void stream_reset(struct stream* s)
+{
+	/** check values */
+	g_assert(s != NULL);
+	g_assert(s->putp >= 0);
+	g_assert(s->endp >= 0);
+	g_assert(s->endp >= 0);
+
+	/** reset */
+	s->putp = 0;
+	s->endp = 0;
+	s->getp = 0;
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_log.c
+ * 	@brief Read over a TCP channel the contents
+ *
+ * 	@param channel
+ *  @param ptr
+ *  @nbytes
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+gint read_channel(GIOChannel* channel, guchar* ptr, gint nbytes)
+{
+	/** check values */
+	g_assert(channel != NULL);
+	g_assert(ptr != NULL);
+	g_assert(nbytes >= 0);
+
+	/** get the file descriptor */
+	gint fd;
+	fd = g_io_channel_unix_get_fd(channel);
+
+	gsize nread;
+	gint nleft;
+	GError* error = NULL;
+	GIOStatus status;
+
+	nleft = nbytes;
+
+	// Set blocking
+	int flags = fcntl(fd, F_GETFL, 0);
+	fcntl(fd, F_SETFL, flags &= ~O_NONBLOCK);
+
+	while (nleft > 0)
+	{
+		status = g_io_channel_read_chars(channel, (void*)ptr, nleft, &nread, &error);
+		if (status != G_IO_STATUS_NORMAL)
+		{
+			//DEBUG_PC ("gio-test: ...from %d: G_IO_STATUS_%s\n", fd,
+			//		  (status == G_IO_STATUS_AGAIN ? "AGAIN" :
+			//		  (status == G_IO_STATUS_EOF ? "EOF" :
+			//		  (status == G_IO_STATUS_ERROR ? "ERROR" : "???"))));
+			return -1;
+		}
+		if (nread < 0)
+		{
+			return (nread);
+		}
+		else
+		{
+			if (nread == 0)
+				break;
+		}
+
+		nleft -= nread;
+		ptr += nread;
+	}
+
+	/** check values */
+	g_assert(channel != NULL);
+	g_assert(ptr != NULL);
+	g_assert(nleft >= 0);
+	g_assert(nbytes >= 0);
+
+	return nbytes - nleft;
+}
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp_log.h b/src/pathcomp/backend/pathComp_log.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9a14209cb2790fed45c93f0b134251f6a990b16
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_log.h
@@ -0,0 +1,89 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PATHCOMP_LOG_H
+#define _PATHCOMP_LOG_H
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+
+#define MAXLENGTH 		131072
+
+ /** Stream buffer. */
+struct stream
+{
+	struct stream *next;
+
+	guchar* data;
+
+	/** Put pointer. */
+	gulong putp;
+
+	/** Get pointer. */
+	gulong getp;
+
+	/** End of pointer. */
+	gulong endp;
+
+	/** Data size. */
+	gulong size;
+};
+
+extern FILE* logfile;
+
+//////////////////////////////////////////////////////
+// For debugging
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+// For debugging
+//////////////////////////////////////////////////////
+#define __SHORT_FILENAME__ \
+        (strrchr(__FILE__,'/') \
+         ? strrchr(__FILE__,'/')+1 \
+         : __FILE__ \
+        )
+
+#define DEBUG_PC(format,...) \
+{			       \
+	if (logfile != NULL)   \
+	{		       \
+		g_fprintf(logfile,"%s:%1.5d  %30s "format"\n",\
+                                __SHORT_FILENAME__,     		\
+                                __LINE__, __FUNCTION__, ##__VA_ARGS__);	        \
+		fflush(logfile);					        \
+	}								        \
+	else 								        \
+	{	                                                                \
+		g_fprintf(stdout,"%s:%1.5d  %30s "format"\n", \
+                                __SHORT_FILENAME__,     		\
+                                __LINE__, __FUNCTION__, ##__VA_ARGS__);	        \
+		fflush(stdout);					                \
+	}                                                                       \
+} 
+
+//// Prototypes ////////
+struct stream* stream_new(size_t);
+void stream_free(struct stream*);
+void stream_reset(struct stream*);
+
+gint read_channel(GIOChannel*, guchar*, gint);
+
+#endif
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp_sp.c b/src/pathcomp/backend/pathComp_sp.c
new file mode 100644
index 0000000000000000000000000000000000000000..735027fafcde1a6dfb9ce82faf3ba71a0bee56e5
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_sp.c
@@ -0,0 +1,362 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h> 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <strings.h>
+#include <time.h>
+#include <math.h>
+#include <fcntl.h>
+
+#include "pathComp_log.h"
+#include "pathComp_tools.h"
+#include "pathComp_sp.h"
+
+// Global Variables
+struct map_nodes_t* mapNodes;
+struct graph_t* graph;
+struct contextSet_t* contextSet;
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_sp.c
+ * 	@brief Excecution Dijkstra algorithm
+ *
+ *  @param srcMapIndex
+ *  @param dstMapIndex
+ *	@param g
+ *	@param s
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct service_t* s) {
+	g_assert(s);
+	g_assert(g);
+
+	// Set params into mapNodes related to the source nodes of the request
+	mapNodes->map[srcMapIndex].distance = 0.0;
+	mapNodes->map[srcMapIndex].latency = 0.0;
+	mapNodes->map[srcMapIndex].avaiBandwidth = 0.0;
+
+	// Initialize the set Q and S
+	GList* S = NULL, *Q = NULL;
+	gint indexVertice = -1;
+
+	//  Add the source into the Q
+	struct nodeItem_t* nodeItem = g_malloc0(sizeof(struct nodeItem_t));
+	if (nodeItem == NULL) {
+		DEBUG_PC("memory allocation failed\n");
+		exit(-1);
+	}
+	// initialize some nodeItem attributes
+	nodeItem->distance = 0.0;
+	nodeItem->latency = 0.0;
+	duplicate_node_id(&mapNodes->map[srcMapIndex].verticeId, &nodeItem->node);
+	Q = g_list_insert_sorted(Q, nodeItem, sort_by_distance);
+
+	while (g_list_length(Q) > 0) {
+		//Extract from Q set
+		GList* listnode = g_list_first(Q);
+		struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data);
+		Q = g_list_remove(Q, node);
+		DEBUG_PC("Q length: %d", g_list_length(Q));
+		DEBUG_PC("DeviceId: %s", node->node.nodeId);
+
+		// visit all the links from u within the graph
+		indexVertice = graph_vertice_lookup(node->node.nodeId, g);
+		g_assert(indexVertice >= 0);
+
+		// Check the targeted vertices from u
+		for (gint i = 0; i < g->vertices[indexVertice].numTargetedVertices; i++) {
+			gint done = check_link(node, indexVertice, i, g, s, &S, &Q, mapNodes);
+			(void)done;
+		}
+		// Add node into the S Set
+		S = g_list_append(S, node);
+		//DEBUG_PC ("S length: %d", g_list_length (S));              
+	}
+	g_list_free_full(S, g_free);
+	g_list_free_full(Q, g_free);
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_sp.c
+ * 	@brief handling the Dijkstra algorithm
+ *
+ *  @param pred
+ *  @param g
+ *	@param s
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s) {
+	g_assert(pred);
+	g_assert(g);
+	g_assert(s);
+
+	// Check the both ingress src and dst endpoints are in the graph
+	gint srcMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[0].device_uuid, mapNodes);
+	if (srcMapIndex == -1) {
+		DEBUG_PC("ingress DeviceId: %s NOT in the graph", s->service_endpoints_id[0].device_uuid);
+		return -1;
+	}
+
+	gint dstMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes);
+	if (dstMapIndex == -1) {
+		DEBUG_PC("egress DeviceId: %s NOT in the graph", s->service_endpoints_id[1].device_uuid);
+		return -1;
+	}
+
+	// Compute the shortest path
+	dijkstra(srcMapIndex, dstMapIndex, g, s);
+
+	// Check that a feasible solution in term of latency and bandwidth is found
+	gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes);
+	struct map_t* dest_map = &mapNodes->map[map_dstIndex];
+	if (!(dest_map->distance < INFINITY_COST)) {
+		DEBUG_PC("destination: %s NOT reachable", s->service_endpoints_id[1].device_uuid);
+		return -1;
+	}
+
+	DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth);
+	// Check that the computed available bandwidth is larger than 0.0
+	if (dest_map->avaiBandwidth <= (gfloat)0.0) {
+		DEBUG_PC("dst: %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid);
+		return -1;
+	}
+	DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid);
+	// Handle predecessors
+	build_predecessors(pred, s, mapNodes);
+
+	return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_sp.c
+ * 	@brief CSPF algorithm execution
+ *
+ *  @param s
+ *  @param path
+ *  @param g
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g) {
+	g_assert(s);
+	g_assert(path);
+	g_assert(g);
+
+	// create map of devices / nodes to handle the path computation using the context
+	mapNodes = create_map_node();
+	build_map_node(mapNodes, g);
+
+	// predecessors to store the computed path    
+	struct pred_t* predecessors = create_predecessors();
+
+	struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]);
+	struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]);
+
+	// SP computation
+	gint done = computation(predecessors, g, s);
+	if (done == -1) {
+		DEBUG_PC("NO PATH FOUND %s[%s] ---> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid);
+		comp_route_connection_issue_handler(path, s);
+		g_free(mapNodes); g_free(predecessors);
+		return;
+	}
+
+	// Construct the path from the computed predecessors
+	struct compRouteOutputItem_t* p = create_path_item();
+	//print_predecessors(predecessors);
+	build_path(p, predecessors, s);
+	//DEBUG_PC ("Path is constructed");
+
+	gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes);
+	struct map_t* dst_map = &mapNodes->map[indexDest];
+	// Get the delay and cost
+	memcpy(&p->cost, &dst_map->distance, sizeof(gdouble));
+	memcpy(&p->availCap, &dst_map->avaiBandwidth, sizeof(dst_map->avaiBandwidth));
+	memcpy(&p->delay, &dst_map->latency, sizeof(mapNodes->map[indexDest].latency));
+	DEBUG_PC("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay);
+	print_path(p);
+
+	gboolean feasibleRoute = check_computed_path_feasability(s, p);
+	if (feasibleRoute == TRUE) {
+		DEBUG_PC("SP Feasible");
+		print_path(p);
+		path->numPaths++;
+
+		// Copy the serviceId
+		DEBUG_PC("contextId: %s", s->serviceId.contextId);
+		copy_service_id(&path->serviceId, &s->serviceId);
+
+		// copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services)
+		for (gint i = 0; i < s->num_service_endpoints_id; i++) {
+			struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]);
+			struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]);
+			copy_service_endpoint_id(oEp, iEp);
+		}
+		path->num_service_endpoints_id = s->num_service_endpoints_id;
+
+		// Copy the computed path
+		struct path_t* targetedPath = &(path->paths[path->numPaths - 1]);
+		duplicate_path_t(p, targetedPath);
+		print_path_t(targetedPath);
+		g_free(predecessors);
+		g_free(p);
+		g_free(mapNodes);
+		return;
+	}
+
+	DEBUG_PC("SP FAILED!!!");
+	comp_route_connection_issue_handler(path, s);
+
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_sp.c
+ * 	@brief Iterates over the list of network connectivity service requests
+ * to compute their own paths fulfilling the constraints
+ *
+ *  @param outputList
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+void sp_execution_services(struct compRouteOutputList_t* oPathList)
+{
+	g_assert(oPathList);
+	g_assert(contextSet);
+	g_assert(serviceList);
+
+	DEBUG_PC("----- Starting the SP Computation ------");
+
+	for (gint i = 0; i < serviceList->numServiceList; i++) {
+		 struct service_t* service = &(serviceList->services[i]);
+
+		 DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId);
+		 struct compRouteOutput_t* pathService = &(oPathList->compRouteConnection[i]);
+		 // check endpoints of the service are different (PE devices/nodes are different)
+		 if (same_src_dst_pe_nodeid(service) == 0) {
+			 DEBUG_PC("PEs are the same... no path computation");
+			 comp_route_connection_issue_handler(pathService, service);
+			 oPathList->numCompRouteConnList++;
+			 continue;
+		 }
+
+		 // get the graph associated to the contextId in the contextSet, if no then error
+		 struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId);
+		 if (g == NULL) {
+			 DEBUG_PC("The targeted contextId is NOT in the ContextSet ... then NO graph");
+			 comp_route_connection_issue_handler(pathService, service);
+			 oPathList->numCompRouteConnList++;
+			 continue;
+		 }
+
+		 computation_shortest_path(service, pathService, g);
+		 oPathList->numCompRouteConnList++;
+
+		 // for each network connectivity service, a single computed path (out of the KCSP) is retuned
+		 // If path is found, then the selected resources must be pre-assigned into the context information
+		 if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) {
+			 continue;
+		 }
+		 struct path_t* path = &(pathService->paths[pathService->numPaths - 1]);
+		 allocate_graph_resources(path, service, g);
+		 allocate_graph_reverse_resources(path, service, g);
+		 print_graph(g);
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_sp.c
+ * 	@brief handles the path computation for the constrained shortest path
+ *
+ *  @param compRouteOutput
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList)
+{
+	g_assert(routeConnList);
+
+	gint numSuccesPathComp = 0, numPathCompIntents = 0;
+
+	DEBUG_PC("================================================================");
+	DEBUG_PC("===========================   SP   =========================");
+	DEBUG_PC("================================================================");
+	// increase the number of Path Comp. Intents
+	numPathCompIntents++;
+	gint http_code = HTTP_CODE_OK;
+
+	// timestamp t0
+	struct timeval t0;
+	gettimeofday(&t0, NULL);
+
+	// Allocate memory for the context
+	contextSet = create_contextSet();
+	// Build up the contextSet (>= 1)
+	build_contextSet(contextSet);
+	print_contextSet(contextSet);
+#if 1	
+	//Triggering the path computation for each specific network connectivity service
+	sp_execution_services(routeConnList);
+
+	// -- timestamp t1
+	struct timeval t1, delta;
+	gettimeofday(&t1, NULL);
+	delta.tv_sec = t1.tv_sec - t0.tv_sec;
+	delta.tv_usec = t1.tv_usec - t0.tv_usec;
+	delta = tv_adjust(delta);
+
+	numSuccesPathComp++;
+	update_stats_path_comp(routeConnList, delta, numSuccesPathComp, numPathCompIntents);
+	print_path_connection_list(routeConnList);
+#endif
+
+	g_free(contextSet);
+	return http_code;
+}
+
+
diff --git a/src/pathcomp/backend/pathComp_sp.h b/src/pathcomp/backend/pathComp_sp.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd0807fea36a69e0456e7e839265505c37ac9f86
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_sp.h
@@ -0,0 +1,31 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+
+#ifndef  _PATHCOMP_SP_H
+#define  _PATHCOMP_SP_H
+
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+
+ // Prototype of external declaration of functions
+gint pathComp_sp_alg(struct compRouteOutputList_t*);
+
+#endif
\ No newline at end of file
diff --git a/src/pathcomp/backend/pathComp_tools.c b/src/pathcomp/backend/pathComp_tools.c
new file mode 100644
index 0000000000000000000000000000000000000000..84cf63994405a07ff6c7fbb1da3fc667b0f0500f
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_tools.c
@@ -0,0 +1,2772 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnològic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Martínez (ricardo.martinez@cttc.es)
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h> 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <strings.h>
+#include <time.h>
+#include <math.h>
+#include <fcntl.h>
+#include <uuid/uuid.h>
+#include <errno.h>
+
+#include "pathComp_log.h"
+#include "pathComp.h"
+#include "pathComp_tools.h"
+
+gint numPathCompIntents = 0;  // number of events triggering the path computation
+//gint numSuccesPathComp = 0; // number of events resulting in succesfully path computations fulfilling the constraints
+struct timeval total_path_comp_time;
+gdouble totalReqBw = 0.0;
+gdouble totalServedBw = 0.0;
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function for time processing
+ *
+ * 	@param a
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+struct timeval tv_adjust (struct timeval a) {
+	while (a.tv_usec >= 1000000) {
+		a.tv_usec -= 1000000;
+		a.tv_sec++;
+	}
+
+	while (a.tv_usec < 0) {
+		a.tv_usec += 1000000;
+		a.tv_sec--;
+	}
+	return a;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief friendly function to copy safely strings
+ *
+ * 	@param dst
+ *  @param src
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_string(gchar* dst, gchar* src) {
+	g_assert(dst);
+	g_assert(src);
+	strcpy(dst, src);
+	dst[strlen(dst)] = '\0';
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to print the computed the path
+ *
+ *	@param path
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void print_path (struct compRouteOutputItem_t *p) {
+	g_assert(p);
+	
+	DEBUG_PC ("=========== COMPUTED PATH =======================");
+	DEBUG_PC ("Path Avail. Bw: %f, E2E Path Latency: %f, Path Cost: %f", p->availCap, p->delay, p->cost);
+	for (gint k = 0; k < p->numRouteElements; k++) {
+		DEBUG_PC ("aNodeId: %s (%s) --> zNodeId: %s (%s)", p->routeElement[k].aNodeId.nodeId, p->routeElement[k].aEndPointId,
+																p->routeElement[k].zNodeId.nodeId, p->routeElement[k].zEndPointId);
+		DEBUG_PC("linkId: %s", p->routeElement[k].linkId);
+		DEBUG_PC("aTopologyId: %s", p->routeElement[k].aTopologyId);
+		DEBUG_PC("zTopologyId: %s", p->routeElement[k].zTopologyId);
+	}
+	DEBUG_PC ("==================================================================");		
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to print the output path formed by link Ids
+ *
+ *	@param p
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_path_t(struct path_t* p) {
+	g_assert(p);
+	DEBUG_PC(" ============ COMPUTED OUTPUT PATH =================");
+	DEBUG_PC("Path Avail Capacity: %f, Cost: %f, Latency: %f", p->path_capacity.value,
+			p->path_cost.cost_value, p->path_latency.fixed_latency);
+	DEBUG_PC("number of links of path %d", p->numPathLinks);
+	for (gint k = 0; k < p->numPathLinks; k++) {
+		DEBUG_PC("Link: %s", p->pathLinks[k].linkId);
+		for (gint l = 0; l < p->pathLinks[k].numLinkTopologies; l++) {
+			DEBUG_PC("end Link [%d] TopologyId: %s", l, p->pathLinks[k].linkTopologies[l].topologyId);
+		}
+		DEBUG_PC(" ContextId: %s", p->pathLinks[k].topologyId.contextId);
+		DEBUG_PC(" TopologyUUid: %s", p->pathLinks[k].topologyId.topology_uuid);
+		DEBUG_PC(" aDeviceId: %s", p->pathLinks[k].aDeviceId);
+		DEBUG_PC(" aEndpointId: %s", p->pathLinks[k].aEndPointId);
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Returns the char (36 bytes) format of a uuid
+ *
+ *	@param uuid
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+gchar* get_uuid_char(uuid_t uuid) {
+	gchar* uuidChar = g_malloc0(16); // uuid has 36 chars
+	if (uuidChar == NULL) {
+		DEBUG_PC("Memory Allocation failure");
+		exit(-1);
+	}
+	uuid_unparse(uuid, (char *)uuidChar);
+	return uuidChar;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Makes a copy of the service identifier (including the context)
+ *
+ *	@param o
+ *  @param i
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void copy_service_id(struct serviceId_t* o, struct serviceId_t* i) {
+	g_assert(o);
+	g_assert(i);
+
+	memcpy(o->contextId, i->contextId, sizeof(i->contextId));
+	memcpy(o->service_uuid, i->service_uuid, sizeof(i->service_uuid));
+
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Makes a copy of the service endpoint identifier (including the topology (contect and topology id), device and endpoint (port))
+ *
+ *	@param oEp
+ *  @param iEp
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void copy_service_endpoint_id(struct service_endpoints_id_t* oEp, struct service_endpoints_id_t* iEp) {
+	g_assert(oEp);
+	g_assert(iEp);
+
+	// copy topology information
+	memcpy(oEp->topology_id.contextId, iEp->topology_id.contextId, sizeof(iEp->topology_id.contextId));
+	memcpy(oEp->topology_id.topology_uuid, iEp->topology_id.topology_uuid, sizeof(iEp->topology_id.topology_uuid));
+
+	// copy the endpoint
+	memcpy(oEp->device_uuid, iEp->device_uuid, sizeof(iEp->device_uuid));
+	memcpy(oEp->endpoint_uuid, iEp->endpoint_uuid, sizeof(iEp->endpoint_uuid));
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief From the set of contexts, it is returned the graph associated to that contexct matching
+ * with the passed contextId
+ *
+ *	@param Set
+ *  @param contextId
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct graph_t* get_graph_by_contextId(struct contextSet_t* Set, gchar* contextId) {
+	g_assert(Set);
+	g_assert(contextId);
+
+	// iterate over the set of context. Pick the one matching with contextId, and return the graph.
+	// If not found, return NULL
+	struct graph_t* g = NULL;
+	for (gint i = 0; i < Set->num_context_set; i++) {
+		struct context_t* context = &(Set->contextList[i]);
+		if (strcmp(context->contextId, contextId) == 0) {
+			g = &(context->g);
+			return g;
+		}
+	}
+	return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Process the service constraint and maps them into the path constraints
+ * to be fulfilled
+ *
+ *  @param path_constraints
+ *  @param s
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct path_constraints_t * get_path_constraints(struct service_t* s) {
+	g_assert(s);
+	
+	struct path_constraints_t* path_constraints = g_malloc0(sizeof(struct path_constraints_t));
+	if (path_constraints == NULL) {
+		DEBUG_PC("Memory Allocation Failure");
+		exit(-1);
+	}
+
+	char* eptr;
+	for (gint i = 0; i < s->num_service_constraints; i++) {
+		struct constraint_t* constraint = &(s->constraints[i]);;
+		if (strncmp((const char*)constraint->constraint_type, "bandwidth", 9) == 0) {
+			path_constraints->bwConstraint = (gdouble)(strtod((char*)constraint->constraint_value, &eptr));
+			path_constraints->bw = TRUE;
+			//DEBUG_PC("Path Constraint Bw: %f", path_constraints->bwConstraint);
+		}
+		if (strncmp((const char*)constraint->constraint_type, "cost", 4) == 0) {
+			path_constraints->costConstraint = (gdouble)(strtod((char*)constraint->constraint_value, &eptr));
+			path_constraints->cost = TRUE;
+			//DEBUG_PC("Path Constraint Cost: %f", path_constraints->costConstraint);
+		}
+		if (strncmp((const char*)constraint->constraint_type, "latency", 7) == 0) {
+			path_constraints->latencyConstraint = (gdouble)(strtod((char*)constraint->constraint_value, &eptr));
+			path_constraints->latency = TRUE;
+			//DEBUG_PC("Path Constraint Latency: %f", path_constraints->latencyConstraint);
+		}
+		if (strncmp((const char*)constraint->constraint_type, "energy", 6) == 0) {
+			path_constraints->energyConstraint = (gdouble)(strtod((char*)constraint->constraint_value, &eptr));
+			path_constraints->energy = TRUE;
+			//DEBUG_PC("Path Constraint Energy: %f", path_constraints->energyConstraint);
+		}
+	}
+	return path_constraints;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Creates the predecessors to keep the computed path
+ *
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct pred_t * create_predecessors ()
+{
+	struct pred_t *predecessors = g_malloc0 (sizeof (struct pred_t));
+	if (predecessors == NULL)
+	{
+		DEBUG_PC ("memory allocation failed\n");
+		exit (-1);
+	}   
+	return predecessors;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief create edge
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct edges_t* create_edge()
+{
+	struct edges_t* e = g_malloc0(sizeof(struct edges_t));
+	if (e == NULL)
+	{
+		DEBUG_PC("Memory allocation failed\n");
+		exit(-1);
+	}
+	return e;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Prints the list of the predecessors for a given computed Shortest Path
+ *
+ *	@param p 
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void print_predecessors (struct pred_t *p)
+{
+	g_assert (p);
+	DEBUG_PC ("Number of Predecessors: %d", p->numPredComp);
+	for (gint i = 0; i < p->numPredComp; i++) {
+		struct pred_comp_t *pComp = &(p->predComp[i]);
+		DEBUG_PC ("deviceId: %s", pComp->v.nodeId);		
+		struct edges_t *e = &(pComp->e);
+		DEBUG_PC("Edge[#%d] (linkId): %s", i, e->linkId);
+		DEBUG_PC ("\t %s[%s] ===>", e->aNodeId.nodeId, e->aEndPointId);
+		DEBUG_PC("\t %s[%s]", e->zNodeId.nodeId, e->zEndPointId);
+		DEBUG_PC("\t aTopologyId: %s", e->aTopologyId);
+		DEBUG_PC("\t zTopologyId: %s", e->zTopologyId);
+	}	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Builds the list of predecessors for the request destination using the computed Shortest Path
+ *	being stored in map
+ *
+ *	@param p 
+ *	@param s
+ *	@param map
+ *	
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void build_predecessors (struct pred_t *p, struct service_t *s, struct map_nodes_t *map)
+{
+	g_assert (p);
+	g_assert (s);
+	g_assert (map);
+	
+	struct nodes_t *v = create_node();
+	duplicate_string(v->nodeId, s->service_endpoints_id[1].device_uuid);
+	
+	struct edges_t *e = create_edge ();	
+	get_edge_from_map_by_node (e, v, map);
+			
+	// Get u (being source of edge e)
+	struct nodes_t u;	
+	duplicate_node_id (&e->aNodeId, &u);
+		
+	// Add to the predecessors list
+	struct pred_comp_t *pred = &(p->predComp[p->numPredComp]);
+	duplicate_node_id (&u, &pred->v);	
+	struct edges_t *e1 = &(pred->e);	
+	duplicate_edge (e1, e);
+	p->numPredComp++;	
+	// Back-trace edges till reaching the srcPEId
+	struct nodes_t* srcNode = create_node();
+	duplicate_string(srcNode->nodeId, s->service_endpoints_id[0].device_uuid);
+
+	while (compare_node_id (&u, srcNode) != 0) 	{		
+		duplicate_node_id (&u, v);
+		get_edge_from_map_by_node (e, v, map);		
+		// Get the u (being source of edge e)		
+		duplicate_node_id (&e->aNodeId, &u);		
+		// Get the new predecessor
+		struct pred_comp_t *pred = &p->predComp[p->numPredComp];			
+		// Add to the predecessors list					
+		duplicate_node_id (&u, &pred->v);		
+		struct edges_t *e1 = &(pred->e);
+		duplicate_edge (e1, e);
+		p->numPredComp++;		
+	}
+	print_predecessors (p);
+    g_free (e);
+	g_free(v);
+	g_free(srcNode);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief It creates a struct nodes_t
+ *
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct nodes_t * create_node ()
+{
+	struct nodes_t *n = g_malloc0 (sizeof (struct nodes_t));
+	if (n == NULL) {
+		DEBUG_PC ("memory allocation problem");
+		exit (-1);
+	}
+	return n;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief It creates a routeElement_t
+ *
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct routeElement_t * create_routeElement ()
+{
+	struct routeElement_t *rE = g_malloc0 (sizeof (struct routeElement_t));
+	if (rE == NULL)
+	{
+		DEBUG_PC ("memory allocation problem");
+		exit (-1);		
+	}
+	return rE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief copy node ids
+ *
+ *	@param src
+ *  @param dst
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_node_id (struct nodes_t *src, struct nodes_t *dst)
+{	
+	g_assert (src);
+	g_assert (dst);
+	
+	//DEBUG_PC ("Duplicate nodeId for %s", src->nodeId);	
+	strcpy (dst->nodeId, src->nodeId);	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief compares a pair of node Ids
+ *
+ *	@param a
+ *  @param b
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint compare_node_id (struct nodes_t *a, struct nodes_t *b)
+{
+	g_assert (a);
+	g_assert (b);	
+	return (memcmp (&a->nodeId, b->nodeId, strlen (b->nodeId)));	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief duplicate two routeElement_t
+ *
+ *	@param src
+ *  @param dst
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_routeElement (struct routeElement_t *src, struct routeElement_t *dst)
+{
+	g_assert (src);
+	g_assert (dst);
+	
+	duplicate_node_id (&(src->aNodeId), &(dst->aNodeId));
+	duplicate_node_id (&(src->zNodeId), &(dst->zNodeId));
+	duplicate_string(dst->aEndPointId, src->aEndPointId);
+	duplicate_string(dst->zEndPointId, src->zEndPointId);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief duplicate two edges
+ *
+ *	@param e1 (destination)
+ *  @param e2 (source)
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_edge (struct edges_t *e1, struct edges_t *e2) {
+	g_assert (e1);
+	g_assert (e2);
+		
+	duplicate_node_id (&e2->aNodeId, &e1->aNodeId);
+	duplicate_node_id (&e2->zNodeId, &e1->zNodeId);
+	//DEBUG_PC ("e->aNodeId: %s --->  e->zNodeId: %s", e1->aNodeId.nodeId, e1->zNodeId.nodeId);
+	duplicate_string(e1->aEndPointId, e2->aEndPointId);
+	duplicate_string(e1->zEndPointId, e2->zEndPointId);
+	duplicate_string(e1->linkId, e2->linkId);
+	duplicate_string(e1->interDomain_localId, e2->interDomain_localId);
+	duplicate_string(e1->interDomain_remoteId, e2->interDomain_remoteId);
+	duplicate_string(e1->aTopologyId, e2->aTopologyId);
+	duplicate_string(e1->zTopologyId, e2->zTopologyId);
+	
+	e1->unit = e2->unit;
+	memcpy(&e1->totalCap, &e2->totalCap, sizeof(gdouble));
+	memcpy(&e1->availCap, &e2->availCap, sizeof(gdouble));
+
+	memcpy (&e1->cost, &e2->cost, sizeof (gdouble));
+    memcpy (&e1->delay, &e2->delay, sizeof (gdouble));	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Duplicate path 
+ *
+ *	@param a - original
+ *  @param b - copy
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_path (struct compRouteOutputItem_t *a, struct compRouteOutputItem_t *b) {		
+	g_assert (a);
+	g_assert (b);
+	memcpy (&b->availCap, &a->availCap, sizeof (gdouble));
+	b->numRouteElements = a->numRouteElements;	
+	memcpy(&b->cost, &a->cost, sizeof(gdouble));	
+	memcpy (&b->delay, &a->delay, sizeof (gdouble));
+	for (gint k = 0; k < a->numRouteElements; k++) {			
+		//DEBUG_PC ("aNodeId: %s // zNodeId: %s", a->routeElement[k].aNodeId.nodeId, a->routeElement[k].zNodeId.nodeId);
+		// aNodeId duplication
+		struct nodes_t *n1 = &(a->routeElement[k].aNodeId);
+		struct nodes_t *n2 = &(b->routeElement[k].aNodeId);			
+		duplicate_node_id (n1, n2);			
+					
+		//zNodeId duplication
+		n1 = &(a->routeElement[k].zNodeId);
+		n2 = &(b->routeElement[k].zNodeId);			
+		duplicate_node_id (n1, n2);
+		duplicate_string(b->routeElement[k].aEndPointId, a->routeElement[k].aEndPointId);
+		duplicate_string(b->routeElement[k].zEndPointId, a->routeElement[k].zEndPointId);
+		duplicate_string(b->routeElement[k].linkId, a->routeElement[k].linkId);
+		duplicate_string(b->routeElement[k].aTopologyId, a->routeElement[k].aTopologyId);
+		duplicate_string(b->routeElement[k].zTopologyId, a->routeElement[k].zTopologyId);
+	}	
+	return;	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Duplicate path from compRouteOutputItem_t to path_t
+ *
+ *	@param a - original
+ *  @param b - copy
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_path_t(struct compRouteOutputItem_t* a, struct path_t* b)
+{
+	g_assert(a);
+	g_assert(b);
+
+	memcpy(&b->path_capacity.value, &a->availCap, sizeof(gdouble));
+	memcpy(&b->path_cost.cost_value, &a->cost, sizeof(gdouble));
+	memcpy(&b->path_latency.fixed_latency, &a->delay, sizeof(gdouble));
+
+	b->numPathLinks = a->numRouteElements;
+
+	for (gint k = 0; k < a->numRouteElements; k++) {
+		struct routeElement_t* rE = &(a->routeElement[k]);
+		struct pathLink_t* pL = &(b->pathLinks[k]);
+
+		// copy the aDeviceId and aEndpointId, zDeviceId and zEndPointId
+		duplicate_string(pL->aDeviceId, rE->aNodeId.nodeId);
+		duplicate_string(pL->zDeviceId, rE->zNodeId.nodeId);
+		duplicate_string(pL->aEndPointId, rE->aEndPointId);
+		duplicate_string(pL->zEndPointId, rE->zEndPointId);
+
+		duplicate_string(pL->topologyId.topology_uuid, rE->aTopologyId);
+		duplicate_string(pL->topologyId.contextId, rE->contextId);
+
+		//copy the linkId
+		duplicate_string(pL->linkId, rE->linkId);
+		pL->numLinkTopologies++;
+		duplicate_string(pL->linkTopologies[pL->numLinkTopologies - 1].topologyId, rE->aTopologyId);
+		pL->numLinkTopologies++;
+		duplicate_string(pL->linkTopologies[pL->numLinkTopologies - 1].topologyId, rE->zTopologyId);
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Return the index into mapN related nodeId
+ * 
+ *  @param nodeId
+ *  @para mapN
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint get_map_index_by_nodeId (gchar *nodeId, struct map_nodes_t * mapN)
+{
+    gint index = -1;
+    gint i = 0;
+    
+    for (i = 0; i < mapN->numMapNodes; i++)
+    {
+		//DEBUG_PC ("i: %d; current: %s // targeted: %s", i, mapN->map[i].verticeId.nodeId, nodeId);
+        if (memcmp (mapN->map[i].verticeId.nodeId, nodeId, strlen (nodeId)) == 0)
+        {
+            index = i;
+			//DEBUG_PC ("Index: %d", index);
+            return index;            
+        }
+    }
+	//DEBUG_PC ("Index: %d", index);
+    return index;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Get the edge e enabling reaching the computed v in mapNodes
+ * 
+ *  @param e
+ *  @param v
+ *  @param mapN
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void get_edge_from_map_by_node (struct edges_t *e, struct nodes_t* v, struct map_nodes_t *mapN) {
+	
+	//DEBUG_PC ("Get the Edge into map from node v: %s", v.nodeId);	
+	// Get the edge reaching the node v from mapNodes
+	gint map_vIndex = get_map_index_by_nodeId (v->nodeId, mapN);
+	
+	//DEBUG_PC ("aNodeId: %s --> zNodeId: %s", mapN->map[map_vIndex].predecessor.aNodeId.nodeId, mapN->map[map_vIndex].predecessor.zNodeId.nodeId);
+	
+	struct edges_t *te = &(mapN->map[map_vIndex].predecessor);	
+	duplicate_edge (e, te);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Get the edge from the predecessors array for a given node n
+ * 
+ *  @param e
+ *  @param n
+ *  @param predecessors
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void get_edge_from_predecessors (struct edges_t *e, struct nodes_t* n, struct pred_t *predecessors) {
+	g_assert(predecessors);
+
+	DEBUG_PC ("Get edge outgoing node %s from predecessors list", n->nodeId);
+	//print_predecessors (predecessors);
+	for (gint i = 0; i < predecessors->numPredComp; i++) {
+		struct pred_comp_t *pred = &(predecessors->predComp[i]);
+		if (compare_node_id (n, &pred->v) == 0) {
+			// Add to the predecessors list
+			struct edges_t *te = &(pred->e);
+			DEBUG_PC("add e (linkId): %s", te->linkId);
+			duplicate_edge (e, te);
+			return;
+		}	
+	}	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Construct the path using the predecessors list
+ * 
+ *  @param path
+ *  @param predecessors
+ *	@param s
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void build_path (struct compRouteOutputItem_t *p, struct pred_t *predecessors, struct service_t *s) {
+	//DEBUG_PC ("\n");
+	// Get the source device Id	of the network connectivity service
+	struct nodes_t *v = create_node();
+	duplicate_string(v->nodeId, s->service_endpoints_id[0].device_uuid);
+
+	struct edges_t* e = create_edge();
+							  	
+	// Get the edge for v in predecessors
+	get_edge_from_predecessors (e, v, predecessors);	
+	// Get the target for e
+	struct nodes_t u;	
+	duplicate_node_id (&e->zNodeId, &u);
+	//DEBUG_PC ("u: %s", u.nodeId);
+	struct path_constraints_t* pathCons = get_path_constraints(s);		
+
+	// Add route element to the path being constructed
+	gint k = 0;
+	duplicate_node_id (&e->aNodeId, &p->routeElement[k].aNodeId);
+	duplicate_node_id (&e->zNodeId, &p->routeElement[k].zNodeId);
+	duplicate_string(p->routeElement[k].aEndPointId, e->aEndPointId);
+	duplicate_string(p->routeElement[k].zEndPointId, e->zEndPointId);
+	duplicate_string(p->routeElement[k].linkId, e->linkId);
+	duplicate_string(p->routeElement[k].aTopologyId, e->aTopologyId);
+	duplicate_string(p->routeElement[k].zTopologyId, e->zTopologyId);
+	duplicate_string(p->routeElement[k].contextId, s->serviceId.contextId);
+	p->numRouteElements++;
+
+	// Get the destination device Id of the network connectivity service
+	struct nodes_t* dst = create_node();
+	duplicate_string(dst->nodeId, s->service_endpoints_id[1].device_uuid);
+	while (compare_node_id (&u, dst) != 0)	
+	{
+		k++; 
+		p->numRouteElements++;
+		// v = u		
+		duplicate_node_id (&u, v);
+		get_edge_from_predecessors (e, v, predecessors);
+		// Get the target u		
+		duplicate_node_id (&e->zNodeId, &u);
+		// Add route element to the path being constructed		
+		duplicate_node_id (&e->aNodeId, &p->routeElement[k].aNodeId);
+		duplicate_node_id (&e->zNodeId, &p->routeElement[k].zNodeId);
+		duplicate_string(p->routeElement[k].aEndPointId, e->aEndPointId);
+		duplicate_string(p->routeElement[k].zEndPointId, e->zEndPointId);
+		duplicate_string(p->routeElement[k].linkId, e->linkId);
+		duplicate_string(p->routeElement[k].aTopologyId, e->aTopologyId);
+		duplicate_string(p->routeElement[k].zTopologyId, e->zTopologyId);
+		duplicate_string(p->routeElement[k].contextId, s->serviceId.contextId);
+
+		// copy the contextId
+		//duplicate_string(p->routeElement[k].contextId, s->service_endpoints_id[0].topology_id.contextId);
+	}		
+	g_free(e); g_free(v); g_free(pathCons);
+	//DEBUG_PC ("Path is constructed");	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Print the graph for DEBUG_PCging purposes
+ * 
+ *  @param g
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void print_graph (struct graph_t *g)
+{	     
+    DEBUG_PC ("================================================================");
+    DEBUG_PC ("===========================   GRAPH   ==========================");
+    DEBUG_PC ("================================================================");
+
+	DEBUG_PC("Graph Num Vertices: %d", g->numVertices);
+    
+    gint i = 0, j = 0, k = 0;
+    for (i = 0; i < g->numVertices; i++)
+    {
+        DEBUG_PC ("Head Vertice [%s]", g->vertices[i].verticeId.nodeId);
+        for (j = 0; j < g->vertices[i].numTargetedVertices; j++)
+        {
+            DEBUG_PC ("  Tail Vertice: %s", g->vertices[i].targetedVertices[j].tVertice.nodeId);
+            for (k = 0; k < g->vertices[i].targetedVertices[j].numEdges; k++)
+            {
+                struct edges_t *e = &(g->vertices[i].targetedVertices[j].edges[k]);
+				DEBUG_PC ("%s(%s) --> %s(%s) [C: %f, Bw: %f b/s, Delay: %f ms]", e->aNodeId.nodeId, e->aEndPointId, e->zNodeId.nodeId, 
+								e->zEndPointId, e->cost, e->availCap, e->delay);				
+           }
+        }       
+    }     
+    return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Look for a given edge into the graph
+ *
+ *  @param verticeIndex
+ *	@param targetedVerticeIndex
+ *  @param e
+ *  @param g
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint graph_edge_lookup (gint verticeIndex, gint targetedVerticeIndex, struct edges_t *e, struct graph_t *g)	{
+	gint indexEdge = -1;
+	
+	for (gint j = 0; j < g->vertices[verticeIndex].targetedVertices[targetedVerticeIndex].numEdges; j++) {
+		struct edges_t *e2 = &(g->vertices[verticeIndex].targetedVertices[targetedVerticeIndex].edges[j]);
+		if ((compare_node_id (&e->aNodeId, &e2->aNodeId) == 0) &&
+			(compare_node_id (&e->zNodeId, &e2->zNodeId) == 0) &&
+			(strcmp (e->aEndPointId, e2->aEndPointId) == 0) &&
+			(strcmp (e->zEndPointId, e2->zEndPointId) == 0) &&
+			(strcmp(e->linkId, e2->linkId) == 0)) {
+			DEBUG_PC ("%s (%s) --> %s (%s) [linkId: %s] FOUND in the Graph at index: %d", e->aNodeId.nodeId, e->aEndPointId, e->zNodeId.nodeId, 
+							e->zEndPointId, e->linkId, j);
+			indexEdge = j;
+			return indexEdge;
+		}		
+	}	
+	return indexEdge;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Look for a given vertice within the graph using the nodeId
+ *
+ *  @param nodeId
+ *	@param g
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint graph_vertice_lookup (gchar *nodeId, struct graph_t *g)
+{
+    gint index = -1; 
+	//DEBUG_PC("Searching Node: %s", nodeId);
+    for (gint i = 0; i < g->numVertices; i++) {
+		//DEBUG_PC("Checked Graph Node: %s", g->vertices[i].verticeId.nodeId);
+		if (memcmp (g->vertices[i].verticeId.nodeId, nodeId, strlen (nodeId)) == 0)
+        {
+            index = i;
+            //DEBUG_PC ("%s is found in the graph vertice [%d]", nodeId, index);
+            break;
+        }     
+    }  
+    return (index);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Check if a nodeId is already considered into the set of targeted vertices from a given vertice
+ *
+ *  @param nodeId
+ *  @param vIndex
+ *  @param g
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint graph_targeted_vertice_lookup (gint vIndex, gchar *nodeId, struct graph_t *g)
+{
+    gint addedTargetedVerticeIndex = -1;
+    gint i = 0;
+    
+    if (g->vertices[vIndex].numTargetedVertices == 0)
+    {
+        return (addedTargetedVerticeIndex);
+    }
+    
+    for (i = 0; i < g->vertices[vIndex].numTargetedVertices; i++)
+    {
+        if (memcmp (g->vertices[vIndex].targetedVertices[i].tVertice.nodeId, nodeId, strlen (nodeId)) == 0)
+        {
+            DEBUG_PC ("Targeted %s reachable from %s", nodeId, g->vertices[vIndex].verticeId.nodeId);
+            addedTargetedVerticeIndex = i;
+            return (addedTargetedVerticeIndex);
+        }        
+    }    
+    // not found ...    
+    return (addedTargetedVerticeIndex);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Check if a nodeId is already considered into the set of targeted vertices from a given vertice, if not to be added
+ *
+ *  @param nodeId
+ *  @param vIndex
+ *  @param g
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint graph_targeted_vertice_add (gint vIndex, gchar *nodeId, struct graph_t *g)
+{
+    gint addedTargetedVerticeIndex = -1;
+    gint i = 0;
+    
+    if (g->vertices[vIndex].numTargetedVertices == 0)
+    {
+        //DEBUG_PC ("targeted vertice %s being reachable from vertice %s", nodeId, g->vertices[vIndex].verticeId.nodeId);        
+        addedTargetedVerticeIndex = 0;
+        return (addedTargetedVerticeIndex);
+    }
+    
+    for (i = 0; i < g->vertices[vIndex].numTargetedVertices; i++)
+    {        
+		if (memcmp (g->vertices[vIndex].targetedVertices[i].tVertice.nodeId, nodeId, strlen (nodeId)) == 0)
+        {
+            //DEBUG_PC ("Targeted vertice %s is already considered in the reachable from vertice %s", nodeId, g->vertices[vIndex].verticeId.nodeId);
+            addedTargetedVerticeIndex = -1;
+            return (addedTargetedVerticeIndex);
+        }        
+    }    
+    // It is not found, next to be added at i position
+    addedTargetedVerticeIndex = i;
+    return (addedTargetedVerticeIndex);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Remove edge from the graph
+ *
+ *  @param g
+ *  @param e
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+void remove_edge_from_graph (struct graph_t *g, struct edges_t *e)
+{
+	// Find the ingress vertice into the graph
+	DEBUG_PC ("Removing from Graph %s[%s]) ---> %s[%s] (linkId: %s)", e->aNodeId.nodeId, e->aEndPointId, e->zNodeId.nodeId, e->aEndPointId, e->linkId);
+	gint verticeIndex = -1;		
+	verticeIndex = graph_vertice_lookup (e->aNodeId.nodeId, g);
+	if (verticeIndex == -1)	{
+		DEBUG_PC ("Edge w/ %s is NOT in the Graph!!", e->aNodeId.nodeId);
+		return;
+	}
+	
+	// Find the targeted vertice from vertice Id
+	gint targetedVerticeIndex = -1;
+	targetedVerticeIndex = graph_targeted_vertice_lookup (verticeIndex, e->zNodeId.nodeId, g);
+	if (targetedVerticeIndex == -1)	{
+		DEBUG_PC ("%s --> %s NOT in the Graph!!", e->aNodeId.nodeId, e->zNodeId.nodeId);
+		return;
+	}
+	
+	//DEBUG_PC ("%s --> %s found in the Graph", e->aNodeId.nodeId, e->zNodeId.nodeId);
+	
+	// Get the edge position
+	gint edgeIndex = -1;
+	edgeIndex = graph_edge_lookup (verticeIndex, targetedVerticeIndex, e, g);
+	if (edgeIndex == -1) 	{
+		DEBUG_PC ("%s --> %s NOT in the Graph!!", e->aNodeId.nodeId, e->zNodeId.nodeId);
+		return;
+	}
+	
+	//DEBUG_PC ("%s --> %s FOUND in Graph w/ edgeIndex: %d", e->aNodeId.nodeId, e->zNodeId.nodeId, edgeIndex);
+	
+	// Remove the edge
+	//DEBUG_PC ("Start Removing %s --> %s from Graph", e->aNodeId.nodeId, e->zNodeId.nodeId);	
+	struct targetNodes_t *v = &(g->vertices[verticeIndex].targetedVertices[targetedVerticeIndex]);	
+	for (gint j = edgeIndex; j < v->numEdges; j++) {	
+		struct edges_t *e1 = &(v->edges[j]);
+		struct edges_t *e2 = &(v->edges[j+1]);		
+		duplicate_edge (e1, e2);
+	}
+	v->numEdges --;
+	DEBUG_PC ("Number of Edges between %s and %s is %d", e->aNodeId.nodeId, e->zNodeId.nodeId, v->numEdges);	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief create the pointer for keeping a set of the paths (struct compRouteOutput_t)
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct path_set_t * create_path_set ()
+{
+	struct path_set_t * p = g_malloc0 (sizeof (struct path_set_t));
+	if (p == NULL)
+	{
+		DEBUG_PC ("Memory allocation problem");
+		exit (-1);		
+	}
+	return p;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Remove the path set
+ *
+ * @param p
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2021
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void remove_path_set(struct path_set_t* p)
+{
+	g_assert(p);
+	g_free(p);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Create map of nodes to handle the path computation
+ *
+ * 	@param mapN
+ *  @param g
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void build_map_node (struct map_nodes_t *mapN, struct graph_t *g)
+{
+	//DEBUG_PC ("Construction of the Map of Nodes");               
+    for (gint i = 0; i < g->numVertices; i++)
+    {	
+		duplicate_node_id (&g->vertices[i].verticeId, &mapN->map[i].verticeId);
+        mapN->map[i].distance = INFINITY_COST;
+        mapN->map[i].avaiBandwidth = 0.0;
+        mapN->map[i].latency = INFINITY_COST;
+        mapN->numMapNodes++;
+    }
+    //DEBUG_PC ("mapNodes formed by %d Nodes", mapN->numMapNodes);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for path of struct compRouteOutputList_t *
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct compRouteOutputList_t * create_route_list ()
+{
+	struct compRouteOutputList_t *p = g_malloc0 (sizeof (struct compRouteOutputList_t));
+	if (p == NULL)
+	{
+		DEBUG_PC ("Memory Allocation Problem");
+		exit (-1);
+	}
+	return p;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for path of struct compRouteOutputItem_t *
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct compRouteOutputItem_t *create_path_item ()
+{
+	struct compRouteOutputItem_t *p = g_malloc0 (sizeof (struct compRouteOutputItem_t));
+	if (p == NULL) 	{
+		DEBUG_PC ("Memory Allocation Problem");
+		exit (-1);
+	}
+	return p;	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Sort the set of paths according to the metric (1st criteria) and latency (2nd criteria)
+ *
+ *	@params setP
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void sort_path_set(struct path_set_t* setP) {
+	g_assert(setP);
+	// Sort the paths contained in setP by shotest metric and latency	
+	float epsilon = 0.0000001;
+
+	for (gint i = 0; i < setP->numPaths; i++) {
+		for (gint j = 0; j < (setP->numPaths - i - 1); j++)	{
+			struct compRouteOutputItem_t* path1 = &setP->paths[j];
+			struct compRouteOutputItem_t* path2 = &setP->paths[j + 1];
+			
+			struct compRouteOutputItem_t* pathTmp = create_path_item();
+			// 1st Criteria (avail Bw)
+			if ((path2->availCap - path1->availCap > 0.0) && (fabs(path1->availCap - path2->availCap) > epsilon)) {
+				duplicate_path(path1, pathTmp);
+				duplicate_path(path2, path1);
+				duplicate_path(pathTmp, path2);
+				g_free(pathTmp);
+				continue;
+			}
+			else if ((path1->availCap - path2->availCap > 0.0) && (fabs(path1->availCap - path2->availCap) > epsilon)) {
+				g_free(pathTmp);
+				continue;
+			}
+			// likely the same available bw between path1 and path2
+			else if (fabs(path1->availCap - path2->availCap) < epsilon) {
+				// 2nd criteria: sort path cost
+				if (path1->cost > path2->cost) {
+					duplicate_path(path1, pathTmp);
+					duplicate_path(path2, path1);
+					duplicate_path(pathTmp, path2);
+					g_free(pathTmp);
+					continue;
+				}
+				else if (path1->cost < path2->cost) {
+					g_free(pathTmp);
+					continue;
+				}
+				// 3rd criteria: same path cost, prioritize the one with lowest e2e latency
+				else if (path1->cost == path2->cost) {
+					if ((path2->delay - path1->delay > 0.0) && (fabs(path1->delay - path2->delay) > epsilon)) {
+						g_free(pathTmp);
+						continue;
+					}
+					else if ((path1->delay - path2->delay > 0.0) && (fabs(path1->delay - path2->delay) > epsilon)) {
+						duplicate_path(path1, pathTmp);
+						duplicate_path(path2, path1);
+						duplicate_path(pathTmp, path2);
+						g_free(pathTmp);
+						continue;
+					}
+					// Same bw, same cost and same latency, path1 and path2 are practically the same
+					else if (fabs(path1->delay - path2->delay) < epsilon) {
+						g_free(pathTmp);
+						continue;
+					}
+				}
+			}			
+		}
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Remove first element from the path sets 
+ *
+ *	@params setP
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void pop_front_path_set (struct path_set_t *setP) {
+	for (gint j = 0; j < setP->numPaths - 1; j++) {
+		struct compRouteOutputItem_t *path1 = &setP->paths[j];
+		struct compRouteOutputItem_t *path2 = &setP->paths[j+1];		
+		duplicate_path (path2, path1);		
+	}
+	setP->numPaths--;	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Add routeElement to the back of the path
+ *
+ * 	@param rE
+ * 	@param p
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void add_routeElement_path_back (struct routeElement_t *rE, struct compRouteOutputItem_t *p)
+{
+	//DEBUG_PC ("p->numRouteElements: %d", p->numRouteElements);
+	p->numRouteElements++;
+	gint index = p->numRouteElements - 1;
+	
+	struct nodes_t *pn = &(p->routeElement[index].aNodeId);
+	struct nodes_t *rEn = &(rE->aNodeId);
+	
+	// duplicate aNodeId
+	duplicate_node_id (rEn, pn);	
+	pn = &(p->routeElement[index].zNodeId);
+	rEn = &(rE->zNodeId);
+	duplicate_node_id (rEn, pn);
+	duplicate_string(p->routeElement[index].aEndPointId, rE->aEndPointId);
+	duplicate_string(p->routeElement[index].zEndPointId, rE->zEndPointId);
+	duplicate_string(p->routeElement[index].linkId, rE->linkId);
+	duplicate_string(p->routeElement[index].aTopologyId, rE->aTopologyId);
+	duplicate_string(p->routeElement[index].zTopologyId, rE->zTopologyId);
+
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief This function compares ap and rootPath. If all the links are equal between both ap and rootPath till the sN, then the link from sN to next node 
+ * 	ap is returned
+ * 
+ * @params ap
+ * @params p
+ * @params sN
+ * @params e
+ * 
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gboolean matching_path_rootPath (struct compRouteOutputItem_t *ap, struct compRouteOutputItem_t *rootPath, struct nodes_t *sN, struct edges_t *e) {
+	gint j = 0;
+	gboolean ret = FALSE;
+	while ((j < ap->numRouteElements) && (j < rootPath->numRouteElements)) {
+		if ((memcmp (ap->routeElement[j].aNodeId.nodeId, rootPath->routeElement[j].aNodeId.nodeId, sizeof (ap->routeElement[j].aNodeId.nodeId)) == 0) &&
+			//(memcmp (ap->routeElement[j].zNodeId.nodeId, rootPath->routeElement[j].zNodeId.nodeId, sizeof (ap->routeElement[j].zNodeId.nodeId)) != 0) &&
+			(memcmp (sN->nodeId, rootPath->routeElement[j].aNodeId.nodeId, sizeof (ap->routeElement[j].aNodeId.nodeId)) == 0)) {						
+			duplicate_node_id (&ap->routeElement[j].aNodeId, &e->aNodeId);
+			duplicate_node_id (&ap->routeElement[j].zNodeId, &e->zNodeId);
+			duplicate_string(e->aEndPointId, ap->routeElement[j].aEndPointId);
+			duplicate_string(e->zEndPointId, ap->routeElement[j].zEndPointId);
+			duplicate_string(e->linkId, ap->routeElement[j].linkId);
+			return TRUE;			
+		}		
+		if ((memcmp (ap->routeElement[j].aNodeId.nodeId, rootPath->routeElement[j].aNodeId.nodeId, sizeof (ap->routeElement[j].aNodeId.nodeId)) == 0) && 
+			(memcmp (ap->routeElement[j].zNodeId.nodeId, rootPath->routeElement[j].zNodeId.nodeId, sizeof (ap->routeElement[j].zNodeId.nodeId)) == 0)) {
+			j++;			
+			continue;			
+		}
+		
+		if ((memcmp (ap->routeElement[j].aNodeId.nodeId, rootPath->routeElement[j].aNodeId.nodeId, sizeof (ap->routeElement[j].aNodeId.nodeId)) != 0) || 
+			(memcmp (ap->routeElement[j].zNodeId.nodeId, rootPath->routeElement[j].zNodeId.nodeId, sizeof (ap->routeElement[j].zNodeId.nodeId)) != 0)) {
+			//DEBUG_PC ("ap and rootPath not in the same path");
+			return ret;
+		}
+	}	
+	return ret;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief This function is used to modify the graph to be used for running the subsequent SP computations acording to the YEN algorithm principles
+ * 
+ * @params g
+ * @params A
+ * @params rootPath
+ * @params spurNode
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void modify_targeted_graph (struct graph_t *g, struct path_set_t *A, struct compRouteOutputItem_t * rootPath, struct nodes_t * spurNode) {
+	//DEBUG_PC ("Modify the Targeted graph according to the Yen algorithm principles");
+	for (gint j = 0; j < A->numPaths; j++)
+	{
+		struct compRouteOutputItem_t *ap = &A->paths[j];
+		struct edges_t *e = create_edge ();
+		gboolean ret =  FALSE;
+		ret = matching_path_rootPath (ap, rootPath, spurNode, e);		
+		if (ret == TRUE) {
+			//DEBUG_PC ("Removal %s [%u]--> %s [%u] from the graph", e->aNodeId.nodeId, e->aLinkId, e->zNodeId.nodeId, e->zLinkId);
+			remove_edge_from_graph (g, e);
+			//DEBUG_PC ("Print Resulting Graph");
+			//print_graph (g);
+			g_free (e);			
+		}
+		if (ret == FALSE)
+		{
+			g_free (e);
+			continue;
+		}						
+	}	
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Supporting fucntion to Check if a nodeId is already in the items of a given GList
+ * 
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint find_nodeId (gconstpointer data, gconstpointer userdata)
+{
+     /** check values */
+     g_assert(data != NULL);
+     g_assert(userdata != NULL);
+ 
+     struct nodeItem_t *SNodeId = (struct nodeItem_t *)data;
+     guchar * nodeId = (guchar *)userdata; 
+     
+     //DEBUG_PC ("SNodeId (%s) nodeId (%s)", SNodeId->node.nodeId, nodeId);   
+        
+     if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId)))
+     {
+		return (0);
+     }
+    return -1;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Explores the link between u and v
+ * 
+ *  @param u
+ *  @param v 
+ *	@param g
+ *	@param s
+ *  @param S
+ *  @param Q
+ *	@param mapNodes
+ * 
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struct graph_t *g, 
+				struct service_t *s, GList **S, GList **Q, struct map_nodes_t *mapNodes) { 
+	g_assert(g);
+	g_assert(s);
+	g_assert(mapNodes);
+
+	struct targetNodes_t *v = &(g->vertices[indexGraphU].targetedVertices[indexGraphV]);	
+    DEBUG_PC("Explored link (u ===> v):");
+	DEBUG_PC("u: %s ====>", u->node.nodeId);
+	DEBUG_PC("====> v: %s", v->tVertice.nodeId);
+    
+    // v already explored in S? then, discard it
+    GList *found = g_list_find_custom (*S, v->tVertice.nodeId, find_nodeId);
+    if (found != NULL) {
+        DEBUG_PC ("v (%s) in S, discard to explore it!", v->tVertice.nodeId);        
+        return 0;
+    }
+
+	// Get the set of constraints imposed by the service
+	struct path_constraints_t* path_constraints = get_path_constraints(s);
+    gdouble distance_through_u = INFINITY_COST;
+    gdouble latency_through_u = INFINITY_COST;	
+	gint i = 0;
+
+    // Check bandwidth requirement is fulfillied on edge u --> v    
+    gint foundAvailBw = 0;
+    gdouble edgeAvailBw = 0.0;
+    for (i = 0; i < v->numEdges; i++) {        
+        struct edges_t *e = &(v->edges[i]);
+		memcpy (&edgeAvailBw, &(e->availCap), sizeof (gdouble));
+		DEBUG_PC("edge:u ===> v");
+        DEBUG_PC ("%s[%s] ===>", u->node.nodeId, e->aEndPointId);
+		DEBUG_PC("====> %s[%s]", v->tVertice.nodeId, e->zEndPointId);
+		DEBUG_PC("edge available bw: %f", edgeAvailBw);
+
+        // if network service constraint specifies "bandwidth" needs (assuming coherent units)
+		if (path_constraints->bw == TRUE) {
+			if (edgeAvailBw < path_constraints->bwConstraint) {
+				continue;
+			}
+			else {
+				foundAvailBw = 1;
+				break;
+			}
+		}		
+    }
+	// if bw path constraint is specified but not sastified ...	discard the edge
+    if ((path_constraints->bw == TRUE) && (foundAvailBw == 0))
+    {
+        DEBUG_PC ("AvailBw: %f < path_constraint: %f -- Discard Edge", edgeAvailBw, path_constraints->bwConstraint);
+		g_free(path_constraints);
+        return 0;    
+    } 
+
+    gint indexEdge = i; // get the index for the explored edge
+    // Update distance, latency and availBw through u to reach v
+    gint map_uIndex = get_map_index_by_nodeId (u->node.nodeId, mapNodes);
+	struct map_t *u_map = &mapNodes->map[map_uIndex];
+    distance_through_u = u_map->distance + v->edges[indexEdge].cost;
+    latency_through_u = u_map->latency + v->edges[indexEdge].delay;    
+    gdouble availBw_through_u = 0.0;
+
+	// ingress endpoint (u) is the src of the request
+    if (strcmp (u->node.nodeId, s->service_endpoints_id[0].device_uuid) == 0) {
+        //DEBUG_PC ("AvailBw %f on %s --> %s", edgeAvailBw, u->node.nodeId, v->tVertice.nodeId);        
+        memcpy (&availBw_through_u, &edgeAvailBw, sizeof (gdouble));        
+    }
+    else {
+        // Get the minimum available bandwidth between the src-->u and the new added edge u-->v
+        //DEBUG_PC ("Current AvailBw: %f from src to %s", u_map->avaiBandwidth, u->node.nodeId);
+        //DEBUG_PC ("AvailBw: %f %s --> %s", edgeAvailBw, u->node.nodeId, v->tVertice.nodeId);
+        if (u_map->avaiBandwidth <= edgeAvailBw) {
+            memcpy (&availBw_through_u, &u_map->avaiBandwidth, sizeof (gdouble));    
+		}
+		else {
+			memcpy (&availBw_through_u, &edgeAvailBw, sizeof (gdouble));
+		} 
+    }     
+    // Relax the link according to the pathCost and latency
+    gint map_vIndex = get_map_index_by_nodeId (v->tVertice.nodeId, mapNodes);
+	struct map_t *v_map = &mapNodes->map[map_vIndex];
+    // If cost dist (u, v) > dist (src, v) relax the link
+    if (distance_through_u > v_map->distance) {
+        //DEBUG_PC ("dist(src, u) + dist(u, v): %f > dist (src, v): %f --> Discard Link", distance_through_u, v_map->distance);  
+        return 0;
+    }
+    // If dist (src, u) + dist (u, v) = current dist(src, v), then use the latency as discarding criteria
+    if ((distance_through_u == v_map->distance) && (latency_through_u > v_map->latency)) {
+        //DEBUG_PC ("dist(src, u) + dist(u,v) = current dist(src, v), but latency (src,u) + latency (u, v) > current latency (src, v)");          
+        return 0;
+    }	
+	// If dist (src, u) + dist (u,v) == current dist(src, v) AND latency (src, u) + latency (u, v) == current latency (src, v), the available bandwidth is the criteria
+	if ((distance_through_u ==  v_map->distance) && (latency_through_u == v_map->latency) && (availBw_through_u < v_map->avaiBandwidth)) {
+		return 0;
+	}    
+    DEBUG_PC ("%s --> %s Relaxed", u->node.nodeId, v->tVertice.nodeId);
+    DEBUG_PC ("\t AvailBw: %f Mb/s, Cost: %f, Latency: %f ms", availBw_through_u, distance_through_u, latency_through_u);
+    
+    // Update Q list -- 
+    struct nodeItem_t *nodeItem = g_malloc0 (sizeof (struct nodeItem_t));
+    if (nodeItem == NULL) {
+		DEBUG_PC ("memory allocation failed\n");
+		exit (-1);    
+    }    
+    nodeItem->distance = distance_through_u;
+	memcpy(&nodeItem->distance, &distance_through_u, sizeof(gdouble));		     
+	memcpy(&nodeItem->latency, &latency_through_u, sizeof(gdouble));
+	duplicate_node_id (&v->tVertice, &nodeItem->node);	
+	// add node to the Q list
+    *Q = g_list_insert_sorted (*Q, nodeItem, sort_by_distance);
+    //DEBUG_PC ("%s ADDED to Q (length: %d)", nodeItem->node.nodeId, g_list_length(*Q));    
+    
+    // Update the mapNodes for the specific reached tv   
+    v_map->distance = distance_through_u;
+	memcpy(&v_map->distance, &distance_through_u, sizeof(gdouble));
+    memcpy (&v_map->avaiBandwidth, &availBw_through_u, sizeof (gdouble));
+    memcpy (&v_map->latency, &latency_through_u, sizeof (gdouble));
+    // Duplicate the predecessor edge into the mapNodes 
+	struct edges_t *e1 = &(v_map->predecessor);
+	struct edges_t *e2 = &(v->edges[indexEdge]);
+	duplicate_edge (e1, e2);	
+	DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId);
+	DEBUG_PC("v-pred aTopology: %s", e2->aTopologyId);
+	DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId);
+
+    // Check whether v is dstPEId
+	//DEBUG_PC ("Targeted dstPEId: %s", req->dstPEId.nodeId);
+	//DEBUG_PC ("nodeId added to the map: %s", v_map->verticeId.nodeId);
+	//DEBUG_PC ("Q Length: %d", g_list_length(*Q));
+	g_free(path_constraints);
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Check the feasability of a path wrt the constraints imposed by the request in terms of latency
+ * 
+ *  @param s
+ *	@param p
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gboolean check_computed_path_feasability (struct service_t *s, struct compRouteOutputItem_t* p) {	
+	float epsilon = 0.0000001;
+	struct path_constraints_t* pathCons = get_path_constraints(s);
+	gboolean ret = TRUE;
+
+	if (pathCons->latency == TRUE) {
+		if ((pathCons->latencyConstraint - p->delay > 0.0) || (fabs(pathCons->latencyConstraint - p->delay) < epsilon)) {
+			DEBUG_PC("Computed Path (latency: %f) is feasible wrt Connection Demand: %f", p->delay, pathCons->latencyConstraint);
+		}
+		else {
+			DEBUG_PC("Computed Path (latency: %f) is NOT feasible wrt Connection Demand: %f", p->delay, pathCons->latencyConstraint);
+			g_free(pathCons);
+			return FALSE;
+		}
+	}
+	// Other constraints...
+	
+	g_free(pathCons);
+	return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Sorting the GList Q items by distance 
+ * 
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint sort_by_distance (gconstpointer a, gconstpointer b)
+{
+	//DEBUG_PC ("sort by distance a and b");	
+	g_assert(a != NULL);
+	g_assert(b != NULL);
+	
+	//DEBUG_PC ("sort by distance a and b");	  
+	struct nodeItem_t *node1 = (struct nodeItem_t *)a;
+	struct nodeItem_t *node2 = (struct nodeItem_t *)b;
+	g_assert (node1);
+	g_assert (node2);
+	 
+	//DEBUG_PC ("a->distance %u; b->distance %u", node1->distance, node2->distance);
+	//DEBUG_PC("a->latency: %f; b->latency: %f", node1->latency, node2->latency);
+	//1st criteria, sorting by lowest distance
+	if (node1->distance > node2->distance)
+		return 1;
+	else if (node1->distance < node2->distance)
+		return 0;
+	if (node1->distance == node2->distance)
+	{
+		if (node1->latency > node2->latency)
+			return 1;
+		else if (node1->latency <= node2->latency)
+			return 0;
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for graph
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct graph_t * create_graph () {
+	struct graph_t * g = g_malloc0 (sizeof (struct graph_t));
+	if (g == NULL)
+	{
+		DEBUG_PC ("Memory Allocation Problem");
+		exit (-1);
+	}
+	return g;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for mapNodes
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+struct map_nodes_t * create_map_node ()	 {
+	struct map_nodes_t * mN = g_malloc0 (sizeof (struct map_nodes_t));
+	if (mN == NULL)
+	{
+		DEBUG_PC ("Memory allocation failed");
+		exit (-1);
+	}
+	return mN;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Look up for the service in the servieList bound to a serviceUUID
+ * 
+ * @params serviceUUID
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+struct service_t* get_service_for_computed_path(gchar* serviceUUID) {
+	for (gint i = 0; i < serviceList->numServiceList; i++) {
+		struct service_t* s = &(serviceList->services[i]);
+		if (strcmp(s->serviceId.service_uuid, serviceUUID) == 0)
+			return s;
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for struct deviceList_t
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct deviceList_t* create_device_list()
+{
+	struct deviceList_t* dList = g_malloc0(sizeof(struct deviceList_t));
+	if (dList == NULL)
+	{
+		DEBUG_PC("Memory Allocation Failure");
+		exit(-1);
+	}
+	return dList;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for struct linkList_t
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct linkList_t* create_link_list() {
+	struct linkList_t* lList = g_malloc0(sizeof(struct linkList_t));
+	if (lList == NULL)
+	{
+		DEBUG_PC("Memory Allocation Failure");
+		exit(-1);
+	}
+	lList->numLinks = 0;
+	return lList;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for struct serviceList_t
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct serviceList_t* create_service_list() {
+	struct serviceList_t* sList = g_malloc0(sizeof(struct serviceList_t));
+	if (sList == NULL)
+	{
+		DEBUG_PC("Memory Allocation Failure");
+		exit(-1);
+	}
+	return sList;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Friendly function to log the service type
+ * 
+ * @param type
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_service_type(guint type) {
+	switch (type) {
+	case SERVICE_TYPE_UNKNOWN:
+			DEBUG_PC("Service Type UNKNOWN");
+			break;
+		case SERVICE_TYPE_L3NM:
+			DEBUG_PC("Service Type L3NM");
+			break;
+		case SERVICE_TYPE_L2NM:
+			DEBUG_PC("Service Type L2NM");
+			break;
+		case SERVICE_TYPE_TAPI:
+			DEBUG_PC("Service Type L2NM");
+			break;
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Friendly function to log the port direction
+ *
+ * @param direction
+ *
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_link_port_direction(guint direction)
+{
+	switch (direction) {
+		case LINK_PORT_DIRECTION_BIDIRECTIONAL:
+			//DEBUG_PC("Bidirectional Port Direction");
+			break;
+		case LINK_PORT_DIRECTION_INPUT:
+			//DEBUG_PC("Input Port Direction");
+			break;
+		case LINK_PORT_DIRECTION_OUTPUT:
+			//DEBUG_PC("Output Port Direction");
+			break;
+		case LINK_PORT_DIRECTION_UNKNOWN:
+			//DEBUG_PC("Unknown Port Direction");
+			break;
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Friendly function to log the port termination direction
+ *
+ * @param direction
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_termination_direction(guint direction)
+{
+	switch (direction) {
+	case TERMINATION_DIRECTION_BIDIRECTIONAL:
+		//DEBUG_PC("Bidirectional Termination Direction");
+		break;
+	case TERMINATION_DIRECTION_SINK:
+		//DEBUG_PC("Input Termination Direction");
+		break;
+	case TERMINATION_DIRECTION_SOURCE:
+		//DEBUG_PC("Output Termination Direction");
+		break;
+	case TERMINATION_DIRECTION_UNKNOWN:
+		//DEBUG_PC("Unknown Termination Direction");
+		break;
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Friendly function to log the termination state
+ *
+ * @param state 
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_termination_state(guint state)
+{
+	switch (state) {
+	case TERMINATION_STATE_CAN_NEVER_TERMINATE:
+		//DEBUG_PC("Can never Terminate");
+		break;
+	case TERMINATION_STATE_NOT_TERMINATED:
+		DEBUG_PC("Not terminated");
+		break;
+	case TERMINATION_STATE_TERMINATED_SERVER_TO_CLIENT_FLOW:
+		DEBUG_PC("Terminated server to client flow");
+		break;
+	case TERMINATION_STATE_TERMINATED_CLIENT_TO_SERVER_FLOW:
+		DEBUG_PC("Terminated client to server flow");
+		break;
+	case TERMINATION_STATE_TERMINATED_BIDIRECTIONAL:
+		//DEBUG_PC("Terminated bidirectional");
+		break;
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Friendly function to log the capacity unit
+ *
+ * @param unit
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_capacity_unit(guint unit) {
+
+	switch (unit) {
+		case CAPACITY_UNIT_TB:
+			DEBUG_PC("Unit in TB");
+			break;
+		case CAPACITY_UNIT_TBPS:
+			DEBUG_PC("Unit in TB/s");
+			break;
+		case CAPACITY_UNIT_GB:
+			DEBUG_PC("Unit in GB");
+			break;
+		case CAPACITY_UNIT_GBPS:
+			DEBUG_PC("Unit in GB/s");
+			break;
+		case CAPACITY_UNIT_MB:
+			DEBUG_PC("Unit in MB");
+			break;
+		case CAPACITY_UNIT_MBPS:
+			//DEBUG_PC("Unit in MB/s");
+			break;
+		case CAPACITY_UNIT_KB:
+			DEBUG_PC("Unit in KB");
+			break;
+		case CAPACITY_UNIT_KBPS:
+			DEBUG_PC("Unit in KB/s");
+			break;
+		case CAPACITY_UNIT_GHZ: 
+			DEBUG_PC("Unit in GHz");
+			break;
+		case CAPACITY_UNIT_MHZ:
+			DEBUG_PC("Unit in MHz");
+			break;
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Friendly function to log the link forwarding direction
+ *
+ * @param linkFwDir
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_link_forwarding_direction(guint linkFwDir) {
+	switch (linkFwDir) {
+		case LINK_FORWARDING_DIRECTION_BIDIRECTIONAL:
+			DEBUG_PC("BIDIRECTIONAL LINK FORWARDING DIRECTION");
+			break;
+		case LINK_FORWARDING_DIRECTION_UNIDIRECTIONAL:
+			DEBUG_PC("UNIDIRECTIONAL LINK FORWARDING DIRECTION");
+			break;
+		case  LINK_FORWARDING_DIRECTION_UNKNOWN:
+			DEBUG_PC("UNKNOWN LINK FORWARDING DIRECTION");
+			break;
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Allocate memory for the contextSet
+ *
+ * @param 
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct contextSet_t* create_contextSet() {
+	struct contextSet_t* c = g_malloc0(sizeof(struct contextSet_t));
+	if (c == NULL) {
+		DEBUG_PC("Memory Allocation Failure");
+		exit(-1);
+	}
+	return c;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Search a specific contextUuid element into the contextSet
+ *
+ * @param contextUuid
+ * @param set
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct context_t* find_contextId_in_set(gchar* contextUuid, struct contextSet_t* set) {
+
+	g_assert(set);
+	//DEBUG_PC("Checking if contextId: %s in in the ContextList??", contextUuid);
+
+	for (gint i = 0; i < set->num_context_set; i++) { 	
+		struct context_t* c = &(set->contextList[i]);
+		//DEBUG_PC("Context Item [%d] Id: %s", i, c->contextId);
+		if (strcmp(contextUuid, c->contextId) == 0) {
+			//DEBUG_PC("contextId: %s is FOUND in the ContextSet_List", contextUuid);
+			return c;
+		}
+	}
+	//DEBUG_PC("contextId: %s NOT FOUND in the ContextSet_List", contextUuid);
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Add a specific context uuid into the context set
+ *
+ * @param contextUuid
+ * @param set
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct context_t* add_contextId_in_set(gchar *contextUuid, struct contextSet_t *set) {
+
+	set->num_context_set++;
+	struct context_t* c = &(set->contextList[set->num_context_set - 1]);
+	duplicate_string(c->contextId, contextUuid);
+	return c;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Find a vertex in a specific graph
+ *
+ * @param contextUuid
+ * @param set
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct vertices_t* find_vertex_in_graph_context(struct graph_t *g, gchar* deviceId) {
+
+	for (gint i = 0; i < g->numVertices; i++)
+	{
+		struct vertices_t* v = &(g->vertices[i]);
+		if (strcmp(v->verticeId.nodeId, deviceId) == 0) {
+			return v;
+		}
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Adding a deviceId into a graph
+ *
+ * @param g
+ * @param deviceId
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct vertices_t* add_vertex_in_graph(struct graph_t* g, gchar* deviceId) {
+	g->numVertices++;
+	struct vertices_t* v = &(g->vertices[g->numVertices - 1]);
+	duplicate_string(v->verticeId.nodeId, deviceId);
+	return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Construct the graphs (vertices and edges) bound to every individual context
+ *
+ * @param cSet
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void build_contextSet_deviceList(struct contextSet_t* cSet) {
+	// Check every device their endpoints
+	for (gint i = 0; i < deviceList->numDevices; i++) {
+		struct device_t* d = &(deviceList->devices[i]);
+		//DEBUG_PC("Exploring DeviceId: %s", d->deviceId);
+
+		// Check the associated endPoints
+		for (gint j = 0; j < d->numEndPoints; j++) {
+			struct endPoint_t* eP = &(d->endPoints[j]);
+			// Get endPointId (topology, context, device Id and endpoint uuid)
+			struct endPointId_t* ePid = &(eP->endPointId);  //end point id
+			//DEBUG_PC("   EndPointId: %s || Type: %s", eP->endPointId.endpoint_uuid, d->deviceType);
+			//DEBUG_PC("   TopologyId: %s || ContextId: %s", eP->endPointId.topology_id.topology_uuid, eP->endPointId.topology_id.contextId);
+
+			// Add contextId in ContextSet and the deviceId (+endpoint) into the vertex set
+			struct context_t *c = find_contextId_in_set(eP->endPointId.topology_id.contextId, cSet);
+			if (c == NULL) {
+				//DEBUG_PC("   contextUuid: %s MUST BE ADDED to ContextSet", eP->endPointId.topology_id.contextId);
+				c = add_contextId_in_set(eP->endPointId.topology_id.contextId, cSet);
+			}
+			// Check if the deviceId and endPointUuid are already considered in the graph of the context c
+			struct vertices_t* v = find_vertex_in_graph_context(&c->g, d->deviceId);
+			if (v == NULL) {
+				//DEBUG_PC("  deviceId: %s MUST BE ADDED to the Context Graph", d->deviceId);
+				v = add_vertex_in_graph(&c->g, d->deviceId);
+			}
+		}
+	}
+	//print_contextSet(cSet);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Determine whether a deviceId is in the targetNode list of a specific vertex v
+ *
+ * @param v
+ * @param deviceId
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct targetNodes_t* find_targeted_vertex_in_graph_context(struct vertices_t* v, gchar *deviceId) {
+	for (gint k = 0; k < v->numTargetedVertices; k++) {
+		struct targetNodes_t* w = &(v->targetedVertices[k]);
+		if (strcmp(w->tVertice.nodeId, deviceId) == 0) {
+			return w;
+		}
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Add a deviceId a targetNode of a specific vertex v
+ *
+ * @param v
+ * @param deviceId
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct targetNodes_t* add_targeted_vertex_in_graph_context(struct vertices_t* v, gchar* bDeviceId) {
+	v->numTargetedVertices++;
+	struct targetNodes_t* w = &(v->targetedVertices[v->numTargetedVertices - 1]);
+	duplicate_string(w->tVertice.nodeId, bDeviceId);
+	return w;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Returns the structure of a device endpoint bound to a specific deviceId and endPointId
+ *
+ * @param devId
+ * @param endPointUuid
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct endPoint_t* find_device_tied_endpoint(gchar* devId, gchar* endPointUuid) {
+	//DEBUG_PC("devId: %s ePId: %s", devId, endPointUuid);
+	for (gint i = 0; i < deviceList->numDevices; i++) {
+		struct device_t* d = &(deviceList->devices[i]);
+		if (strcmp(d->deviceId, devId) != 0) {
+			continue;
+		}
+		// Iterate over the endpoints tied to the deviceId
+		for (gint j = 0; j < d->numEndPoints; j++) {
+			struct endPoint_t* eP = &(d->endPoints[j]);
+			//DEBUG_PC("looked endPointId: %s", eP->endPointId.endpoint_uuid);
+			if (strcmp(eP->endPointId.endpoint_uuid, endPointUuid) == 0) {
+				return eP;
+			}
+		}
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Adding the edge/linnk in the targetedNodes w list
+ *
+ * @param w
+ * @param l
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void add_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l) {
+	//DEBUG_PC("\t targetedVertex: %s", w->tVertice.nodeId);
+	w->numEdges++;
+	struct edges_t* e = &(w->edges[w->numEdges - 1]);
+	// Copy the link Id UUID
+	duplicate_string(e->linkId, l->linkId);
+
+	// copy the deviceId and endpointsIds (A --> Z)
+	struct link_endpointId_t* aEndpointId = &(l->linkEndPointId[0]);
+	duplicate_string(e->aNodeId.nodeId, aEndpointId->deviceId);
+	duplicate_string(e->aEndPointId, aEndpointId->endPointId);
+	duplicate_string(e->aTopologyId, aEndpointId->topology_id.topology_uuid);
+
+	struct link_endpointId_t* zEndpointId = &(l->linkEndPointId[1]);
+	duplicate_string(e->zNodeId.nodeId, zEndpointId->deviceId);
+	duplicate_string(e->zEndPointId, zEndpointId->endPointId);
+	duplicate_string(e->zTopologyId, zEndpointId->topology_id.topology_uuid);
+
+	// The potential and available capacity is indeed retrieved using aEndpointId in the deviceList
+	struct endPoint_t* eP = find_device_tied_endpoint(aEndpointId->deviceId, aEndpointId->endPointId);
+	if (eP == NULL) {
+		DEBUG_PC("devId: %s endPointUuid: %s NOT in Device List!!--- Weird", aEndpointId->deviceId, aEndpointId->endPointId);
+		exit(-1);
+	}
+	//Potential(total) and available capacity
+	e->unit = eP->potential_capacity.unit;
+	memcpy(&e->totalCap, &eP->potential_capacity.value, sizeof(gdouble));
+	memcpy(&e->availCap, &eP->available_capacity.value, sizeof(gdouble));
+
+	// Copy interdomain local/remote Ids
+	memcpy(e->interDomain_localId, eP->inter_domain_plug_in.inter_domain_plug_in_local_id, 
+		strlen(eP->inter_domain_plug_in.inter_domain_plug_in_local_id));
+	memcpy(e->interDomain_remoteId, eP->inter_domain_plug_in.inter_domain_plug_in_remote_id,
+		strlen(eP->inter_domain_plug_in.inter_domain_plug_in_remote_id));
+
+	// cost value
+	memcpy(&e->cost, &l->cost_characteristics.cost_value, sizeof(gdouble));
+
+	// latency
+	memcpy(&e->delay, &l->latency_characteristics.fixed_latency, sizeof(gdouble));
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Searching a specific edge/link by the linkId(UUID)
+ *
+ * @param w
+ * @param l
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct edges_t* find_edge_in_targetedVertice_set(struct targetNodes_t* w, struct link_t* l) {
+		
+	for (gint i = 0; i < w->numEdges; i++) {
+		struct edges_t* e = &(w->edges[i]);
+		if (strcmp(e->linkId, l->linkId) == 0) {
+			return e;
+		}
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief supporting the construction of the graph per context using the explicit
+ * contents/info of the link list
+ *
+ * @param set
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void build_contextSet_linklList(struct contextSet_t* set) {
+	g_assert(set);
+	
+	// for each link in linkList:
+	// 1st- Retrieve endpoints A --> B feauture (context Id, device Id, endpoint Id)
+	// 2st - In the graph associated to the contextId, check wheter A (deviceId) is in the vertices list
+	// o No, this is weird ... exist
+	// o Yes, get the other link endpoint (i.e., B) and check whether it exists. If NOT add it, considering
+	// all the attributes; Otherwise, check whether the link is different from existing edges between A and B
+
+	for (gint j = 0; j < linkList->numLinks; j++) {
+		struct link_t* l = &(linkList->links[j]);
+		// link assumed to be P2P A --> B; I.e. 2 endPoints; 1st specifies A and 2nd specifie B
+		struct link_endpointId_t* aEndpointId = &(l->linkEndPointId[0]);
+		struct topology_id_t* topologyId = &(aEndpointId->topology_id);
+		// get the contextId
+		gchar contextUuid[UUID_CHAR_LENGTH];
+		duplicate_string(contextUuid, topologyId->contextId);
+		//DEBUG_PC("Link: %s in Context: %s", l->linkId, contextUuid);
+
+		// Check first contextUuid exists in the cSet
+		struct context_t* c = find_contextId_in_set(contextUuid, set);
+		if (c == NULL) {
+			DEBUG_PC("ContextId: %s does NOT exist... weird", contextUuid);
+			exit(-1);
+		}
+
+		// get the device ID of A
+		gchar aDeviceId[UUID_CHAR_LENGTH];
+		duplicate_string(aDeviceId, aEndpointId->deviceId);
+
+		struct graph_t* g = &(c->g); // get the graph associated to the context c
+		struct vertices_t* v = find_vertex_in_graph_context(g, aDeviceId);
+		if (v == NULL) {
+			DEBUG_PC("aDeviceId: %s IS NOT IN Vertices of contextId: %s", aDeviceId, contextUuid);
+			exit(-1);
+		}		
+		// get the bEndpointId
+		struct link_endpointId_t* bEndpointId = &(l->linkEndPointId[1]);
+		gchar bDeviceId[UUID_CHAR_LENGTH];
+		duplicate_string(bDeviceId, bEndpointId->deviceId);
+		// Check whether device B is in the targeted Vertices from A (i.e., v)?
+		// If not, add B in the targeted vertices B + create the edge and add it
+		// If B exist, check whether the explored link/edge is already in the list of edges
+		struct targetNodes_t* w = find_targeted_vertex_in_graph_context(v, bDeviceId);
+		if (w == NULL) {
+			//DEBUG_PC("B device [%s] is PEER of A device [%s]", bDeviceId, v->verticeId.nodeId);
+			w = add_targeted_vertex_in_graph_context(v, bDeviceId);
+			add_edge_in_targetedVertice_set(w, l);
+		}
+		else {
+			// w exists, it is needed to check whether the edge (link) should be added
+			struct edges_t* e = find_edge_in_targetedVertice_set(w, l);
+			if (e == NULL) {
+				// Add the link into the list
+				add_edge_in_targetedVertice_set(w, l);
+			}
+			else {
+				DEBUG_PC("The link already exists ...");
+				continue;
+			}
+		}
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Create the set of (distinct) contexts with the deviceList and linkList
+ *
+ * @param cSet
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void build_contextSet(struct contextSet_t* cSet) {
+	g_assert(cSet);
+	g_assert(deviceList);
+	g_assert(linkList);
+
+	// devices are tied to contexts, i.e. depending on the contextId of the devices
+	build_contextSet_deviceList(cSet);
+
+	// Once the diverse contexts are created and the devices/endpoints asigned to the 
+	// respective graph tied to each context, it is needed to create the edges
+	build_contextSet_linklList(cSet);
+
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Print the contents of the ContextIds
+ *
+ * @param set
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_contextSet(struct contextSet_t* set) {
+	g_assert(set);
+
+	for (gint i = 0; i < set->num_context_set; i++) {
+		struct context_t* c = &(set->contextList[i]);
+		DEBUG_PC("-------------------------------------------------------------");
+		DEBUG_PC(" Context Id: %s", c->contextId);
+		DEBUG_PC("-------------------------------------------------------------");
+
+		struct graph_t* g = &(c->g);
+		for (gint j = 0; j < g->numVertices; j++) {
+			struct vertices_t* v = &(g->vertices[j]);
+			DEBUG_PC("  Head Device Id: %s", v->verticeId.nodeId);
+			for (gint k = 0; k < v->numTargetedVertices; k++) {
+				struct targetNodes_t* w = &(v->targetedVertices[k]);
+				DEBUG_PC("  [%d] --- Peer Device Id: %s", k, w->tVertice.nodeId);
+				for (gint l = 0; l < w->numEdges; l++) {
+					struct edges_t* e = &(w->edges[l]);
+					DEBUG_PC("   \t link Id: %s", e->linkId);
+					DEBUG_PC("   \t aEndPointId: %s", e->aEndPointId);
+					DEBUG_PC("   \t zEndPointId: %s", e->zEndPointId);
+					DEBUG_PC("   \t Available Capacity: %f, Latency: %f, Cost: %f", e->availCap, e->delay, e->cost);
+					DEBUG_PC("   \t aTopologyId: %s", e->aTopologyId);
+					DEBUG_PC("   \t zTopologyId: %s", e->zTopologyId);
+				}
+			}
+		}
+	}
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Check whether src and dst PE nodeId of the req are the same
+ *
+ *	@param r
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+gint same_src_dst_pe_nodeid(struct service_t* s)
+{
+	// Check that source PE and dst PE are NOT the same, i.e., different ingress and egress endpoints (iEp, eEp)
+	struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]);
+	struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]);
+
+	gchar* iEpUUID = iEp->endpoint_uuid;
+	gchar* eEpUUID = eEp->endpoint_uuid;
+	gchar* iDevUUID = iEp->device_uuid;
+	gchar* eDevUUID = eEp->device_uuid;
+
+	// Compare the device uuids
+	if (strcmp(iDevUUID, eDevUUID) != 0) {
+		DEBUG_PC("DIFFERENT --- iDevId: %s and eDevId: %s", iDevUUID, eDevUUID);
+		return 1;
+	}
+	// Compare the endpoints (ports)
+	if (strcmp(iEpUUID, eEpUUID) != 0) {
+		DEBUG_PC("DIFFERENT --- iEpUUID: %s and eEpUUID: %s", iEpUUID, eEpUUID);
+		return 1;
+	}
+	return 0;	
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Handles issues with the route computation
+ *
+ *	@param route
+ *	@param s
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void comp_route_connection_issue_handler (struct compRouteOutput_t *path, struct service_t *s)
+{
+	g_assert(path);
+	g_assert(s);
+
+	// Increase the number of computed routes/paths despite there was an issue to be reported		
+	path->numPaths++;	
+	// Copy the serviceId
+	copy_service_id(&(path->serviceId), &(s->serviceId));
+
+	// copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services)
+	for (gint i = 0; i < s->num_service_endpoints_id; i++) {
+		struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]);
+		struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]);
+		copy_service_endpoint_id(oEp, iEp);
+	}
+	path->num_service_endpoints_id = s->num_service_endpoints_id;
+	path->noPathIssue = NO_PATH_CONS_ISSUE;
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief released the allocated memory fo compRouteOutputList_t
+ *
+ *	@param ro
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void destroy_compRouteOutputList (struct compRouteOutputList_t *ro)
+{
+	g_assert (ro);	
+	g_free (ro);	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief creates a copy of the underlying graph
+ *
+ *	@param originalGraph
+ *	@param destGraph
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void duplicate_graph (struct graph_t *originalGraph, struct graph_t *destGraph)	{
+	g_assert (originalGraph);
+	g_assert (destGraph);
+	
+	destGraph->numVertices = originalGraph->numVertices;
+	for (gint i = 0; i < originalGraph->numVertices; i++) {
+		struct vertices_t *oVertex = &(originalGraph->vertices[i]);
+		struct vertices_t *dVertex = &(destGraph->vertices[i]);
+		dVertex->numTargetedVertices = oVertex->numTargetedVertices;		
+		duplicate_node_id (&oVertex->verticeId, &dVertex->verticeId);
+		
+		for (gint j = 0; j < oVertex->numTargetedVertices; j++)	{
+			struct targetNodes_t *oTargetedVertex = &(oVertex->targetedVertices[j]);
+			struct targetNodes_t *dTargetedVertex = &(dVertex->targetedVertices[j]);
+			duplicate_node_id (&oTargetedVertex->tVertice, &dTargetedVertex->tVertice);
+			dTargetedVertex->numEdges = oTargetedVertex->numEdges;
+			
+			for (gint k = 0; k < oTargetedVertex->numEdges; k++) {
+				struct edges_t *oEdge = &(oTargetedVertex->edges[k]);
+				struct edges_t *dEdge = &(dTargetedVertex->edges[k]);
+				duplicate_edge (dEdge, oEdge);						
+			}
+		}	
+	}	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to retrieve from the graph the edge instance associated to the
+ * pathLink (pL)
+ *
+ *	@param pL
+ *	@parma g
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct edges_t* get_edge_from_graph_by_linkId(struct pathLink_t* pL, struct graph_t* g) {
+	g_assert(pL);
+	g_assert(g);
+
+	for (gint i = 0; i < g->numVertices; i++) {
+		struct vertices_t* v = &(g->vertices[i]);
+		for (gint j = 0; j < v->numTargetedVertices; j++) {
+			struct targetNodes_t* tv = &(v->targetedVertices[j]);
+			for (gint k = 0; k < tv->numEdges; k++) {
+				struct edges_t* e = &(tv->edges[k]);
+				if (strcmp(e->linkId, pL->linkId) == 0) {
+					return e;
+				}
+			}		
+		}
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to retrieve from the graph the reverse edge (rev_e) associated to an edge (e)
+ *
+ *	@param e
+ *	@parma g
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+struct edges_t* get_reverse_edge_from_the_graph(struct edges_t* e, struct graph_t* g) {
+	g_assert(e);
+	g_assert(g);
+
+	for (gint i = 0; i < g->numVertices; i++) {
+		struct vertices_t* v = &(g->vertices[i]);
+		// Check Route Element zNodeId with the v->verticeId
+		if (compare_node_id(&e->zNodeId, &v->verticeId) != 0)
+			continue;
+		// Check Route Element zNodeis with any of reachable targeted vertices from v
+		gboolean foundTargVert = FALSE;
+		gint indexTargVert = -1;
+		for (gint j = 0; j < v->numTargetedVertices; j++) {
+			struct targetNodes_t* tv = &(v->targetedVertices[j]);
+			if (compare_node_id(&e->aNodeId, &tv->tVertice) == 0)
+			{
+				foundTargVert = TRUE;
+				indexTargVert = j;
+				break;
+			}
+		}
+		if (foundTargVert == FALSE) {
+			 continue;
+		}			
+
+		// The targeted vertice is found, then check matching with the endpoints
+		struct targetNodes_t* tv = &(v->targetedVertices[indexTargVert]);
+		for (gint k = 0; k < tv->numEdges; k++) {
+			struct edges_t* rev_e = &(tv->edges[k]);
+			if ((strcmp(rev_e->aEndPointId, e->zEndPointId) == 0) &&
+				(strcmp(rev_e->zEndPointId, e->aEndPointId) == 0)) {
+				return rev_e;
+			}				
+		}
+	}
+	return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to reflect in the graph the assigned/allocated resources contained in the path p
+ * 	considering the needs (e.g., bandwidth) of service s
+ *
+ *	@param p
+ *	@param s
+ *	@parma g
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2022
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+void allocate_graph_resources (struct path_t *p, struct service_t *s, struct graph_t *g)
+{
+	g_assert (p);
+	g_assert (s);
+	g_assert (g);
+	// Retrieve the requested bw by the service
+	struct path_constraints_t* pathCons = get_path_constraints(s);
+
+	for (gint i = 0; i < p->numPathLinks; i++) {
+		struct pathLink_t* pL = &(p->pathLinks[i]);
+		// get the edge associated to the linkId in the graph
+		struct edges_t* e = get_edge_from_graph_by_linkId(pL, g);
+		if (e == NULL) {
+			DEBUG_PC("The linkId: %s is NOT found in the Graph!!!", pL->linkId);
+			exit(-1);
+		}
+		//Update the availBw in the edge
+		gdouble resBw = e->availCap - pathCons->bwConstraint;
+		DEBUG_PC("Updating the Avail Bw @ edge/link: %s", e->linkId);
+		DEBUG_PC("Initial avaiCap @ e/link: %f, demanded Bw: %f, resulting Avail Bw: %f", e->availCap, pathCons->bwConstraint, resBw);
+		memcpy(&e->availCap, &resBw, sizeof(gdouble));
+		DEBUG_PC("Final e/link avail Bw: %f", e->availCap);	
+	}
+	g_free(pathCons);
+	
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to reflect in the graph the assigned/allocated resources contained in the reverse direction of the path p
+ * 	considering the needs (e.g., bandwidth) of service s
+ *
+ *	@param p
+ *	@param s
+ *	@parma g
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2021
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void allocate_graph_reverse_resources(struct path_t* p, struct service_t * s, struct graph_t* g)
+{
+	g_assert(p);
+	g_assert(s);
+	g_assert(g);
+
+	struct path_constraints_t* pathCons = get_path_constraints(s);
+	for (gint i = 0; i < p->numPathLinks; i++) {
+		struct pathLink_t* pL = &(p->pathLinks[i]);
+		struct edges_t* e = get_edge_from_graph_by_linkId(pL, g);
+		if (e == NULL) {
+			DEBUG_PC("The linkId: %s is NOT found in the Graph!!!", pL->linkId);
+			exit(-1);
+		}
+		struct edges_t* rev_e = get_reverse_edge_from_the_graph(e, g);
+		if (rev_e == NULL) {
+			DEBUG_PC("the reverse edge of linkId: %s is NOT found in the Graph!!!", pL->linkId);
+			exit(-1);
+		}
+		//Update the availBw in the edge
+		gdouble resBw = rev_e->availCap - pathCons->bwConstraint;
+		DEBUG_PC("Updating the Avail Bw @ reverse edge/link: %s", rev_e->linkId);
+		DEBUG_PC("Initial avaiCap @ reverse edge e/link: %f, demanded Bw: %f, resulting Avail Bw: %f", rev_e->availCap, pathCons->bwConstraint, resBw);
+		memcpy(&rev_e->availCap, &resBw, sizeof(gdouble));
+		DEBUG_PC("Final reverse edge e/link avail Bw: %f", rev_e->availCap);
+	}
+	g_free(pathCons);
+	return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief Function used to printall the computed paths for the requested network connectivity services
+ *
+ *	@param routeList
+ *
+ * 	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2021
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void print_path_connection_list(struct compRouteOutputList_t* routeList) {
+	g_assert(routeList);
+	for (gint i = 0; i < routeList->numCompRouteConnList; i++) {
+		DEBUG_PC("==================== Service Item: %d ===================", i);
+		struct compRouteOutput_t* rO = &(routeList->compRouteConnection[i]);
+		DEBUG_PC("num service endpoints: %d", rO->num_service_endpoints_id);
+		struct serviceId_t* s = &(rO->serviceId);
+		DEBUG_PC("ContextId: %s, ServiceId: %s", s->contextId, s->service_uuid);
+		DEBUG_PC("ingress --- %s [%s]", rO->service_endpoints_id[0].device_uuid, 
+			rO->service_endpoints_id[0].endpoint_uuid);
+		DEBUG_PC("egress --- %s [%s]", rO->service_endpoints_id[1].device_uuid,
+			rO->service_endpoints_id[1].endpoint_uuid);
+
+		if (rO->noPathIssue == NO_PATH_CONS_ISSUE) {
+			DEBUG_PC("NO PATH SUCCESSFULLY COMPUTED");
+			continue;
+		}
+		// Path
+		DEBUG_PC("Number of paths: %d", rO->numPaths);
+		for (gint j = 0; j < rO->numPaths; j++) {
+			struct path_t* p = &(rO->paths[j]);
+			print_path_t(p);
+		}
+	}
+	return;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@file pathComp_tools.c
+ * 	@brief update statistics for the path computation operations
+ *
+ *  @param routeConnList
+ *	@param d
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2021
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void update_stats_path_comp(struct compRouteOutputList_t* routeConnList, struct timeval d, gint numSuccesPathComp, gint numPathCompIntents) {
+	g_assert(routeConnList);
+
+	total_path_comp_time.tv_sec = total_path_comp_time.tv_sec + d.tv_sec;
+	total_path_comp_time.tv_usec = total_path_comp_time.tv_usec + d.tv_usec;
+	total_path_comp_time = tv_adjust(total_path_comp_time);
+
+	gdouble path_comp_time_msec = (((total_path_comp_time.tv_sec) * 1000) + ((total_path_comp_time.tv_usec) / 1000));
+	gdouble av_alg_comp_time = ((path_comp_time_msec / numSuccesPathComp));
+	DEBUG_PC("\t --- STATS PATH COMP ----");
+	DEBUG_PC("Succesfully Comp: %d | Path Comp Requests: %d", numSuccesPathComp, numPathCompIntents);
+	DEBUG_PC("AV. PATH COMP ALG. TIME: %f ms", av_alg_comp_time);
+
+	for (gint i = 0; i < serviceList->numServiceList; i++) {
+		struct service_t* s = &(serviceList->services[i]);
+		char* eptr;
+		for (gint j = 0; j < s->num_service_constraints; j++) {
+			struct constraint_t* constraints = &(s->constraints[j]);
+			if (strncmp((const char*)(constraints->constraint_type), "bandwidth", 9) == 0) {
+				totalReqBw += (gdouble)(strtod((char*)constraints->constraint_value, &eptr));
+			}
+		}
+	}
+	for (gint k = 0; k < routeConnList->numCompRouteConnList; k++) {
+		struct compRouteOutput_t* rO = &(routeConnList->compRouteConnection[k]);
+		if (rO->noPathIssue == NO_PATH_CONS_ISSUE) {
+			continue;
+		}
+		// Get the requested service bw bound to that computed path
+		struct path_t* p = &(rO->paths[0]);
+		struct service_t* s = get_service_for_computed_path(rO->serviceId.service_uuid);
+		if (s == NULL) {
+			DEBUG_PC("Weird the service associated to a path is not found");
+			exit(-1);
+		}
+		for (gint l = 0; l < s->num_service_constraints; l++) {
+			struct constraint_t* constraints = &(s->constraints[l]);
+			char* eptr;
+			if (strncmp((const char*)(constraints->constraint_type), "bandwidth", 9) == 0) {
+				totalServedBw += (gdouble)(strtod((char*)constraints->constraint_value, &eptr));
+			}
+		}
+	}
+	gdouble avServedRatio = totalServedBw / totalReqBw;
+	DEBUG_PC("AV. Served Ratio: %f", avServedRatio);
+	gdouble avBlockedBwRatio = (gdouble)(1.0 - avServedRatio);
+	DEBUG_PC("AV. BBE: %f", avBlockedBwRatio);
+	return;
+
+}
diff --git a/src/pathcomp/backend/pathComp_tools.h b/src/pathcomp/backend/pathComp_tools.h
new file mode 100644
index 0000000000000000000000000000000000000000..8fe704c3932c219e0f04046fcc62d6f1da5f9b66
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_tools.h
@@ -0,0 +1,617 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# Copyright 2022 Centre Tecnol�gic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Author: CTTC/CERCA PONS RU Ricardo Mart�nez (ricardo.martinez@cttc.es)
+ */
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PATHCOMP_TOOLS_H
+#define _PATHCOMP_TOOLS_H
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-2.0/glib/gtypes.h>
+#include <uuid/uuid.h>
+
+// External variables
+extern struct map_nodes_t* mapNodes;
+extern struct graph_t* graph;
+extern struct contextSet_t* contextSet;
+extern struct linkList_t* linkList;
+extern struct deviceList_t* deviceList;
+extern struct serviceList_t* serviceList;
+
+#define INFINITY_COST                   0xFFFFFFFF
+#define MAX_NUM_PRED					100
+
+#define MAX_KSP_VALUE					3
+
+// HTTP RETURN CODES
+#define HTTP_CODE_OK					200
+#define HTTP_CODE_CREATED 				201
+#define HTTP_CODE_BAD_REQUEST    		400
+#define HTTP_CODE_UNAUTHORIZED   		401
+#define HTTP_CODE_FORBIDDEN      		403
+#define HTTP_CODE_NOT_FOUND				404
+#define HTTP_CODE_NOT_ACCEPTABLE		406
+
+#define MAX_NODE_ID_SIZE				37 // UUID 128 Bits - In hexadecimal requires 36 char
+#define MAX_CONTEXT_ID					37
+//#define UUID_CHAR_LENGTH				37
+#define UUID_CHAR_LENGTH				100
+struct nodes_t {
+	gchar nodeId[UUID_CHAR_LENGTH];
+};
+
+struct nodeItem_t {
+    struct nodes_t node;
+    gdouble distance;
+	gdouble latency;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Structures for collecting the RL topology including: intra WAN topology and inter-WAN links
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define MAX_INTER_DOMAIN_PLUG_IN_SIZE					128
+struct edges_t {	
+	//aNodeId/Device Id
+	struct nodes_t aNodeId;	
+	//zNodeId/Device Id
+	struct nodes_t zNodeId;	
+	
+	// UUID of the endPointIds
+	gchar aEndPointId[UUID_CHAR_LENGTH];
+	gchar zEndPointId[UUID_CHAR_LENGTH];
+
+	// UUID of the link
+	gchar linkId[UUID_CHAR_LENGTH];
+
+	// Potential(total) and available capacity
+	gint unit;
+	gdouble totalCap, availCap;
+	
+	gdouble cost;	
+	gdouble delay;	
+
+	// inter-domain local and remote Ids
+	gchar interDomain_localId[MAX_INTER_DOMAIN_PLUG_IN_SIZE];
+	gchar interDomain_remoteId[MAX_INTER_DOMAIN_PLUG_IN_SIZE];
+
+	gchar aTopologyId[UUID_CHAR_LENGTH];
+	gchar zTopologyId[UUID_CHAR_LENGTH];
+};
+
+// Structure to handle the path computation
+struct pred_comp_t {
+	struct nodes_t v;
+	struct edges_t e;	
+};
+
+struct pred_t {
+    struct pred_comp_t predComp[MAX_NUM_PRED];
+    gint numPredComp;
+};
+
+// Structures for the managing the path computation algorithm
+struct map_t {
+	struct nodes_t verticeId;
+	struct edges_t predecessor;
+	gdouble distance;
+	gdouble avaiBandwidth;
+	gdouble latency;	
+};
+
+#define MAX_MAP_NODE_SIZE				100
+struct map_nodes_t {
+    struct map_t map[MAX_MAP_NODE_SIZE];
+    gint numMapNodes;
+};
+
+#define MAX_NUM_VERTICES				20 // 100 # LGR: reduced from 100 to 20 to divide by 5 the memory used
+#define MAX_NUM_EDGES					10 // 100 # LGR: reduced from 100 to 10 to divide by 10 the memory used
+// Structures for the graph composition
+struct targetNodes_t {
+	// remote / targeted node
+	struct nodes_t tVertice;
+	// edge conencting a pair of vertices
+	struct edges_t edges[MAX_NUM_EDGES];	
+	gint numEdges; 
+};
+
+struct vertices_t {
+	struct targetNodes_t targetedVertices[MAX_NUM_VERTICES];
+	gint numTargetedVertices;
+    struct nodes_t verticeId;
+};
+
+struct graph_t {
+	struct vertices_t vertices[MAX_NUM_VERTICES];
+	gint numVertices;	
+};
+
+////////////////////////////////////////////////////
+// Structure for the Set of Contexts
+///////////////////////////////////////////////////
+struct context_t {
+	gchar contextId[UUID_CHAR_LENGTH]; // UUID char format 36 chars
+	// conext Id has a graph associated
+	struct graph_t g;
+};
+
+////////////////////////////////////////////////////
+// Structure for the Set of Contexts
+///////////////////////////////////////////////////
+#define MAX_NUMBER_CONTEXT		5 // 100 # LGR: reduced from 100 to 5 to divide by 20 the memory used
+struct contextSet_t {
+	struct context_t contextList[MAX_NUMBER_CONTEXT];
+	gint num_context_set;
+};
+
+#define MAX_ALG_ID_LENGTH		10
+////////////////////////////////////////////////////
+// External Variables
+///////////////////////////////////////////////////
+extern gchar algId[MAX_ALG_ID_LENGTH];
+
+////////////////////////////////////////////////////
+// Structure for the Requested Transport Connectivity Services
+///////////////////////////////////////////////////
+#define SERVICE_TYPE_UNKNOWN			0
+#define SERVICE_TYPE_L3NM				1
+#define SERVICE_TYPE_L2NM				2
+#define SERVICE_TYPE_TAPI				3
+
+///////////////////////////////////////////////////////////////////
+// Structure for the topology_id
+///////////////////////////////////////////////////////////////////
+struct topology_id_t {
+	gchar contextId[UUID_CHAR_LENGTH];
+	gchar topology_uuid[UUID_CHAR_LENGTH];
+};
+
+struct inter_domain_plug_in_t {
+	gchar inter_domain_plug_in_local_id[MAX_INTER_DOMAIN_PLUG_IN_SIZE];
+	gchar inter_domain_plug_in_remote_id[MAX_INTER_DOMAIN_PLUG_IN_SIZE];
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the endPointId
+///////////////////////////////////////////////////////////////////
+struct endPointId_t {
+	struct topology_id_t topology_id;
+	gchar device_id[UUID_CHAR_LENGTH];
+	gchar endpoint_uuid[UUID_CHAR_LENGTH];
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the endPoint
+///////////////////////////////////////////////////////////////////
+#define CAPACITY_UNIT_TB									0
+#define CAPACITY_UNIT_TBPS									1
+#define CAPACITY_UNIT_GB									2
+#define CAPACITY_UNIT_GBPS									3
+#define CAPACITY_UNIT_MB									4
+#define CAPACITY_UNIT_MBPS									5
+#define CAPACITY_UNIT_KB									6
+#define CAPACITY_UNIT_KBPS									7
+#define CAPACITY_UNIT_GHZ									8
+#define CAPACITY_UNIT_MHZ									9
+struct capacity_t {
+	gdouble value;
+	gint unit;
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the endPoint
+///////////////////////////////////////////////////////////////////
+#define MAX_ENDPOINT_TYPE_SIZE								128
+// Link Port Direction
+#define LINK_PORT_DIRECTION_BIDIRECTIONAL					0
+#define LINK_PORT_DIRECTION_INPUT							1
+#define LINK_PORT_DIRECTION_OUTPUT							2
+#define LINK_PORT_DIRECTION_UNKNOWN							3
+// Termination Direction
+#define TERMINATION_DIRECTION_BIDIRECTIONAL					0
+#define TERMINATION_DIRECTION_SINK							1
+#define TERMINATION_DIRECTION_SOURCE						2
+#define TERMINATION_DIRECTION_UNKNOWN						3
+// Termination State
+#define TERMINATION_STATE_CAN_NEVER_TERMINATE				0
+#define TERMINATION_STATE_NOT_TERMINATED					1
+#define TERMINATION_STATE_TERMINATED_SERVER_TO_CLIENT_FLOW	2
+#define TERMINATION_STATE_TERMINATED_CLIENT_TO_SERVER_FLOW	3
+#define TERMINATION_STATE_TERMINATED_BIDIRECTIONAL			4
+
+struct endPoint_t {
+	struct endPointId_t endPointId;
+	gchar endpointType[MAX_ENDPOINT_TYPE_SIZE];
+	guint link_port_direction;
+	guint termination_direction;
+	guint termination_state;
+	struct capacity_t potential_capacity;
+	struct capacity_t available_capacity;
+	// inter-domain identifiers
+	struct inter_domain_plug_in_t inter_domain_plug_in;
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the device contents
+///////////////////////////////////////////////////////////////////
+#define MAX_DEV_TYPE_SIZE				128
+#define MAX_DEV_ENDPOINT_LENGTH			10
+struct device_t {
+	gchar deviceId[UUID_CHAR_LENGTH]; // device ID using UUID (128 bits)
+
+	gchar deviceType[MAX_DEV_TYPE_SIZE]; // Specifies the device type
+
+	// define the endpoints attached to the device
+	gint numEndPoints;
+	struct endPoint_t endPoints[MAX_DEV_ENDPOINT_LENGTH];
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the device List
+///////////////////////////////////////////////////////////////////
+#define MAX_NUM_DEVICE		200
+struct deviceList_t {
+	// device information
+	gint numDevices;
+	struct device_t devices[MAX_NUM_DEVICE];
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the link EndPoint Id
+///////////////////////////////////////////////////////////////////
+struct link_endpointId_t {
+	struct topology_id_t topology_id;
+	gchar deviceId[UUID_CHAR_LENGTH];  // Device UUID
+	gchar endPointId[UUID_CHAR_LENGTH];	// Link EndPoint UUID
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the link cost characteristics
+///////////////////////////////////////////////////////////////////
+#define LINK_COST_NAME_SIZE								128
+struct cost_characteristics_t {
+	gchar cost_name[LINK_COST_NAME_SIZE];
+	gdouble cost_value;
+	gdouble cost_algorithm;
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the latency characteristics of the link
+///////////////////////////////////////////////////////////////////
+struct latency_characteristics_t {
+	gdouble fixed_latency;
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the link 
+///////////////////////////////////////////////////////////////////
+#define MAX_NUM_LINK_ENDPOINT_IDS								2
+
+#define LINK_FORWARDING_DIRECTION_BIDIRECTIONAL					0
+#define LINK_FORWARDING_DIRECTION_UNIDIRECTIONAL				1
+#define LINK_FORWARDING_DIRECTION_UNKNOWN						2
+struct link_t {
+	gchar linkId[UUID_CHAR_LENGTH]; // link Id using UUID (128 bits)
+
+	gint numLinkEndPointIds;
+	struct link_endpointId_t linkEndPointId[MAX_NUM_LINK_ENDPOINT_IDS];
+
+	guint forwarding_direction;
+	struct capacity_t potential_capacity;
+	struct capacity_t available_capacity;
+	struct cost_characteristics_t cost_characteristics;
+	struct latency_characteristics_t latency_characteristics;
+};
+
+///////////////////////////////////////////////////////////////////
+// Structure for the link List
+///////////////////////////////////////////////////////////////////
+#define MAX_NUM_LIST							2000
+struct linkList_t {
+	gint numLinks;
+	struct link_t links[MAX_NUM_LIST];
+};
+
+////////////////////////////////////////////////////
+// Structure for service Identifier
+///////////////////////////////////////////////////
+struct serviceId_t {
+	gchar contextId[UUID_CHAR_LENGTH];
+	gchar service_uuid[UUID_CHAR_LENGTH];
+};
+
+////////////////////////////////////////////////////
+// Structure the service endpoint ids
+///////////////////////////////////////////////////
+struct service_endpoints_id_t {
+	struct topology_id_t topology_id;
+	gchar device_uuid[UUID_CHAR_LENGTH];
+	gchar endpoint_uuid[UUID_CHAR_LENGTH];
+};
+
+////////////////////////////////////////////////////
+// Structure for handling generic targeted service constraints
+////////////////////////////////////////////////////
+#define MAX_CONSTRAINT_SIZE					128
+// Constraint Type: bandwidth, latency, energy, cost
+struct constraint_t {
+	gchar constraint_type[MAX_CONSTRAINT_SIZE];
+	gchar constraint_value[MAX_CONSTRAINT_SIZE];
+};
+
+////////////////////////////////////////////////////
+// Structure for individual service request
+////////////////////////////////////////////////////
+#define SERVICE_TYPE_UNKNOWN					0
+#define SERVICE_TYPE_L3NM						1
+#define SERVICE_TYPE_L2NM						2
+#define SERVICE_TYPE_TAPI						3
+
+#define MAX_NUM_SERVICE_ENPOINTS_ID				2
+
+#define MAX_NUM_SERVICE_CONSTRAINTS				10
+struct service_t {
+	// Indentifier used to determine the used Algorithm Id, e.g., KSP
+	gchar algId[MAX_ALG_ID_LENGTH];
+
+	// PATHS expected for the output
+	guint kPaths;
+	
+	struct serviceId_t serviceId;
+
+	guint service_type;	 // unknown, l2nm, l3nm, tapi
+
+	// endpoints of the network connectivity service, assumed p2p
+	// the 1st one assumed to be the source (ingress) and the 2nd one is the sink (egress)
+	struct service_endpoints_id_t service_endpoints_id[MAX_NUM_SERVICE_ENPOINTS_ID];
+	guint num_service_endpoints_id;
+
+	// Service Constraints
+	struct constraint_t constraints[MAX_NUM_SERVICE_CONSTRAINTS];
+	guint num_service_constraints;
+};
+
+////////////////////////////////////////////////////
+// Structure to handle path constraints during computation
+////////////////////////////////////////////////////
+struct path_constraints_t {
+	gdouble bwConstraint;
+	gboolean bw;
+
+	gdouble costConstraint;
+	gboolean cost;
+
+	gdouble latencyConstraint;
+	gboolean latency;
+
+	gdouble energyConstraint;
+	gboolean energy;
+};
+
+////////////////////////////////////////////////////
+// Structure for the handling the service requests
+///////////////////////////////////////////////////
+#define MAX_SERVICE_LIST						100
+struct serviceList_t {
+	struct service_t services[MAX_SERVICE_LIST];
+	gint numServiceList;	
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Structure describing the links forming a computed path
+////////////////////////////////////////////////////////////////////////////////////////////
+struct linkTopology_t {
+	gchar topologyId[UUID_CHAR_LENGTH];
+};
+
+struct pathLink_t {
+	gchar linkId[UUID_CHAR_LENGTH]; // link id UUID in char format
+
+	gchar aDeviceId[UUID_CHAR_LENGTH];
+	gchar zDeviceId[UUID_CHAR_LENGTH];
+	gchar aEndPointId[UUID_CHAR_LENGTH];
+	gchar zEndPointId[UUID_CHAR_LENGTH];
+
+	struct topology_id_t topologyId;
+
+	struct linkTopology_t linkTopologies[2]; // a p2p link (at most) can connect to devices (endpoints) attached to 2 different topologies
+	gint numLinkTopologies;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Structure describing a computed path
+////////////////////////////////////////////////////////////////////////////////////////////
+#define MAX_ROUTE_ELEMENTS  50
+struct routeElement_t {
+	//aNodeId/Device Id
+	struct nodes_t aNodeId;
+	//zNodeId/Device Id
+	struct nodes_t zNodeId;
+
+	// UUID of the endPointIds
+	gchar aEndPointId[UUID_CHAR_LENGTH];
+	gchar zEndPointId[UUID_CHAR_LENGTH];
+
+	// UUID of the link
+	gchar linkId[UUID_CHAR_LENGTH];
+
+	gchar aTopologyId[UUID_CHAR_LENGTH];
+	gchar zTopologyId[UUID_CHAR_LENGTH];
+
+	// contextId
+	gchar contextId[UUID_CHAR_LENGTH];
+};
+
+struct compRouteOutputItem_t {
+	// Potential(total) and available capacity
+	gint unit;
+	gdouble totalCap, availCap;
+
+	gdouble cost;
+	gdouble delay;
+
+	struct routeElement_t routeElement[MAX_ROUTE_ELEMENTS];
+	gint numRouteElements;
+};
+
+#define MAX_NUM_PATHS		30
+struct path_set_t {
+	struct compRouteOutputItem_t paths[MAX_NUM_PATHS];
+	gint numPaths;
+};
+
+#define MAX_NUM_PATH_LINKS						20
+struct path_t {
+	struct capacity_t path_capacity;
+	struct latency_characteristics_t path_latency;
+	struct cost_characteristics_t path_cost;
+
+	struct pathLink_t pathLinks[MAX_NUM_PATH_LINKS];
+	guint numPathLinks;
+};
+
+#define NO_PATH_CONS_ISSUE								1	 // No path due to a constraint issue
+#define MAX_NUM_COMPUTED_PATHS							10
+struct compRouteOutput_t
+{
+	// object describing the service identifier: serviceId and contextId
+	struct serviceId_t serviceId;
+
+	// array describing the service endpoints ids
+	struct service_endpoints_id_t service_endpoints_id[MAX_NUM_SERVICE_ENPOINTS_ID];
+	guint num_service_endpoints_id;
+
+	struct path_t paths[MAX_NUM_COMPUTED_PATHS];
+	gint numPaths;
+	
+	// if the transport connectivity service cannot be computed, this value is set to 0 determining the constraints were not fulfilled
+	gint noPathIssue;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Structure to handle the response list with all the computed network connectivity services
+////////////////////////////////////////////////////////////////////////////////////////////
+#define MAX_COMP_CONN_LIST		100
+struct compRouteOutputList_t
+{
+	struct compRouteOutput_t compRouteConnection[MAX_COMP_CONN_LIST];
+	gint numCompRouteConnList;
+
+	///////////////// Metrics //////////////////////////////////////////
+	// Number of total succesfully computed connections, i.e., at least 1 feasible path exists
+	// for every connection in the list
+	gint compRouteOK;
+	// For the succesfully newly computed/recovered/re-allocated/re-optimized connections, this 
+	// metric determines the average allocable bandwidth over all the (re-)computed paths for the succesfully 
+	// (i.e., feasible path) connections
+	gdouble compRouteConnAvBandwidth;
+	// For the succesfully newly computed/recovered/re-allocated/re-optimized connections, this 
+	// metric determines the average path length (in terms of number of hops) over the computed path for the
+	// succesfully (i.e., feasible path) connections
+	gdouble compRouteConnAvPathLength;
+};
+
+// Prototype of external declaration of functions
+void print_path (struct compRouteOutputItem_t *);
+void print_path_t(struct path_t*);
+
+void duplicate_string(gchar *, gchar *);
+
+gchar* get_uuid_char(uuid_t);
+void copy_service_id(struct serviceId_t*, struct serviceId_t *);
+void copy_service_endpoint_id(struct service_endpoints_id_t *, struct service_endpoints_id_t *);
+
+struct graph_t* get_graph_by_contextId(struct contextSet_t *, gchar *);
+
+struct pred_t * create_predecessors ();
+struct edges_t* create_edge();
+void print_predecessors (struct pred_t *);
+void build_predecessors (struct pred_t *, struct service_t *, struct map_nodes_t *);
+struct nodes_t * create_node ();
+struct routeElement_t * create_routeElement ();
+
+void duplicate_node_id (struct nodes_t *, struct nodes_t *);
+gint compare_node_id (struct nodes_t *, struct nodes_t *);
+void duplicate_routeElement (struct routeElement_t *, struct routeElement_t *);
+void duplicate_edge (struct edges_t *, struct edges_t *);
+void duplicate_path (struct compRouteOutputItem_t *, struct compRouteOutputItem_t *);
+void duplicate_path_t(struct compRouteOutputItem_t *, struct path_t *);
+gint get_map_index_by_nodeId (gchar *, struct map_nodes_t *);
+void get_edge_from_map_by_node (struct edges_t *, struct nodes_t*, struct map_nodes_t *);
+void get_edge_from_predecessors (struct edges_t *, struct nodes_t*, struct pred_t *);
+void build_path (struct compRouteOutputItem_t *, struct pred_t *, struct service_t *);
+void print_graph (struct graph_t *);
+
+gint graph_vertice_lookup (gchar *, struct graph_t *);
+gint graph_targeted_vertice_lookup (gint, gchar *, struct graph_t *);
+gint graph_targeted_vertice_add (gint, gchar *, struct graph_t *);
+
+void remove_edge_from_graph (struct graph_t *, struct edges_t *);
+
+struct path_set_t * create_path_set ();
+void sort_path_set (struct path_set_t *);
+void pop_front_path_set (struct path_set_t *);
+void remove_path_set(struct path_set_t*);
+
+void build_map_node(struct map_nodes_t *, struct graph_t *);
+struct compRouteOutputList_t * create_route_list();
+struct compRouteOutputItem_t * create_path_item (); 
+void add_routeElement_path_back (struct routeElement_t *, struct compRouteOutputItem_t *);
+gboolean matching_path_rootPath (struct compRouteOutputItem_t *, struct compRouteOutputItem_t *, struct nodes_t *, struct edges_t *);
+void modify_targeted_graph (struct graph_t *, struct path_set_t *, struct compRouteOutputItem_t *, struct nodes_t *);
+gint find_nodeId (gconstpointer, gconstpointer);
+gint check_link (struct nodeItem_t *, gint, gint, struct graph_t *, struct service_t *, GList **, GList **, struct map_nodes_t *);
+gboolean check_computed_path_feasability (struct service_t *, struct compRouteOutputItem_t * );
+
+gint sort_by_distance (gconstpointer, gconstpointer);
+
+struct graph_t * create_graph ();
+struct map_nodes_t * create_map_node ();
+
+struct service_t * get_service_for_computed_path(gchar *);
+
+struct deviceList_t* create_device_list();
+struct linkList_t* create_link_list();
+struct serviceList_t* create_service_list();
+
+void print_service_type(guint);
+void print_link_port_direction(guint);
+void print_termination_direction(guint);
+void print_termination_state(guint);
+void print_capacity_unit(guint);
+void print_link_forwarding_direction(guint);
+
+struct contextSet_t* create_contextSet();
+void build_contextSet(struct contextSet_t *);
+void print_contextSet(struct contextSet_t *);
+
+gint same_src_dst_pe_nodeid (struct service_t *);
+void comp_route_connection_issue_handler (struct compRouteOutput_t *, struct service_t *);
+
+void destroy_compRouteOutputList (struct compRouteOutputList_t *);
+void duplicate_graph (struct graph_t *, struct graph_t *);
+
+void allocate_graph_resources (struct path_t *, struct service_t *, struct graph_t *);
+void allocate_graph_reverse_resources(struct path_t*, struct service_t *, struct graph_t *);
+void print_route_solution_list (GList *);
+struct timeval tv_adjust(struct timeval);
+
+void print_path_connection_list(struct compRouteOutputList_t*);
+void update_stats_path_comp(struct compRouteOutputList_t*, struct timeval, gint, gint);
+#endif
\ No newline at end of file
diff --git a/src/pathcomp/backend/tests/inter_domain_test.txt b/src/pathcomp/backend/tests/inter_domain_test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3aeaa3779a816c7b79ff20601d80450de1743d4a
--- /dev/null
+++ b/src/pathcomp/backend/tests/inter_domain_test.txt
@@ -0,0 +1,543 @@
+{
+"serviceList": [
+{
+"algId": "KSP",
+"syncPaths": false,
+"serviceId": {
+"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"service_uuid": "651550d8-46a0-4f36-9fb9-21b8e4f1b8d2"
+},
+"serviceType": 1,
+"service_endpoints_ids": [
+{
+"topology_id": {
+"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaa"
+},
+"device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+"endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa111"
+},
+{
+"topology_id": {
+"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+},
+"device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+"endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"
+}
+],
+"service_constraints": [
+{"constraint_type": "bandwidth", "constraint_value": "100"},
+{"constraint_type": "latency", "constraint_value": "20"}
+],
+"kPaths": 3
+}
+],
+"deviceList": [
+{"device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa111"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 4, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa112"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa113"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa132"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa133"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa134"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa122"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa123"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa124"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa142"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa143"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa141"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in": {"plug-id-inter-domain-local-id": "a2", "plug-id-inter-domain-remote-id":"c1"}} 
+]
+},
+{"device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa151"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"a1",
+"plug-id-inter-domain-remote-id":"b1"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa152"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa153"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb211"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"b1",
+"plug-id-inter-domain-remote-id":"a1"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb212"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb213"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb231"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"b2",
+"plug-id-inter-domain-remote-id":"c2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb232"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb233"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb241"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"b4",
+"plug-id-inter-domain-remote-id":"c3"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb242"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb243"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc311"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"c1",
+"plug-id-inter-domain-remote-id":"a2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc312"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc313"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc321"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"c2",
+"plug-id-inter-domain-remote-id":"b2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc322"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc323"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}, "inter-domain-plug-in":{"plug-id-inter-domain-local-id":"c3",
+"plug-id-inter-domain-remote-id":"b4"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc332"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc333"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+}
+],
+"linkList": [
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1112",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa113"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa122"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1211",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa122"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa113"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1113",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa112"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa132"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1311",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa132"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa112"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1312",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa133"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa123"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1213",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa123"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa133"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1214",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa124"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa142"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1412",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa142"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa124"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1315",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa134"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa152"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1513",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa152"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa134"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1415",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa143"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa153"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1514",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa153"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa143"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1521",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa151"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb211"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2115",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb211"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa151"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1431",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa141"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc311"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3114",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc311"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa141"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2124",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb212"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb242"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2421",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb242"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb212"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2123",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb213"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb233"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2321",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb233"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb213"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2324",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb232"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb243"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2424",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb243"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb232"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2332",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb231"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc321"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3223",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc321"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb231"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2433",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb241"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc34", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3324",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb241"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3132",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc312"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc323"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3231",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc323"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc312"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3133",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc313"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc333"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3331",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc333"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc313"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3233",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc322"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc332"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3332",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc332"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc322"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+}
+]
+}
\ No newline at end of file
diff --git a/src/pathcomp/backend/tests/pc-req.json b/src/pathcomp/backend/tests/pc-req.json
new file mode 100644
index 0000000000000000000000000000000000000000..f465c95235dc80851b9e91dc80c3df60d3b4dbe0
--- /dev/null
+++ b/src/pathcomp/backend/tests/pc-req.json
@@ -0,0 +1,1230 @@
+{
+    "deviceList": [
+        {
+            "device_Id": "A1",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A1",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A1",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A1",
+                        "endpoint_uuid": "2000",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "A2",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A2",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A2",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A2",
+                        "endpoint_uuid": "1001",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "A3",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A3",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "A3",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "B1",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B1",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B1",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B1",
+                        "endpoint_uuid": "2000",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "B2",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B2",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B2",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B2",
+                        "endpoint_uuid": "1002",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "B3",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B3",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "B3",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "C1",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C1",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C1",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C1",
+                        "endpoint_uuid": "1001",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "C2",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C2",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C2",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_Id": "C3",
+            "device_endpoints": [
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C3",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C3",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                },
+                {
+                    "available-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    },
+                    "endpoint_id": {
+                        "device_id": "C3",
+                        "endpoint_uuid": "1002",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    },
+                    "endpoint_type": "copper",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "unit": 5,
+                            "value": 200
+                        }
+                    }
+                }
+            ],
+            "device_type": "emu-packet-router"
+        }
+    ],
+    "linkList": [
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "A1/1==A2/1",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "A1",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "A2",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "A1/2==A3/1",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "A1",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "A3",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "A2/1001==C3/1002",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "A2",
+                        "endpoint_uuid": "1001",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "C3",
+                        "endpoint_uuid": "1002",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "A2/2==A3/2",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "A2",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "A3",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "A"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "B1/1==B2/1",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "B1",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "B2",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "B1/2==B3/1",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "B1",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "B3",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "B2/2==B3/2",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "B2",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "B3",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "C1/1001==B2/1002",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "C1",
+                        "endpoint_uuid": "1001",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "B2",
+                        "endpoint_uuid": "1002",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "B"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "C1/1==C2/1",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "C1",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "C2",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "C1/2==C3/1",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "C1",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "C3",
+                        "endpoint_uuid": "1",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        },
+        {
+            "available-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            },
+            "cost-characteristics": {
+                "cost-algorithm": "0",
+                "cost-name": "linkcost",
+                "cost-value": "1"
+            },
+            "forwarding_direction": 0,
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            },
+            "link_Id": "C2/2==C3/2",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "device_id": "C2",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "device_id": "C3",
+                        "endpoint_uuid": "2",
+                        "topology_id": {
+                            "contextId": "admin",
+                            "topology_uuid": "C"
+                        }
+                    }
+                }
+            ],
+            "total-potential-capacity": {
+                "total-size": {
+                    "unit": 5,
+                    "value": 200
+                }
+            }
+        }
+    ],
+    "serviceList": [
+        {
+            "algId": "KSP",
+            "kPaths": 2,
+            "serviceId": {
+                "contextId": "admin",
+                "service_uuid": "svc:A1/2000==B1/2000"
+            },
+            "serviceType": 1,
+            "service_constraints": [
+                {
+                    "constraint_type": "bandwidth[gbps]",
+                    "constraint_value": "10.0"
+                },
+                {
+                    "constraint_type": "latency[ms]",
+                    "constraint_value": "12.0"
+                }
+            ],
+            "service_endpoints_ids": [
+                {
+                    "device_id": "A1",
+                    "endpoint_uuid": "2000",
+                    "topology_id": {
+                        "contextId": "admin",
+                        "topology_uuid": "A"
+                    }
+                },
+                {
+                    "device_id": "B1",
+                    "endpoint_uuid": "2000",
+                    "topology_id": {
+                        "contextId": "admin",
+                        "topology_uuid": "B"
+                    }
+                }
+            ],
+            "syncPaths": false
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/pathcomp/backend/tests/run-test.sh b/src/pathcomp/backend/tests/run-test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..214acdf1b8172a8bbd43056b3e3842583ffff645
--- /dev/null
+++ b/src/pathcomp/backend/tests/run-test.sh
@@ -0,0 +1 @@
+curl -0 -v -X POST -H "Expect:" -H "Content-Type: application/json" http://172.17.0.2:8081/pathComp/api/v1/compRoute -d @inter_domain_test.txt
\ No newline at end of file
diff --git a/src/pathcomp/backend/tests/test.txt b/src/pathcomp/backend/tests/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2bab9f2b908dc2c4a17b86134cea38f6d0ed0b7
--- /dev/null
+++ b/src/pathcomp/backend/tests/test.txt
@@ -0,0 +1,236 @@
+{
+"serviceList": [
+{
+"algId": "KSP",
+"syncPaths": false,
+"serviceId": {
+"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"service_uuid": "651550d8-46a0-4f36-9fb9-21b8e4f1b8d2"
+},
+"serviceType": 1,
+"service_endpoints_ids": [
+{
+"topology_id": {
+"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"
+},
+"device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
+"endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1"
+},
+{
+"topology_id": {
+"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"
+},
+"device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee",
+"endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee1"
+}
+],
+"service_constraints": [
+{"constraint_type": "bandwidth", "constraint_value": "100"},
+{"constraint_type": "latency", "constraint_value": "10"}
+],
+"kPaths": 3
+}
+],
+"deviceList": [
+{"device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 4, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa2"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa3"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb2"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb3"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb4"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc2"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc3"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc4"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "endpoint_uuid": "dddddddd-dddd-dddd-dddd-ddddddddddd2"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "endpoint_uuid": "dddddddd-dddd-dddd-dddd-ddddddddddd3"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+},
+{"device_Id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "device_type": "L3", 
+"device_endpoints": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee1"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 4, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee2"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee3"},
+"endpoint_type": "termination", "link_port_direction": 0, "termination-direction": 0, "termination-state": 0, "total-potential-capacity": {"total-size": {"value": 200,
+"unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}}} 
+]
+}
+],
+"linkList": [
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffab",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb2"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "10"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffba",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa2"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffac",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa3"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc2"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffca",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa3"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffcb",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc3"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb3"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffbc",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb3"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc3"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffcd",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc4"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "endpoint_uuid": "dddddddd-dddd-dddd-dddd-ddddddddddd2"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffdc",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "endpoint_uuid": "dddddddd-dddd-dddd-dddd-ddddddddddd2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccccc4"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffbe",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb4"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee2"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffeb",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee2"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb4"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffde",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "endpoint_uuid": "dddddddd-dddd-dddd-dddd-ddddddddddd3"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee3"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+},
+{"link_Id": "ffffffff-ffff-ffff-ffff-ffffffffffed",
+"link_endpoint_ids": [
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "endpoint_uuid": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee3"}},
+{"endpoint_id": {"topology_id": {"contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+"topology_uuid": "abf65601-a36b-496f-8e21-1708e5f96e2d"}, "device_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "endpoint_uuid": "dddddddd-dddd-dddd-dddd-ddddddddddd3"}}
+],
+"forwarding_direction": 1, "total-potential-capacity": { "total-size": {"value": 200, "unit": 5}}, "available-capacity": {"total-size": {"value": 200, "unit": 5}},
+"cost-characteristics": {"cost-name": "linkcost","cost-value": "1","cost-algorithm": "0"},"latency-characteristics": {"fixed-latency-characteristic": "2"}
+}
+]
+}
\ No newline at end of file
diff --git a/src/pathcomp/frontend/Config.py b/src/pathcomp/frontend/Config.py
new file mode 100644
index 0000000000000000000000000000000000000000..f59ca45035ab0efecdf4297467626df18b74fa4d
--- /dev/null
+++ b/src/pathcomp/frontend/Config.py
@@ -0,0 +1,38 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+
+DEFAULT_PATHCOMP_BACKEND_SCHEME  = 'http'
+DEFAULT_PATHCOMP_BACKEND_HOST    = '127.0.0.1'
+DEFAULT_PATHCOMP_BACKEND_PORT    = '8081'
+DEFAULT_PATHCOMP_BACKEND_BASEURL = '/pathComp/api/v1/compRoute'
+
+PATHCOMP_BACKEND_SCHEME  = str(os.environ.get('PATHCOMP_BACKEND_SCHEME',  DEFAULT_PATHCOMP_BACKEND_SCHEME ))
+PATHCOMP_BACKEND_BASEURL = str(os.environ.get('PATHCOMP_BACKEND_BASEURL', DEFAULT_PATHCOMP_BACKEND_BASEURL))
+
+# Find IP:port of backend container as follows:
+# - first check env vars PATHCOMP_BACKEND_HOST & PATHCOMP_BACKEND_PORT
+# - if not set, check env vars PATHCOMPSERVICE_SERVICE_HOST & PATHCOMPSERVICE_SERVICE_PORT_HTTP
+# - if not set, use DEFAULT_PATHCOMP_BACKEND_HOST & DEFAULT_PATHCOMP_BACKEND_PORT
+backend_host = DEFAULT_PATHCOMP_BACKEND_HOST
+backend_host = os.environ.get('PATHCOMPSERVICE_SERVICE_HOST', backend_host)
+PATHCOMP_BACKEND_HOST = str(os.environ.get('PATHCOMP_BACKEND_HOST', backend_host))
+
+backend_port = DEFAULT_PATHCOMP_BACKEND_PORT
+backend_port = os.environ.get('PATHCOMPSERVICE_SERVICE_PORT_HTTP', backend_port)
+PATHCOMP_BACKEND_PORT = int(os.environ.get('PATHCOMP_BACKEND_PORT', backend_port))
+
+BACKEND_URL = '{:s}://{:s}:{:d}{:s}'.format(
+    PATHCOMP_BACKEND_SCHEME, PATHCOMP_BACKEND_HOST, PATHCOMP_BACKEND_PORT, PATHCOMP_BACKEND_BASEURL)
diff --git a/src/pathcomp/Dockerfile b/src/pathcomp/frontend/Dockerfile
similarity index 94%
rename from src/pathcomp/Dockerfile
rename to src/pathcomp/frontend/Dockerfile
index ec1ebbf06616233fb96acb4e54d3de24b8a016a4..2c511bc073b8d0631bbf120cff98d14a07187c3f 100644
--- a/src/pathcomp/Dockerfile
+++ b/src/pathcomp/frontend/Dockerfile
@@ -56,14 +56,15 @@ RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \;
 # Create component sub-folders, get specific Python packages
 RUN mkdir -p /var/teraflow/pathcomp
 WORKDIR /var/teraflow/pathcomp
-COPY src/pathcomp/requirements.in requirements.in
+COPY src/pathcomp/frontend/requirements.in requirements.in
 RUN pip-compile --quiet --output-file=requirements.txt requirements.in
 RUN python3 -m pip install -r requirements.txt
 
 # Add component files into working directory
 WORKDIR /var/teraflow
 COPY src/context/. context/
+COPY src/device/. device/
 COPY src/pathcomp/. pathcomp/
 
 # Start the service
-ENTRYPOINT ["python", "-m", "pathcomp.service"]
+ENTRYPOINT ["python", "-m", "pathcomp.frontend.service"]
diff --git a/src/pathcomp/Config.py b/src/pathcomp/frontend/__init__.py
similarity index 100%
rename from src/pathcomp/Config.py
rename to src/pathcomp/frontend/__init__.py
diff --git a/src/pathcomp/client/PathCompClient.py b/src/pathcomp/frontend/client/PathCompClient.py
similarity index 100%
rename from src/pathcomp/client/PathCompClient.py
rename to src/pathcomp/frontend/client/PathCompClient.py
diff --git a/src/pathcomp/service/__init__.py b/src/pathcomp/frontend/client/__init__.py
similarity index 100%
rename from src/pathcomp/service/__init__.py
rename to src/pathcomp/frontend/client/__init__.py
diff --git a/src/pathcomp/frontend/example/command.txt b/src/pathcomp/frontend/example/command.txt
new file mode 100644
index 0000000000000000000000000000000000000000..59002337f8efe1db607ebd724bb89287142e9d94
--- /dev/null
+++ b/src/pathcomp/frontend/example/command.txt
@@ -0,0 +1,4 @@
+curl -0 -v -X POST \
+    -H "Expect:" -H "Content-Type: application/json" \
+    http://172.17.0.2:8081/pathComp/api/v1/compRoute \
+    -d @src/pathcomp/backend/test/inter_domain_test.txt
diff --git a/src/pathcomp/frontend/example/reply.json b/src/pathcomp/frontend/example/reply.json
new file mode 100644
index 0000000000000000000000000000000000000000..6bb4bef233d7eda6215a06d83a03f97901d8ad83
--- /dev/null
+++ b/src/pathcomp/frontend/example/reply.json
@@ -0,0 +1,92 @@
+{
+    "response-list": [
+        {
+            "serviceId": {
+                "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                "service_uuid": "651550d8-46a0-4f36-9fb9-21b8e4f1b8d2"
+            },
+            "service_endpoints_ids": [
+                {
+                    "topology_id": {
+                        "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                        "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaa"
+                    },
+                    "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                    "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa111"
+                },
+                {
+                    "topology_id": {
+                        "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                        "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                    },
+                    "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                    "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"
+                }
+            ],
+            "path": [
+                {
+                    "path-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 0
+                        }
+                    },
+                    "path-latency": {
+                        "fixed-latency-characteristic": "8.000000"
+                    },
+                    "path-cost": {
+                        "cost-name": "",
+                        "cost-value": "4.000000",
+                        "cost-algorithm": "0.000000"
+                    },
+                    "link": [
+                        {
+                            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1112",
+                            "topology": [
+                                {
+                                    "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                                },
+                                {
+                                    "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                                }
+                            ]
+                        },
+                        {
+                            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1214",
+                            "topology": [
+                                {
+                                    "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                                },
+                                {
+                                    "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                                }
+                            ]
+                        },
+                        {
+                            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1431",
+                            "topology": [
+                                {
+                                    "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                                },
+                                {
+                                    "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                                }
+                            ]
+                        },
+                        {
+                            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3133",
+                            "topology": [
+                                {
+                                    "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                                },
+                                {
+                                    "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/pathcomp/frontend/example/request.json b/src/pathcomp/frontend/example/request.json
new file mode 100644
index 0000000000000000000000000000000000000000..a13f20f12fd9d181d0a21ffc737979cae23bf457
--- /dev/null
+++ b/src/pathcomp/frontend/example/request.json
@@ -0,0 +1,2474 @@
+{
+    "serviceList": [
+        {
+            "algId": "KSP",
+            "syncPaths": false,
+            "serviceId": {
+                "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                "service_uuid": "651550d8-46a0-4f36-9fb9-21b8e4f1b8d2"
+            },
+            "serviceType": 1,
+            "service_endpoints_ids": [
+                {
+                    "topology_id": {
+                        "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                        "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaa"
+                    },
+                    "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                    "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa111"
+                },
+                {
+                    "topology_id": {
+                        "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                        "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                    },
+                    "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                    "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"
+                }
+            ],
+            "service_constraints": [
+                {
+                    "constraint_type": "bandwidth",
+                    "constraint_value": "100"
+                },
+                {
+                    "constraint_type": "latency",
+                    "constraint_value": "20"
+                }
+            ],
+            "kPaths": 3
+        }
+    ],
+    "deviceList": [
+        {
+            "device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa111"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 4,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa112"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa113"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa132"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa133"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa134"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa122"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa123"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa124"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa142"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa143"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa141"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "a2",
+                        "plug-id-inter-domain-remote-id": "c1"
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa151"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "a1",
+                        "plug-id-inter-domain-remote-id": "b1"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa152"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa153"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb211"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "b1",
+                        "plug-id-inter-domain-remote-id": "a1"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb212"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb213"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb231"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "b2",
+                        "plug-id-inter-domain-remote-id": "c2"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb232"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb233"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb241"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "b4",
+                        "plug-id-inter-domain-remote-id": "c3"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb242"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb243"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc311"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "c1",
+                        "plug-id-inter-domain-remote-id": "a2"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc312"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc313"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc321"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "c2",
+                        "plug-id-inter-domain-remote-id": "b2"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc322"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc323"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "device_Id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+            "device_type": "L3",
+            "device_endpoints": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "inter-domain-plug-in": {
+                        "plug-id-inter-domain-local-id": "c3",
+                        "plug-id-inter-domain-remote-id": "b4"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc332"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc333"
+                    },
+                    "endpoint_type": "termination",
+                    "link_port_direction": 0,
+                    "termination-direction": 0,
+                    "termination-state": 0,
+                    "total-potential-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    },
+                    "available-capacity": {
+                        "total-size": {
+                            "value": 200,
+                            "unit": 5
+                        }
+                    }
+                }
+            ]
+        }
+    ],
+    "linkList": [
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1112",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa113"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa122"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1211",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa122"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa113"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1113",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa112"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa132"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1311",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa132"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa11",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa112"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1312",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa133"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa123"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1213",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa123"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa133"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1214",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa124"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa142"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1412",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa142"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa12",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa124"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1315",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa134"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa152"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1513",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa152"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa13",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa134"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1415",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa143"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa153"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1514",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa153"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa143"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1521",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa151"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb211"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2115",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb211"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa15",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa151"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa1431",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa141"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc311"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3114",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc311"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
+                        },
+                        "device_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa14",
+                        "endpoint_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa141"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2124",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb212"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb242"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2421",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb242"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb212"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2123",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb213"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb233"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2321",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb233"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb21",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb213"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2324",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb232"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb243"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2424",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb243"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb232"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2332",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb231"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc321"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3223",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc321"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb23",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb231"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbb2433",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb241"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc34",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3324",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc331"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
+                        },
+                        "device_id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb24",
+                        "endpoint_uuid": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbb241"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3132",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc312"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc323"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3231",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc323"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc312"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3133",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc313"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc333"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3331",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc333"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc31",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc313"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3233",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc322"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc332"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        },
+        {
+            "link_Id": "cccccccc-cccc-cccc-cccc-cccccccc3332",
+            "link_endpoint_ids": [
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc33",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc332"
+                    }
+                },
+                {
+                    "endpoint_id": {
+                        "topology_id": {
+                            "contextId": "b55a05a5-ae2d-4ff3-85ca-97fac0c56f91",
+                            "topology_uuid": "cccccccc-cccc-cccc-cccc-cccccccccccc"
+                        },
+                        "device_id": "cccccccc-cccc-cccc-cccc-cccccccccc32",
+                        "endpoint_uuid": "cccccccc-cccc-cccc-cccc-ccccccccc322"
+                    }
+                }
+            ],
+            "forwarding_direction": 1,
+            "total-potential-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "available-capacity": {
+                "total-size": {
+                    "value": 200,
+                    "unit": 5
+                }
+            },
+            "cost-characteristics": {
+                "cost-name": "linkcost",
+                "cost-value": "1",
+                "cost-algorithm": "0"
+            },
+            "latency-characteristics": {
+                "fixed-latency-characteristic": "2"
+            }
+        }
+    ]
+}
diff --git a/src/pathcomp/requirements.in b/src/pathcomp/frontend/requirements.in
similarity index 100%
rename from src/pathcomp/requirements.in
rename to src/pathcomp/frontend/requirements.in
diff --git a/src/pathcomp/service/PathCompService.py b/src/pathcomp/frontend/service/PathCompService.py
similarity index 93%
rename from src/pathcomp/service/PathCompService.py
rename to src/pathcomp/frontend/service/PathCompService.py
index 7fd9eab3ba8de53ddc5fdee018519126c44361f0..88dc5134754cc1b198a505ca9d1cd1f98f2ace22 100644
--- a/src/pathcomp/service/PathCompService.py
+++ b/src/pathcomp/frontend/service/PathCompService.py
@@ -15,7 +15,7 @@
 from common.Constants import ServiceNameEnum
 from common.Settings import get_service_port_grpc
 from common.tools.service.GenericGrpcService import GenericGrpcService
-from pathcomp.proto.pathcomp_pb2_grpc import add_PathCompServiceServicer_to_server
+from common.proto.pathcomp_pb2_grpc import add_PathCompServiceServicer_to_server
 from .PathCompServiceServicerImpl import PathCompServiceServicerImpl
 
 class PathCompService(GenericGrpcService):
diff --git a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py
new file mode 100644
index 0000000000000000000000000000000000000000..1d55646abffcdb4a882167406ba046aca7bfa651
--- /dev/null
+++ b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py
@@ -0,0 +1,61 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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.proto.context_pb2 import Empty
+from common.proto.pathcomp_pb2 import PathCompReply, PathCompRequest
+from common.proto.pathcomp_pb2_grpc import PathCompServiceServicer
+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 pathcomp.frontend.service.algorithms.Factory import get_algorithm
+
+LOGGER = logging.getLogger(__name__)
+
+SERVICE_NAME = 'PathComp'
+METHOD_NAMES = ['Compute']
+METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
+
+class PathCompServiceServicerImpl(PathCompServiceServicer):
+    def __init__(self) -> None:
+        LOGGER.debug('Creating Servicer...')
+        LOGGER.debug('Servicer Created')
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def Compute(self, request : PathCompRequest, context : grpc.ServicerContext) -> PathCompReply:
+        LOGGER.info('[Compute] begin ; request = {:s}'.format(grpc_message_to_json_string(request)))
+
+        context_client = ContextClient()
+
+        # TODO: add filtering of devices and links
+        # TODO: add contexts, topologies, and membership of devices/links in topologies
+        algorithm = get_algorithm(request)
+        algorithm.add_devices(context_client.ListDevices(Empty()))
+        algorithm.add_links(context_client.ListLinks(Empty()))
+        algorithm.add_service_requests(request)
+
+        #LOGGER.debug('device_list = {:s}'  .format(str(algorithm.device_list  )))
+        #LOGGER.debug('endpoint_dict = {:s}'.format(str(algorithm.endpoint_dict)))
+        #LOGGER.debug('link_list = {:s}'    .format(str(algorithm.link_list    )))
+        #LOGGER.debug('service_list = {:s}' .format(str(algorithm.service_list )))
+        #LOGGER.debug('service_dict = {:s}' .format(str(algorithm.service_dict )))
+
+        #import time
+        #ts = time.time()
+        #algorithm.execute('request-{:f}.json'.format(ts), 'reply-{:f}.json'.format(ts))
+        algorithm.execute()
+
+        reply = algorithm.get_reply()
+        LOGGER.info('[Compute] end ; reply = {:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
diff --git a/src/pathcomp/tests/__init__.py b/src/pathcomp/frontend/service/__init__.py
similarity index 100%
rename from src/pathcomp/tests/__init__.py
rename to src/pathcomp/frontend/service/__init__.py
diff --git a/src/pathcomp/service/__main__.py b/src/pathcomp/frontend/service/__main__.py
similarity index 95%
rename from src/pathcomp/service/__main__.py
rename to src/pathcomp/frontend/service/__main__.py
index a41b9e994f02db725c4adf371d9638fd5135693e..24a5b77418839153839a4fcf92f1a2b42d9cf91d 100644
--- a/src/pathcomp/service/__main__.py
+++ b/src/pathcomp/frontend/service/__main__.py
@@ -31,7 +31,7 @@ def main():
     global LOGGER # pylint: disable=global-statement
 
     log_level = get_log_level()
-    logging.basicConfig(level=log_level)
+    logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
diff --git a/src/pathcomp/frontend/service/algorithms/Factory.py b/src/pathcomp/frontend/service/algorithms/Factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..80d329a9d6d2f3adf824132aca7e4d5a35cffa99
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/Factory.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.
+
+from ._Algorithm import _Algorithm
+from .KDisjointPathAlgorithm import KDisjointPathAlgorithm
+from .KShortestPathAlgorithm import KShortestPathAlgorithm
+from .ShortestPathAlgorithm import ShortestPathAlgorithm
+
+ALGORITHMS = {
+    'shortest_path'  : ShortestPathAlgorithm,
+    'k_shortest_path': KShortestPathAlgorithm,
+    'k_disjoint_path': KDisjointPathAlgorithm,
+}
+
+def get_algorithm(request) -> _Algorithm:
+    algorithm_name = request.WhichOneof('algorithm')
+    algorithm_class = ALGORITHMS.get(algorithm_name)
+    if algorithm_class is None:
+        raise Exception('Algorithm({:s}) not supported'.format(str(algorithm_name)))
+    algorithm_settings = getattr(request, algorithm_name)
+    algorithm_instance = algorithm_class(algorithm_settings)
+    return algorithm_instance
diff --git a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..76b49bc8bd4a5ded840ccad13f0941d05070d344
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py
@@ -0,0 +1,236 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 operator
+from typing import Dict, List, Optional, Set, Tuple
+from common.proto.context_pb2 import Connection, Link, Service
+from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompReply, PathCompRequest
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from pathcomp.frontend.service.algorithms.tools.ComputeSubServices import convert_explicit_path_hops_to_connections
+from pathcomp.frontend.service.algorithms.tools.EroPathToHops import eropath_to_hops
+from ._Algorithm import _Algorithm
+from .KShortestPathAlgorithm import KShortestPathAlgorithm
+
+Service_Id          = Tuple[str, str]   # (context_uuid, service_uuid)
+Service_Constraints = Dict[str, str]    # {constraint_type => constraint_value}
+Endpoint_Id         = Tuple[str, str]   # (device_uuid, endpoint_uuid)
+Endpoint_Details    = Tuple[str, int]   # (site_id, priority)
+Service_Endpoints   = Dict[Endpoint_Id, Endpoint_Details]
+Service_Details     = Tuple[int, Service_Constraints, Service_Endpoints]
+Services_Details    = Dict[Service_Id, Service_Details]
+
+CUSTOM_CONSTRAINTS = {'bandwidth[gbps]', 'latency[ms]', 'jitter[us]'}
+
+DUMP_EXECUTION_STEPS = False
+
+class KDisjointPathAlgorithm(_Algorithm):
+    def __init__(self, algorithm : Algorithm_KDisjointPath, class_name=__name__) -> None:
+        super().__init__('KDP', False, class_name=class_name)
+        self.num_disjoint = algorithm.num_disjoint
+        self.services_details : Services_Details = dict()
+
+    def add_service_requests(self, request: PathCompRequest) -> None:
+        super().add_service_requests(request)
+        for service in request.services:
+            service_id = service.service_id
+            context_uuid = service_id.context_id.context_uuid.uuid
+            service_uuid = service_id.service_uuid.uuid
+            service_key = (context_uuid, service_uuid)
+
+            constraints = dict()
+            endpoints = dict()
+            service_details = (int(service.service_type), constraints, endpoints)
+            self.services_details.setdefault(service_key, service_details)
+
+            for constraint in service.service_constraints:
+                if constraint.WhichOneof('constraint') == 'custom':
+                    constraint_type = constraint.custom.constraint_type
+                    if constraint_type not in CUSTOM_CONSTRAINTS: continue
+                    constraint_value = constraint.custom.constraint_value
+                    constraints[constraint_type] = constraint_value
+
+                if constraint.WhichOneof('constraint') == 'endpoint_location':
+                    endpoint_id = constraint.endpoint_location.endpoint_id
+                    device_uuid = endpoint_id.device_id.device_uuid.uuid
+                    endpoint_uuid = endpoint_id.endpoint_uuid.uuid
+                    location_kind = constraint.endpoint_location.location.WhichOneof('location')
+                    if location_kind != 'region':
+                        MSG = 'Unsupported LocationType({:s}) in Constraint({:s})'
+                        raise Exception(MSG.format(location_kind, grpc_message_to_json_string(constraint)))
+                    site_id = constraint.endpoint_location.location.region
+                    endpoints.setdefault((device_uuid, endpoint_uuid), dict())['site_id'] = site_id
+
+                if constraint.WhichOneof('constraint') == 'endpoint_priority':
+                    endpoint_id = constraint.endpoint_priority.endpoint_id
+                    device_uuid = endpoint_id.device_id.device_uuid.uuid
+                    endpoint_uuid = endpoint_id.endpoint_uuid.uuid
+                    priority = constraint.endpoint_priority.priority
+                    endpoints.setdefault((device_uuid, endpoint_uuid), dict())['priority'] = priority
+
+            # TODO: ensure these constraints are provided in the request
+            if 'bandwidth[gbps]' not in constraints: constraints['bandwidth[gbps]'] = '20.0'
+            if 'latency[ms]' not in constraints: constraints['latency[ms]'] = '20.0'
+
+    def get_link_from_endpoint(self, endpoint : Dict) -> Tuple[Dict, Link]:
+        device_uuid = endpoint['device_id']
+        endpoint_uuid = endpoint['endpoint_uuid']
+        item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid))
+        if item is None:
+            MSG = 'Link for Endpoint({:s}, {:s}) not found'
+            self.logger.warning(MSG.format(device_uuid, endpoint_uuid))
+            return None
+        return item
+
+    def path_to_links(self, path_endpoints : List[Dict]) -> Tuple[List[Dict], Set[str]]:
+        path_links = list()
+        path_link_ids = set()
+        for endpoint in path_endpoints:
+            link_tuple = self.get_link_from_endpoint(endpoint)
+            if link_tuple is None: continue
+            json_link,_ = link_tuple
+            json_link_id = json_link['link_Id']
+            if len(path_links) == 0 or path_links[-1]['link_Id'] != json_link_id:
+                path_links.append(json_link)
+                path_link_ids.add(json_link_id)
+        return path_links, path_link_ids
+
+    def remove_traversed_links(self, link_list : List[Dict], path_endpoints : List[Dict]):
+        _, path_link_ids = self.path_to_links(path_endpoints)
+        new_link_list = list(filter(lambda l: l['link_Id'] not in path_link_ids, link_list))
+        #self.logger.info('cur_link_list = {:s}'.format(str(link_list)))
+        #self.logger.info('new_link_list = {:s}'.format(str(new_link_list)))
+        return new_link_list
+
+    def execute(self, dump_request_filename: Optional[str] = None, dump_reply_filename: Optional[str] = None) -> None:
+        algorithm = KShortestPathAlgorithm(Algorithm_KShortestPath(k_inspection=0, k_return=1))
+        algorithm.sync_paths = True
+        algorithm.device_list = self.device_list
+        algorithm.device_dict = self.device_dict
+        algorithm.endpoint_dict = self.endpoint_dict
+        algorithm.link_list = self.link_list
+        algorithm.link_dict = self.link_dict
+        algorithm.endpoint_to_link_dict = self.endpoint_to_link_dict
+
+        Path = List[Dict]
+        Path_NoPath = Optional[Path] # None = no path, list = path
+        self.json_reply : Dict[Tuple[str, str], List[Path_NoPath]] = dict()
+
+        for num_path in range(self.num_disjoint):
+            algorithm.service_list = list()
+            algorithm.service_dict = dict()
+
+            #self.logger.warning('services_details = {:s}'.format(str(self.services_details)))
+
+            _request = PathCompRequest()
+            for service_key, service_details in self.services_details.items():
+                service_type, constraints, endpoints = service_details
+                _service = _request.services.add()
+                _service.service_id.context_id.context_uuid.uuid = service_key[0]
+                _service.service_id.service_uuid.uuid = service_key[1]
+                _service.service_type = service_type
+                for constraint_type, constraint_value in constraints.items():
+                    constraint = _service.service_constraints.add()
+                    constraint.custom.constraint_type = constraint_type
+                    constraint.custom.constraint_value = constraint_value
+
+                site_to_endpoints : Dict[str, List[Tuple[Endpoint_Id, int]]] = {}
+                for endpoint_key,endpoint_details in endpoints.items():
+                    site_id = endpoint_details.get('site_id')
+                    if site_id is None: continue
+                    priority = endpoint_details.get('priority', 999)
+                    site_to_endpoints.setdefault(site_id, list()).append((endpoint_key, priority))
+
+                for site_id,site_endpoints in site_to_endpoints.items():
+                    pending_endpoints = sorted(site_endpoints, key=operator.itemgetter(1))
+                    if len(pending_endpoints) == 0: continue
+                    endpoint_key, _ = pending_endpoints[0]
+                    device_uuid, endpoint_uuid = endpoint_key
+                    endpoint_id = _service.service_endpoint_ids.add()
+                    endpoint_id.device_id.device_uuid.uuid = device_uuid
+                    endpoint_id.endpoint_uuid.uuid = endpoint_uuid
+                    endpoints.pop(endpoint_key)
+
+            algorithm.add_service_requests(_request)
+
+            dump_request_filename = 'ksp-{:d}-request.json'.format(num_path) if DUMP_EXECUTION_STEPS else None
+            dump_reply_filename   = 'ksp-{:d}-reply.txt'.format(num_path)    if DUMP_EXECUTION_STEPS else None
+            algorithm.execute(dump_request_filename, dump_reply_filename)
+
+            response_list = algorithm.json_reply.get('response-list', [])
+            for response in response_list:
+                service_id = response['serviceId']
+                service_key = (service_id['contextId'], service_id['service_uuid'])
+                json_reply_service = self.json_reply.setdefault(service_key, list())
+
+                no_path_issue = response.get('noPath', {}).get('issue')
+                if no_path_issue is not None:
+                    json_reply_service.append(None)
+                    continue
+
+                path_endpoints = response['path'][0]['devices']
+                json_reply_service.append(path_endpoints)
+                algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints)
+
+        self.logger.debug('self.json_reply = {:s}'.format(str(self.json_reply)))
+
+    def get_reply(self) -> PathCompReply:
+        reply = PathCompReply()
+        grpc_services : Dict[Tuple[str, str], Service] = {}
+        grpc_connections : Dict[Tuple[int, str], Connection] = {}
+        for service_key,paths in self.json_reply.items():
+            context_uuid, service_uuid = service_key
+
+            grpc_services[service_key] = self.add_service_to_reply(reply, context_uuid, service_uuid)
+
+            for num_path,service_path_ero in enumerate(paths):
+                self.logger.warning('num_path={:d}'.format(num_path))
+                self.logger.warning('service_path_ero={:s}'.format(str(service_path_ero)))
+                if service_path_ero is None: continue
+                path_hops = eropath_to_hops(service_path_ero, self.endpoint_to_link_dict)
+                self.logger.warning('path_hops={:s}'.format(str(path_hops)))
+                connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid)
+                self.logger.warning('connections={:s}'.format(str(connections)))
+
+                for connection in connections:
+                    connection_uuid,device_layer,path_hops,_ = connection
+
+                    service_key = (context_uuid, connection_uuid)
+                    grpc_service = grpc_services.get(service_key)
+                    if grpc_service is not None: continue
+                    grpc_service = self.add_service_to_reply(
+                        reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops)
+                    grpc_services[service_key] = grpc_service
+
+                for connection in connections:
+                    connection_uuid,device_layer,path_hops,dependencies = connection
+
+                    service_key = (context_uuid, connection_uuid)
+                    grpc_service = grpc_services.get(service_key)
+                    if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key)))
+
+                    connection_uuid = '{:s}:{:d}'.format(connection_uuid, num_path)
+                    grpc_connection = grpc_connections.get(connection_uuid)
+                    if grpc_connection is not None: continue
+                    grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops)
+                    grpc_connections[connection_uuid] = grpc_connection
+
+                    for sub_service_uuid in dependencies:
+                        sub_service_key = (context_uuid, sub_service_uuid)
+                        grpc_sub_service = grpc_services.get(sub_service_key)
+                        if grpc_sub_service is None:
+                            raise Exception('Service({:s}) not found'.format(str(sub_service_key)))
+                        grpc_sub_service_id = grpc_connection.sub_service_ids.add()
+                        grpc_sub_service_id.CopyFrom(grpc_sub_service.service_id)
+
+        return reply
diff --git a/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..11da9daa59268b78768c1733333e0d2cc7882335
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/KShortestPathAlgorithm.py
@@ -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.
+
+from common.proto.pathcomp_pb2 import Algorithm_KShortestPath
+from ._Algorithm import _Algorithm
+
+class KShortestPathAlgorithm(_Algorithm):
+    def __init__(self, algorithm : Algorithm_KShortestPath, class_name=__name__) -> None:
+        super().__init__('KSP', False, class_name=class_name)
+        self.k_inspection = algorithm.k_inspection
+        self.k_return = algorithm.k_return
+
+    def add_service_requests(self, requested_services) -> None:
+        super().add_service_requests(requested_services)
+        for service_request in self.service_list:
+            service_request['algId'    ] = self.algorithm_id
+            service_request['syncPaths'] = self.sync_paths
+            service_request['kPaths'   ] = self.k_return
diff --git a/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..d5f937fd207807ba650669ea9fb2395b2e21b164
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py
@@ -0,0 +1,26 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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.proto.pathcomp_pb2 import Algorithm_ShortestPath
+from ._Algorithm import _Algorithm
+
+class ShortestPathAlgorithm(_Algorithm):
+    def __init__(self, algorithm : Algorithm_ShortestPath, class_name=__name__) -> None:
+        super().__init__('SP', False, class_name=class_name)
+
+    def add_service_requests(self, requested_services) -> None:
+        super().add_service_requests(requested_services)
+        for service_request in self.service_list:
+            service_request['algId'    ] = self.algorithm_id
+            service_request['syncPaths'] = self.sync_paths
diff --git a/src/pathcomp/frontend/service/algorithms/_Algorithm.py b/src/pathcomp/frontend/service/algorithms/_Algorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..b798813a83d984d6d1d75450529e9c826e220624
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/_Algorithm.py
@@ -0,0 +1,248 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 typing import Dict, List, Optional, Tuple
+from common.proto.context_pb2 import (
+    ConfigRule, Connection, Device, DeviceList, EndPointId, Link, LinkList, Service, ServiceStatusEnum,
+    ServiceTypeEnum)
+from common.proto.pathcomp_pb2 import PathCompReply, PathCompRequest
+from common.tools.object_factory.ConfigRule import json_config_rule_set
+from pathcomp.frontend.Config import BACKEND_URL
+from pathcomp.frontend.service.algorithms.tools.ConstantsMappings import DEVICE_LAYER_TO_SERVICE_TYPE, DeviceLayerEnum
+from .tools.EroPathToHops import eropath_to_hops
+from .tools.ComposeRequest import compose_device, compose_link, compose_service
+from .tools.ComputeSubServices import convert_explicit_path_hops_to_connections
+
+class _Algorithm:
+    def __init__(self, algorithm_id : str, sync_paths : bool, class_name=__name__) -> None:
+        # algorithm_id: algorithm to be executed
+        # sync_paths: if multiple services are included in the request, tunes how to prevent contention. If true,
+        #             services are computed one after the other and resources assigned to service i, are considered as
+        #             used when computing services i+1..n; otherwise, resources are never marked as used during the
+        #             path computation.
+
+        self.logger = logging.getLogger(class_name)
+        self.algorithm_id = algorithm_id
+        self.sync_paths = sync_paths
+
+        self.device_list : List[Dict] = list()
+        self.device_dict : Dict[str, Tuple[Dict, Device]] = dict()
+        self.endpoint_dict : Dict[str, Dict[str, Tuple[Dict, EndPointId]]] = dict()
+        self.link_list : List[Dict] = list()
+        self.link_dict : Dict[str, Tuple[Dict, Link]] = dict()
+        self.endpoint_to_link_dict : Dict[Tuple[str, str], Tuple[Dict, Link]] = dict()
+        self.service_list : List[Dict] = list()
+        self.service_dict : Dict[Tuple[str, str], Tuple[Dict, Service]] = dict()
+
+    def add_devices(self, grpc_devices : DeviceList) -> None:
+        for grpc_device in grpc_devices.devices:
+            json_device = compose_device(grpc_device)
+            self.device_list.append(json_device)
+
+            device_uuid = json_device['device_Id']
+            self.device_dict[device_uuid] = (json_device, grpc_device)
+
+            device_endpoint_dict : Dict[str, Tuple[Dict, EndPointId]] = dict()
+            for json_endpoint,grpc_endpoint in zip(json_device['device_endpoints'], grpc_device.device_endpoints):
+                endpoint_uuid = json_endpoint['endpoint_id']['endpoint_uuid']
+                endpoint_tuple = (json_endpoint['endpoint_id'], grpc_endpoint.endpoint_id)
+                device_endpoint_dict[endpoint_uuid] = endpoint_tuple
+
+            self.endpoint_dict[device_uuid] = device_endpoint_dict
+
+    def add_links(self, grpc_links : LinkList) -> None:
+        for grpc_link in grpc_links.links:
+            json_link = compose_link(grpc_link)
+            self.link_list.append(json_link)
+
+            link_uuid = json_link['link_Id']
+            self.link_dict[link_uuid] = (json_link, grpc_link)
+
+            for link_endpoint_id in json_link['link_endpoint_ids']:
+                link_endpoint_id = link_endpoint_id['endpoint_id']
+                device_uuid = link_endpoint_id['device_id']
+                endpoint_uuid = link_endpoint_id['endpoint_uuid']
+                endpoint_key = (device_uuid, endpoint_uuid)
+                link_tuple = (json_link, grpc_link)
+                self.endpoint_to_link_dict[endpoint_key] = link_tuple
+
+    def add_service_requests(self, request : PathCompRequest) -> None:
+        for grpc_service in request.services:
+            json_service = compose_service(grpc_service)
+            self.service_list.append(json_service)
+            service_id = json_service['serviceId']
+            service_key = (service_id['contextId'], service_id['service_uuid'])
+            service_tuple = (json_service, grpc_service)
+            self.service_dict[service_key] = service_tuple
+
+    def execute(self, dump_request_filename : Optional[str] = None, dump_reply_filename : Optional[str] = None) -> None:
+        request = {'serviceList': self.service_list, 'deviceList': self.device_list, 'linkList': self.link_list}
+
+        self.logger.info('[execute] request={:s}'.format(str(request)))
+        if dump_request_filename is not None:
+            with open(dump_request_filename, 'w', encoding='UTF-8') as f:
+                f.write(json.dumps(request, sort_keys=True, indent=4))
+
+        self.logger.info('[execute] BACKEND_URL: {:s}'.format(str(BACKEND_URL)))
+        reply = requests.post(BACKEND_URL, json=request)
+        self.status_code = reply.status_code
+        self.raw_reply = reply.content.decode('UTF-8')
+
+        self.logger.info('[execute] status_code={:s} reply={:s}'.format(str(reply.status_code), str(self.raw_reply)))
+        if dump_reply_filename is not None:
+            with open(dump_reply_filename, 'w', encoding='UTF-8') as f:
+                f.write('status_code={:s} reply={:s}'.format(str(self.status_code), str(self.raw_reply)))
+
+        if reply.status_code not in {requests.codes.ok}:
+            raise Exception('Backend error({:s}) for request({:s})'.format(
+                str(self.raw_reply), json.dumps(request, sort_keys=True)))
+        
+        self.json_reply = reply.json()
+
+    def add_connection_to_reply(
+        self, reply : PathCompReply, connection_uuid : str, service : Service, path_hops : List[Dict]
+    ) -> Connection:
+        connection = reply.connections.add()
+
+        connection.connection_id.connection_uuid.uuid = connection_uuid
+        connection.service_id.CopyFrom(service.service_id)
+
+        for path_hop in path_hops:
+            device_uuid = path_hop['device']
+
+            ingress_endpoint_uuid = path_hop['ingress_ep']
+            endpoint_id = connection.path_hops_endpoint_ids.add()
+            endpoint_id.CopyFrom(self.endpoint_dict[device_uuid][ingress_endpoint_uuid][1])
+
+            egress_endpoint_uuid = path_hop['egress_ep']
+            endpoint_id = connection.path_hops_endpoint_ids.add()
+            endpoint_id.CopyFrom(self.endpoint_dict[device_uuid][egress_endpoint_uuid][1])
+
+        return connection
+
+    def add_service_to_reply(
+        self, reply : PathCompReply, context_uuid : str, service_uuid : str,
+        device_layer : Optional[DeviceLayerEnum] = None, path_hops : List[Dict] = []
+    ) -> Service:
+        # TODO: implement support for multi-point services
+        # Control deactivated to enable disjoint paths with multiple redundant endpoints on each side
+        #service_endpoint_ids = service.service_endpoint_ids
+        #if len(service_endpoint_ids) != 2: raise NotImplementedError('Service must have 2 endpoints')
+
+        service_key = (context_uuid, service_uuid)
+        tuple_service = self.service_dict.get(service_key)
+        if tuple_service is not None:
+            service = reply.services.add()
+            service.CopyFrom(tuple_service[1])
+        else:
+            service = reply.services.add()
+            service.service_id.context_id.context_uuid.uuid = context_uuid
+            service.service_id.service_uuid.uuid = service_uuid
+
+            if device_layer is not None:
+                service_type = DEVICE_LAYER_TO_SERVICE_TYPE.get(device_layer.value)
+                if service_type is None:
+                    MSG = 'Unable to map DeviceLayer({:s}) to ServiceType'
+                    raise Exception(MSG.format(str(device_layer)))
+                service.service_type = service_type
+
+                if service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE:
+                    json_tapi_settings = {
+                        'capacity_value'  : 50.0,
+                        'capacity_unit'   : 'GHz',
+                        'layer_proto_name': 'PHOTONIC_MEDIA',
+                        'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC',
+                        'direction'       : 'UNIDIRECTIONAL',
+                    }
+                    config_rule = ConfigRule(**json_config_rule_set('/settings', json_tapi_settings))
+                    service.service_config.config_rules.append(config_rule)
+
+            service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
+
+            if path_hops is not None and len(path_hops) > 0:
+                ingress_endpoint_id = service.service_endpoint_ids.add()
+                ingress_endpoint_id.device_id.device_uuid.uuid = path_hops[0]['device']
+                ingress_endpoint_id.endpoint_uuid.uuid = path_hops[0]['ingress_ep']
+
+                egress_endpoint_id = service.service_endpoint_ids.add()
+                egress_endpoint_id.device_id.device_uuid.uuid = path_hops[-1]['device']
+                egress_endpoint_id.endpoint_uuid.uuid = path_hops[-1]['egress_ep']
+
+        return service
+
+    def get_reply(self) -> PathCompReply:
+        response_list = self.json_reply.get('response-list', [])
+        reply = PathCompReply()
+        grpc_services : Dict[Tuple[str, str], Service] = {}
+        grpc_connections : Dict[str, Connection] = {}
+        for response in response_list:
+            service_id = response['serviceId']
+            context_uuid = service_id['contextId']
+            service_uuid = service_id['service_uuid']
+            service_key = (context_uuid, service_uuid)
+            grpc_services[service_key] = self.add_service_to_reply(reply, context_uuid, service_uuid)
+
+            no_path_issue = response.get('noPath', {}).get('issue')
+            if no_path_issue is not None:
+                # no path found: leave connection with no endpoints
+                # no_path_issue == 1 => no path due to a constraint
+                continue
+
+            for service_path_ero in response['path']:
+                path_hops = eropath_to_hops(service_path_ero['devices'], self.endpoint_to_link_dict)
+                connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid)
+
+                for connection in connections:
+                    connection_uuid,device_layer,path_hops,_ = connection
+                    service_key = (context_uuid, connection_uuid)
+                    grpc_service = grpc_services.get(service_key)
+                    if grpc_service is None:
+                        grpc_service = self.add_service_to_reply(
+                            reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops)
+                        grpc_services[service_key] = grpc_service
+
+                for connection in connections:
+                    connection_uuid,device_layer,path_hops,dependencies = connection
+
+                    service_key = (context_uuid, connection_uuid)
+                    grpc_service = grpc_services.get(service_key)
+                    if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key)))
+                        
+                    grpc_connection = grpc_connections.get(connection_uuid)
+                    if grpc_connection is not None: continue
+                    grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops)
+                    grpc_connections[connection_uuid] = grpc_connection
+
+                    for service_uuid in dependencies:
+                        sub_service_key = (context_uuid, service_uuid)
+                        grpc_sub_service = grpc_services.get(sub_service_key)
+                        if grpc_sub_service is None:
+                            raise Exception('Service({:s}) not found'.format(str(sub_service_key)))
+                        grpc_sub_service_id = grpc_connection.sub_service_ids.add()
+                        grpc_sub_service_id.CopyFrom(grpc_sub_service.service_id)
+
+                # ... "path-capacity": {"total-size": {"value": 200, "unit": 0}},
+                # ... "path-latency": {"fixed-latency-characteristic": "10.000000"},
+                # ... "path-cost": {"cost-name": "", "cost-value": "5.000000", "cost-algorithm": "0.000000"},
+                #path_capacity = service_path['path-capacity']['total-size']
+                #path_capacity_value = path_capacity['value']
+                #path_capacity_unit = CapacityUnit(path_capacity['unit'])
+                #path_latency = service_path['path-latency']['fixed-latency-characteristic']
+                #path_cost = service_path['path-cost']
+                #path_cost_name = path_cost['cost-name']
+                #path_cost_value = path_cost['cost-value']
+                #path_cost_algorithm = path_cost['cost-algorithm']
+
+        return reply
diff --git a/src/pathcomp/frontend/service/algorithms/__init__.py b/src/pathcomp/frontend/service/algorithms/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/__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/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py
new file mode 100644
index 0000000000000000000000000000000000000000..c1977cedb9b341fbb767a5fb8c829cd5f633884c
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py
@@ -0,0 +1,147 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+from typing import Dict
+from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
+from common.proto.context_pb2 import Constraint, Device, EndPointId, Link, Service, ServiceId, TopologyId
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from .ConstantsMappings import (
+    CapacityUnit, LinkForwardingDirection, LinkPortDirection, TerminationDirection, TerminationState)
+
+LOGGER = logging.getLogger(__name__)
+
+LOGGER = logging.getLogger(__name__)
+
+def compose_topology_id(topology_id : TopologyId) -> Dict:
+    context_uuid = topology_id.context_id.context_uuid.uuid
+    topology_uuid = topology_id.topology_uuid.uuid
+
+    if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_UUID
+    if len(topology_uuid) == 0: topology_uuid = DEFAULT_TOPOLOGY_UUID
+
+    return {'contextId': context_uuid, 'topology_uuid': topology_uuid}
+
+def compose_service_id(service_id : ServiceId) -> Dict:
+    context_uuid = service_id.context_id.context_uuid.uuid
+
+    if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_UUID
+
+    service_uuid = service_id.service_uuid.uuid
+    return {'contextId': context_uuid, 'service_uuid': service_uuid}
+
+def compose_endpoint_id(endpoint_id : EndPointId) -> Dict:
+    topology_id = compose_topology_id(endpoint_id.topology_id)
+    device_uuid = endpoint_id.device_id.device_uuid.uuid
+    endpoint_uuid = endpoint_id.endpoint_uuid.uuid
+    return {'topology_id': topology_id, 'device_id': device_uuid, 'endpoint_uuid': endpoint_uuid}
+
+def compose_capacity(value : str, unit : str) -> Dict:
+    return {'total-size': {'value': value, 'unit': unit}}
+
+def compose_endpoint(
+    endpoint_id : Dict, endpoint_type : str, link_port_direction : int, termination_direction : int,
+    termination_state : int, total_potential_capacity : Dict, available_capacity : Dict
+) -> Dict:
+    return {
+        'endpoint_id': endpoint_id, 'endpoint_type': endpoint_type, 'link_port_direction': link_port_direction,
+        'termination-direction': termination_direction, 'termination-state': termination_state,
+        'total-potential-capacity': total_potential_capacity, 'available-capacity': available_capacity,
+    }
+
+def compose_cost_characteristics(cost_name : str, cost_value : str, cost_algorithm : str) -> Dict:
+    return {'cost-name': cost_name, 'cost-value': cost_value, 'cost-algorithm': cost_algorithm}
+
+def compose_latency_characteristics(fixed_latency_characteristic : str) -> Dict:
+    return {'fixed-latency-characteristic': fixed_latency_characteristic}
+
+def compose_constraint(constraint : Constraint) -> Dict:
+    if constraint.WhichOneof('constraint') != 'custom':
+        str_constraint = grpc_message_to_json_string(constraint)
+        LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint))
+        return None
+    constraint_type = constraint.custom.constraint_type
+    if constraint_type in {'diversity'}:
+        str_constraint = grpc_message_to_json_string(constraint)
+        LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint))
+        return None
+    constraint_value = constraint.custom.constraint_value
+    return {'constraint_type': constraint_type, 'constraint_value': constraint_value}
+
+def compose_device(grpc_device : Device) -> Dict:
+    device_uuid = grpc_device.device_id.device_uuid.uuid
+    device_type = grpc_device.device_type
+
+    endpoints = []
+    for device_endpoint in grpc_device.device_endpoints:
+        endpoint_id = compose_endpoint_id(device_endpoint.endpoint_id)
+        endpoint_type = device_endpoint.endpoint_type
+        link_port_direction = LinkPortDirection.BIDIRECTIONAL.value
+        termination_direction = TerminationDirection.BIDIRECTIONAL.value
+        termination_state = TerminationState.TERMINATED_BIDIRECTIONAL.value
+        total_potential_capacity = compose_capacity(200, CapacityUnit.MBPS.value)
+        available_capacity = compose_capacity(200, CapacityUnit.MBPS.value)
+        endpoint = compose_endpoint(
+            endpoint_id, endpoint_type, link_port_direction, termination_direction,
+            termination_state, total_potential_capacity, available_capacity)
+        endpoints.append(endpoint)
+
+    return {'device_Id': device_uuid, 'device_type': device_type, 'device_endpoints': endpoints}
+
+def compose_link(grpc_link : Link) -> Dict:
+    link_uuid = grpc_link.link_id.link_uuid.uuid
+
+    endpoint_ids = [
+        {'endpoint_id' : compose_endpoint_id(link_endpoint_id)}
+        for link_endpoint_id in grpc_link.link_endpoint_ids
+    ]
+
+    forwarding_direction = LinkForwardingDirection.BIDIRECTIONAL.value
+    total_potential_capacity = compose_capacity(200, CapacityUnit.MBPS.value)
+    available_capacity = compose_capacity(200, CapacityUnit.MBPS.value)
+    cost_characteristics = compose_cost_characteristics('linkcost', '1', '0')
+    latency_characteristics = compose_latency_characteristics('2')
+
+    return {
+        'link_Id': link_uuid, 'link_endpoint_ids': endpoint_ids, 'forwarding_direction': forwarding_direction,
+        'total-potential-capacity': total_potential_capacity, 'available-capacity': available_capacity,
+        'cost-characteristics': cost_characteristics, 'latency-characteristics': latency_characteristics,
+    }
+
+def compose_service(grpc_service : Service) -> Dict:
+    service_id = compose_service_id(grpc_service.service_id)
+    service_type = grpc_service.service_type
+
+    endpoint_ids = [
+        compose_endpoint_id(service_endpoint_id)
+        for service_endpoint_id in grpc_service.service_endpoint_ids
+    ]
+
+    constraints = list(filter(lambda constraint: constraint is not None, [
+        compose_constraint(service_constraint)
+        for service_constraint in grpc_service.service_constraints
+    ]))
+
+    constraint_types = {constraint['constraint_type'] for constraint in constraints}
+    if 'bandwidth[gbps]' not in constraint_types:
+        constraints.append({'constraint_type': 'bandwidth[gbps]', 'constraint_value': '20.0'})
+    if 'latency[ms]' not in constraint_types:
+        constraints.append({'constraint_type': 'latency[ms]', 'constraint_value': '20.0'})
+
+    return {
+        'serviceId': service_id,
+        'serviceType': service_type,
+        'service_endpoints_ids': endpoint_ids,
+        'service_constraints': constraints,
+    }
diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py b/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.py
new file mode 100644
index 0000000000000000000000000000000000000000..f2c66cb24ca3c15c71f22dbe4eeca634e18d985a
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/tools/ComputeSubServices.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.
+
+# Convert the path defined as explicit hops with ingress and egress endpoints per device into a set of connections and
+# compute the dependencies among them.
+#
+# Example:
+# o-- int DC1 eth1 -- 10/1 CS1 1/2 -- 1/2 R2 2/1 -- a7.. OLS 60.. -- 2/1 R3 1/1 -- 1/1 CS2 10/1 -- eth1 DC2 int --o
+#         APP              PKT            PKT            CTRL            PKT           PKT              APP
+#
+# path_hops = [
+#     {'device': 'DC1-GW', 'ingress_ep': 'int', 'egress_ep': 'eth1'},
+#     {'device': 'CS1-GW1', 'ingress_ep': '10/1', 'egress_ep': '1/2'},
+#     {'device': 'TN-R2', 'ingress_ep': '1/2', 'egress_ep': '2/1'},
+#     {'device': 'TN-OLS', 'ingress_ep': 'a7a80b23a703', 'egress_ep': '60519106029e'},
+#     {'device': 'TN-R3', 'ingress_ep': '2/1', 'egress_ep': '1/1'},
+#     {'device': 'CS2-GW1', 'ingress_ep': '1/1', 'egress_ep': '10/1'},
+#     {'device': 'DC2-GW', 'ingress_ep': 'eth1', 'egress_ep': 'int'}
+# ]
+#
+# connections=[
+#     (UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e'), <DeviceLayerEnum.OPTICAL_CONTROLLER: 1>, [
+#             {'device': 'TN-OLS', 'ingress_ep': '833760219d0f', 'egress_ep': 'cf176771a4b9'}
+#         ], []),
+#     (UUID('c2e57966-5d82-4705-a5fe-44cf6487219e'), <DeviceLayerEnum.PACKET_DEVICE: 30>, [
+#             {'device': 'CS1-GW1', 'ingress_ep': '10/1', 'egress_ep': '1/2'},
+#             {'device': 'TN-R2', 'ingress_ep': '1/2', 'egress_ep': '2/1'},
+#             {'device': 'TN-R3', 'ingress_ep': '2/1', 'egress_ep': '1/1'},
+#             {'device': 'CS2-GW1', 'ingress_ep': '1/1', 'egress_ep': '10/1'}
+#         ], [UUID('7548edf7-ee7c-4adf-ac0f-c7a0c0dfba8e')]),
+#     (UUID('1e205c82-f6ea-4977-9e97-dc27ef1f4802'), <DeviceLayerEnum.APPLICATION_DEVICE: 40>, [
+#             {'device': 'DC1-GW', 'ingress_ep': 'int', 'egress_ep': 'eth1'},
+#             {'device': 'DC2-GW', 'ingress_ep': 'eth1', 'egress_ep': 'int'}
+#         ], [UUID('c2e57966-5d82-4705-a5fe-44cf6487219e')])
+# ]
+
+import queue, uuid
+from typing import Dict, List, Tuple
+from common.proto.context_pb2 import Device
+from .ConstantsMappings import DEVICE_TYPE_TO_LAYER, DeviceLayerEnum
+
+def convert_explicit_path_hops_to_connections(
+    path_hops : List[Dict], device_dict : Dict[str, Tuple[Dict, Device]], main_connection_uuid : str
+) -> List[Tuple[str, DeviceLayerEnum, List[str], List[str]]]:
+
+    connection_stack = queue.LifoQueue()
+    connections : List[Tuple[str, DeviceLayerEnum, List[str], List[str]]] = list()
+    old_device_layer = None
+    last_device_uuid = None
+    for path_hop in path_hops:
+        device_uuid = path_hop['device']
+        if last_device_uuid == device_uuid: continue
+        device_tuple = device_dict.get(device_uuid)
+        if device_tuple is None: raise Exception('Device({:s}) not found'.format(str(device_uuid)))
+        json_device,_ = device_tuple
+        device_type = json_device['device_type']
+        device_layer = DEVICE_TYPE_TO_LAYER.get(device_type)
+        if device_layer is None: raise Exception('Undefined Layer for DeviceType({:s})'.format(str(device_type)))
+
+        if old_device_layer is None:
+            # path ingress
+            connection_stack.put((main_connection_uuid, device_layer, [path_hop], []))
+        elif old_device_layer > device_layer:
+            # underlying connection begins
+            connection_uuid = str(uuid.uuid4())
+            connection_stack.put((connection_uuid, device_layer, [path_hop], []))
+        elif old_device_layer == device_layer:
+            # same connection continues
+            connection_stack.queue[-1][2].append(path_hop)
+        elif old_device_layer < device_layer:
+            # underlying connection ended
+            connection = connection_stack.get()
+            connections.append(connection)
+            connection_stack.queue[-1][3].append(connection[0])
+            connection_stack.queue[-1][2].append(path_hop)
+        else:
+            raise Exception('Uncontrolled condition')
+
+        old_device_layer = device_layer
+        last_device_uuid = device_uuid
+
+    # path egress
+    connections.append(connection_stack.get())
+    assert connection_stack.empty()
+    return connections
diff --git a/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py b/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py
new file mode 100644
index 0000000000000000000000000000000000000000..755549a7f078439dc317e7b3f4dd0b949e6a9bea
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/tools/ConstantsMappings.py
@@ -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.
+
+from enum import IntEnum
+from common.DeviceTypes import DeviceTypeEnum
+from common.proto.context_pb2 import ServiceTypeEnum
+
+class CapacityUnit(IntEnum):
+    TB   = 0
+    TBPS = 1
+    GB   = 2
+    GBPS = 3
+    MB   = 4
+    MBPS = 5
+    KB   = 6
+    KBPS = 7
+    GHZ  = 8
+    MHZ  = 9
+
+CAPACITY_MULTIPLIER = {
+    CapacityUnit.TB   : 1.e12,
+    CapacityUnit.TBPS : 1.e12,
+    CapacityUnit.GB   : 1.e9,
+    CapacityUnit.GBPS : 1.e9,
+    CapacityUnit.MB   : 1.e6,
+    CapacityUnit.MBPS : 1.e6,
+    CapacityUnit.KB   : 1.e3,
+    CapacityUnit.KBPS : 1.e3,
+    CapacityUnit.GHZ  : 1.e9,
+    CapacityUnit.MHZ  : 1.e6,
+}
+
+class LinkPortDirection(IntEnum):
+    BIDIRECTIONAL = 0
+    INPUT         = 1
+    OUTPUT        = 2
+    UNKNOWN       = 3
+
+class TerminationDirection(IntEnum):
+    BIDIRECTIONAL = 0
+    SINK          = 1
+    SOURCE        = 2
+    UNKNOWN       = 3
+
+class TerminationState(IntEnum):
+    CAN_NEVER_TERMINATE         = 0
+    NOT_TERMINATED              = 1
+    TERMINATED_SERVER_TO_CLIENT = 2
+    TERMINATED_CLIENT_TO_SERVER = 3
+    TERMINATED_BIDIRECTIONAL    = 4
+    PERMENANTLY_TERMINATED      = 5
+    TERMINATION_STATE_UNKNOWN   = 6
+
+class LinkForwardingDirection(IntEnum):
+    BIDIRECTIONAL  = 0
+    UNIDIRECTIONAL = 1
+    UNKNOWN        = 2
+
+class DeviceLayerEnum(IntEnum):
+    APPLICATION_CONTROLLER = 41     # Layer 4 domain controller
+    APPLICATION_DEVICE     = 40     # Layer 4 domain device
+    PACKET_CONTROLLER      = 31     # Layer 3 domain controller
+    PACKET_DEVICE          = 30     # Layer 3 domain device
+    MAC_LAYER_CONTROLLER   = 21     # Layer 2 domain controller
+    MAC_LAYER_DEVICE       = 20     # Layer 2 domain device
+    OPTICAL_CONTROLLER     =  1     # Layer 0 domain controller
+    OPTICAL_DEVICE         =  0     # Layer 0 domain device
+
+DEVICE_TYPE_TO_LAYER = {
+    DeviceTypeEnum.EMULATED_DATACENTER.value      : DeviceLayerEnum.APPLICATION_DEVICE,
+    DeviceTypeEnum.DATACENTER.value               : DeviceLayerEnum.APPLICATION_DEVICE,
+
+    DeviceTypeEnum.EMULATED_PACKET_ROUTER.value   : DeviceLayerEnum.PACKET_DEVICE,
+    DeviceTypeEnum.PACKET_ROUTER.value            : DeviceLayerEnum.PACKET_DEVICE,
+    DeviceTypeEnum.PACKET_SWITCH.value            : DeviceLayerEnum.MAC_LAYER_DEVICE,
+    DeviceTypeEnum.P4_SWITCH.value                : DeviceLayerEnum.MAC_LAYER_DEVICE,
+
+    DeviceTypeEnum.MICROVAWE_RADIO_SYSTEM.value   : DeviceLayerEnum.MAC_LAYER_CONTROLLER,
+
+    DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value: DeviceLayerEnum.OPTICAL_CONTROLLER,
+    DeviceTypeEnum.OPEN_LINE_SYSTEM.value         : DeviceLayerEnum.OPTICAL_CONTROLLER,
+    DeviceTypeEnum.XR_CONSTELLATION.value         : DeviceLayerEnum.OPTICAL_CONTROLLER,
+
+    DeviceTypeEnum.OPTICAL_ROADM.value            : DeviceLayerEnum.OPTICAL_DEVICE,
+    DeviceTypeEnum.OPTICAL_TRANSPONDER.value      : DeviceLayerEnum.OPTICAL_DEVICE,
+}
+
+DEVICE_LAYER_TO_SERVICE_TYPE = {
+    DeviceLayerEnum.APPLICATION_DEVICE.value: ServiceTypeEnum.SERVICETYPE_L3NM,
+
+    DeviceLayerEnum.PACKET_DEVICE.value     : ServiceTypeEnum.SERVICETYPE_L3NM,
+    DeviceLayerEnum.MAC_LAYER_DEVICE.value  : ServiceTypeEnum.SERVICETYPE_L2NM,
+
+    DeviceLayerEnum.OPTICAL_CONTROLLER.value: ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+}
diff --git a/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py b/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.py
new file mode 100644
index 0000000000000000000000000000000000000000..021940937c23a7cb461a603aa32a15f16626eb1d
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/tools/EroPathToHops.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.
+
+# Convert the Explicit Route Object (ERO)-like paths produced by the PathComp component (response['path']) into
+# explicit hops with ingress and egress endpoints per device (path_hops).
+#
+# response['path'] = [{
+#     'path-capacity': {'total-size': {'value': 200, 'unit': 0}},
+#     'path-latency': {'fixed-latency-characteristic': '12.000000'},
+#     'path-cost': {'cost-name': '', 'cost-value': '6.000000', 'cost-algorithm': '0.000000'},
+#     'devices': [
+#         {'device_id': 'DC1-GW', 'endpoint_uuid': 'int'},
+#         {'device_id': 'DC1-GW', 'endpoint_uuid': 'eth1'},
+#         {'device_id': 'CS1-GW1', 'endpoint_uuid': '1/2'},
+#         {'device_id': 'TN-R2', 'endpoint_uuid': '2/1'},
+#         {'device_id': 'TN-OLS', 'endpoint_uuid': 'ca46812e8ad7'},
+#         {'device_id': 'TN-R3', 'endpoint_uuid': '1/1'},
+#         {'device_id': 'CS2-GW1', 'endpoint_uuid': '10/1'},
+#         {'device_id': 'DC2-GW', 'endpoint_uuid': 'int'}
+#     ]
+# }]
+#
+# path_hops = [
+#   {'device': 'DC1-GW', 'ingress_ep': 'int', 'egress_ep': 'eth1'},
+#   {'device': 'CS1-GW1', 'ingress_ep': '10/1', 'egress_ep': '1/2'},
+#   {'device': 'TN-R2', 'ingress_ep': '1/2', 'egress_ep': '2/1'},
+#   {'device': 'TN-OLS', 'ingress_ep': '951f2f57e4a4', 'egress_ep': 'ca46812e8ad7'},
+#   {'device': 'TN-R3', 'ingress_ep': '2/1', 'egress_ep': '1/1'},
+#   {'device': 'CS2-GW1', 'ingress_ep': '1/1', 'egress_ep': '10/1'},
+#   {'device': 'DC2-GW', 'ingress_ep': 'eth1', 'egress_ep': 'int'}
+# ]
+#
+
+from typing import Dict, List
+
+def eropath_to_hops(ero_path : List[Dict], endpoint_to_link_dict : Dict) -> List[Dict]:
+    path_hops = []
+    for endpoint in ero_path:
+        device_uuid = endpoint['device_id']
+        endpoint_uuid = endpoint['endpoint_uuid']
+
+        if len(path_hops) == 0:
+            path_hops.append({'device': device_uuid, 'ingress_ep': endpoint_uuid})
+            continue
+
+        last_hop = path_hops[-1]
+        if (last_hop['device'] == device_uuid):
+            if ('ingress_ep' not in last_hop) or ('egress_ep' in last_hop): continue
+            last_hop['egress_ep'] = endpoint_uuid
+            continue
+
+        endpoint_key = (last_hop['device'], last_hop['egress_ep'])
+        link_tuple = endpoint_to_link_dict.get(endpoint_key)
+        ingress = next(iter([
+            ep_id for ep_id in link_tuple[0]['link_endpoint_ids']
+            if (ep_id['endpoint_id']['device_id'] == device_uuid) and\
+                (ep_id['endpoint_id']['endpoint_uuid'] != endpoint_uuid)
+        ]), None)
+        if ingress['endpoint_id']['device_id'] != device_uuid: raise Exception('Malformed path')
+        path_hops.append({
+            'device': ingress['endpoint_id']['device_id'],
+            'ingress_ep': ingress['endpoint_id']['endpoint_uuid'],
+            'egress_ep': endpoint_uuid,
+        })
+    return path_hops
diff --git a/src/pathcomp/frontend/service/algorithms/tools/__init__.py b/src/pathcomp/frontend/service/algorithms/tools/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/pathcomp/frontend/service/algorithms/tools/__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/pathcomp/tests/.gitignore b/src/pathcomp/frontend/tests/.gitignore
similarity index 100%
rename from src/pathcomp/tests/.gitignore
rename to src/pathcomp/frontend/tests/.gitignore
diff --git a/src/pathcomp/tests/MockService_Dependencies.py b/src/pathcomp/frontend/tests/MockService_Dependencies.py
similarity index 63%
rename from src/pathcomp/tests/MockService_Dependencies.py
rename to src/pathcomp/frontend/tests/MockService_Dependencies.py
index b5fe85aa9cec8dd3e3993493abf8a26956a1a886..16ff9a5efca5827fdb531dad74aabff29507a580 100644
--- a/src/pathcomp/tests/MockService_Dependencies.py
+++ b/src/pathcomp/frontend/tests/MockService_Dependencies.py
@@ -17,18 +17,12 @@ 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.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
-from common.proto.device_pb2_grpc import add_DeviceServiceServicer_to_server
-from common.proto.service_pb2_grpc import add_ServiceServiceServicer_to_server
 from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
-from common.tests.MockServicerImpl_Device import MockServicerImpl_Device
-from common.tests.MockServicerImpl_Service import MockServicerImpl_Service
 from common.tools.service.GenericGrpcService import GenericGrpcService
 
 LOCAL_HOST = '127.0.0.1'
 
 SERVICE_CONTEXT = ServiceNameEnum.CONTEXT
-SERVICE_DEVICE  = ServiceNameEnum.DEVICE
-SERVICE_SERVICE = ServiceNameEnum.SERVICE
 
 class MockService_Dependencies(GenericGrpcService):
     # Mock Service implementing Context, Device, and Service to simplify unitary tests of PathComp
@@ -41,18 +35,6 @@ class MockService_Dependencies(GenericGrpcService):
         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)
-
-        self.service_servicer = MockServicerImpl_Service()
-        add_ServiceServiceServicer_to_server(self.service_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)
-
-        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)
diff --git a/src/pathcomp/tests/Objects.py b/src/pathcomp/frontend/tests/Objects_A_B_C.py
similarity index 70%
rename from src/pathcomp/tests/Objects.py
rename to src/pathcomp/frontend/tests/Objects_A_B_C.py
index f4785d7ae670efcc5525d6b00c4baf3acf3f22b1..510ebb6746ccb8d050d5eb6ea91ec6354f224459 100644
--- a/src/pathcomp/tests/Objects.py
+++ b/src/pathcomp/frontend/tests/Objects_A_B_C.py
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
-from common.tools.object_factory.Constraint import json_constraint
+from common.tools.object_factory.Constraint import json_constraint_custom
 from common.tools.object_factory.Context import json_context, json_context_id
 from common.tools.object_factory.Device import json_device_emulated_packet_router_disabled, json_device_id
 from common.tools.object_factory.EndPoint import json_endpoints
@@ -21,10 +21,10 @@ from common.tools.object_factory.Link import get_link_uuid, json_link, json_link
 from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned
 from common.tools.object_factory.Topology import json_topology, json_topology_id
 
-def compose_device(device_uuid, endpoint_uuids):
+def compose_device(device_uuid, endpoint_uuids, topology_id=None):
     device_id = json_device_id(device_uuid)
     endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
-    endpoints = json_endpoints(device_id, endpoints, topology_id=TOPOLOGY_A_ID)
+    endpoints = json_endpoints(device_id, endpoints, topology_id=topology_id)
     device = json_device_emulated_packet_router_disabled(device_uuid, endpoints=endpoints)
     return device_id, endpoints, device
 
@@ -45,32 +45,36 @@ CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
 CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
 
 # ----- Domains --------------------------------------------------------------------------------------------------------
-TOPOLOGY_ADMIN_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID)
-TOPOLOGY_ADMIN    = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID)
+TOPOLOGY_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID
+TOPOLOGY_ADMIN_ID   = json_topology_id(TOPOLOGY_ADMIN_UUID, context_id=CONTEXT_ID)
+TOPOLOGY_ADMIN      = json_topology(TOPOLOGY_ADMIN_UUID, context_id=CONTEXT_ID)
 
-TOPOLOGY_A_ID = json_topology_id('A', context_id=CONTEXT_ID)
-TOPOLOGY_A    = json_topology('A', context_id=CONTEXT_ID)
+TOPOLOGY_A_UUID = 'A'
+TOPOLOGY_A_ID   = json_topology_id(TOPOLOGY_A_UUID, context_id=CONTEXT_ID)
+TOPOLOGY_A      = json_topology(TOPOLOGY_A_UUID, context_id=CONTEXT_ID)
 
-TOPOLOGY_B_ID = json_topology_id('B', context_id=CONTEXT_ID)
-TOPOLOGY_B    = json_topology('B', context_id=CONTEXT_ID)
+TOPOLOGY_B_UUID = 'B'
+TOPOLOGY_B_ID   = json_topology_id(TOPOLOGY_B_UUID, context_id=CONTEXT_ID)
+TOPOLOGY_B      = json_topology(TOPOLOGY_B_UUID, context_id=CONTEXT_ID)
 
-TOPOLOGY_C_ID = json_topology_id('C', context_id=CONTEXT_ID)
-TOPOLOGY_C    = json_topology('C', context_id=CONTEXT_ID)
+TOPOLOGY_C_UUID = 'C'
+TOPOLOGY_C_ID   = json_topology_id(TOPOLOGY_C_UUID, context_id=CONTEXT_ID)
+TOPOLOGY_C      = json_topology(TOPOLOGY_C_UUID, context_id=CONTEXT_ID)
 
 # ----- Devices Domain A -----------------------------------------------------------------------------------------------
-DEVICE_A1_ID, DEVICE_A1_ENDPOINTS, DEVICE_A1 = compose_device('A1', ['1', '2', '2000'])
-DEVICE_A2_ID, DEVICE_A2_ENDPOINTS, DEVICE_A2 = compose_device('A2', ['1', '2', '1001'])
-DEVICE_A3_ID, DEVICE_A3_ENDPOINTS, DEVICE_A3 = compose_device('A3', ['1', '2'])
+DEVICE_A1_ID, DEVICE_A1_ENDPOINTS, DEVICE_A1 = compose_device('A1', ['1', '2', '2000'], topology_id=TOPOLOGY_A_ID)
+DEVICE_A2_ID, DEVICE_A2_ENDPOINTS, DEVICE_A2 = compose_device('A2', ['1', '2', '1001'], topology_id=TOPOLOGY_A_ID)
+DEVICE_A3_ID, DEVICE_A3_ENDPOINTS, DEVICE_A3 = compose_device('A3', ['1', '2'        ], topology_id=TOPOLOGY_A_ID)
 
 # ----- Devices Domain B -----------------------------------------------------------------------------------------------
-DEVICE_B1_ID, DEVICE_B1_ENDPOINTS, DEVICE_B1 = compose_device('B1', ['1', '2', '2000'])
-DEVICE_B2_ID, DEVICE_B2_ENDPOINTS, DEVICE_B2 = compose_device('B2', ['1', '2', '1002'])
-DEVICE_B3_ID, DEVICE_B3_ENDPOINTS, DEVICE_B3 = compose_device('B3', ['1', '2'])
+DEVICE_B1_ID, DEVICE_B1_ENDPOINTS, DEVICE_B1 = compose_device('B1', ['1', '2', '2000'], topology_id=TOPOLOGY_B_ID)
+DEVICE_B2_ID, DEVICE_B2_ENDPOINTS, DEVICE_B2 = compose_device('B2', ['1', '2', '1002'], topology_id=TOPOLOGY_B_ID)
+DEVICE_B3_ID, DEVICE_B3_ENDPOINTS, DEVICE_B3 = compose_device('B3', ['1', '2'        ], topology_id=TOPOLOGY_B_ID)
 
 # ----- Devices Domain C -----------------------------------------------------------------------------------------------
-DEVICE_C1_ID, DEVICE_C1_ENDPOINTS, DEVICE_C1 = compose_device('C1', ['1', '2', '1001'])
-DEVICE_C2_ID, DEVICE_C2_ENDPOINTS, DEVICE_C2 = compose_device('C2', ['1', '2'])
-DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', '1002'])
+DEVICE_C1_ID, DEVICE_C1_ENDPOINTS, DEVICE_C1 = compose_device('C1', ['1', '2', '1001'], topology_id=TOPOLOGY_C_ID)
+DEVICE_C2_ID, DEVICE_C2_ENDPOINTS, DEVICE_C2 = compose_device('C2', ['1', '2'        ], topology_id=TOPOLOGY_C_ID)
+DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', '1002'], topology_id=TOPOLOGY_C_ID)
 
 # ----- InterDomain Links ----------------------------------------------------------------------------------------------
 LINK_A2_C3_ID, LINK_A2_C3 = compose_link(DEVICE_A2_ENDPOINTS[2], DEVICE_C3_ENDPOINTS[2])
@@ -93,13 +97,13 @@ LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPO
 
 # ----- Service --------------------------------------------------------------------------------------------------------
 SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[
-    json_constraint('bandwidth[gbps]', 10.0),
-    json_constraint('latency[ms]',      5.0),
+    json_constraint_custom('bandwidth[gbps]', 10.0),
+    json_constraint_custom('latency[ms]',     12.0),
 ])
 
 # ----- Containers -----------------------------------------------------------------------------------------------------
-CONTEXTS   = [CONTEXT]
-TOPOLOGIES = [TOPOLOGY_ADMIN, TOPOLOGY_A, TOPOLOGY_B, TOPOLOGY_C]
+CONTEXTS   = [  CONTEXT]
+TOPOLOGIES = [  TOPOLOGY_ADMIN, TOPOLOGY_A, TOPOLOGY_B, TOPOLOGY_C]
 DEVICES    = [  DEVICE_A1, DEVICE_A2, DEVICE_A3,
                 DEVICE_B1, DEVICE_B2, DEVICE_B3,
                 DEVICE_C1, DEVICE_C2, DEVICE_C3,    ]
@@ -107,4 +111,28 @@ LINKS      = [  LINK_A2_C3, LINK_C1_B2,
                 LINK_A1_A2, LINK_A1_A3, LINK_A2_A3,
                 LINK_B1_B2, LINK_B1_B3, LINK_B2_B3,
                 LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, ]
-SERVICES   = [SERVICE_A1_B1]
+SERVICES   = [  SERVICE_A1_B1]
+
+OBJECTS_PER_TOPOLOGY = [
+    (TOPOLOGY_ADMIN_ID,
+        [   DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID,
+            DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID,
+            DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID,       ],
+        [   LINK_A2_C3_ID, LINK_C1_B2_ID,
+            LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID,
+            LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID,
+            LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID,    ],
+    ),
+    (TOPOLOGY_A_ID,
+        [   DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID,       ],
+        [   LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID,    ],
+    ),
+    (TOPOLOGY_B_ID,
+        [   DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID,       ],
+        [   LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID,    ],
+    ),
+    (TOPOLOGY_C_ID,
+        [   DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID,       ],
+        [   LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID,    ],
+    ),
+]
diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py
new file mode 100644
index 0000000000000000000000000000000000000000..06e9bbbc715a85a2c0d979584c58b268bff687e6
--- /dev/null
+++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py
@@ -0,0 +1,191 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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.Constraint import json_constraint_custom
+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_datacenter_disabled,
+    json_device_emulated_packet_router_disabled, json_device_id)
+from common.tools.object_factory.EndPoint import json_endpoints
+from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id
+from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+
+# if true, Device component is present and will infeer the endpoints from connect-rules
+# if false, Device component is not present and device objects must contain preconfigured endpoints
+ADD_CONNECT_RULES_TO_DEVICES = False
+
+def compose_router(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_packet_router_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_datacenter(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_datacenter_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_link(endpoint_a, endpoint_z):
+    link_uuid = get_link_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    link_id   = json_link_id(link_uuid)
+    link      = json_link(link_uuid, [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']])
+    return link_id, link
+
+def compose_service(endpoint_a, endpoint_z, constraints=[]):
+    service_uuid = get_service_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    endpoint_ids = [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']]
+    service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints)
+    return service
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+# ----- Domains --------------------------------------------------------------------------------------------------------
+# Overall network topology
+TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID
+TOPO_ADMIN_ID   = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+TOPO_ADMIN      = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #1 Network
+TOPO_DC1_UUID = 'DC1'
+TOPO_DC1_ID   = json_topology_id(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+TOPO_DC1      = json_topology(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #2 Network
+TOPO_DC2_UUID = 'DC2'
+TOPO_DC2_ID   = json_topology_id(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+TOPO_DC2      = json_topology(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+
+# CellSite #1 Network
+TOPO_CS1_UUID = 'CS1'
+TOPO_CS1_ID   = json_topology_id(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+TOPO_CS1      = json_topology(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+
+# CellSite #2 Network
+TOPO_CS2_UUID = 'CS2'
+TOPO_CS2_ID   = json_topology_id(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+TOPO_CS2      = json_topology(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+
+# Transport Network Network
+TOPO_TN_UUID = 'TN'
+TOPO_TN_ID   = json_topology_id(TOPO_TN_UUID, context_id=CONTEXT_ID)
+TOPO_TN      = json_topology(TOPO_TN_UUID, context_id=CONTEXT_ID)
+
+
+# ----- Devices --------------------------------------------------------------------------------------------------------
+# DataCenters
+DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_datacenter('DC1-GW', ['eth1', 'eth2', 'int'])
+DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_datacenter('DC2-GW', ['eth1', 'eth2', 'int'])
+
+# CellSites
+DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_router('CS1-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_router('CS1-GW2', ['10/1', '1/1', '1/2'])
+DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_router('CS2-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_router('CS2-GW2', ['10/1', '1/1', '1/2'])
+
+# Transport Network
+DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_router('TN-R1', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_router('TN-R2', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_router('TN-R3', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_router('TN-R4', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+# InterDomain DC-CSGW
+LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW1 = compose_link(DEV_DC1GW_EPS[0], DEV_CS1GW1_EPS[0])
+LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1GW2_EPS[0])
+LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0])
+LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0])
+
+# InterDomain CSGW-TN
+LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0])
+LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0])
+LINK_CS1GW1_TNR2_ID, LINK_CS1GW1_TNR2 = compose_link(DEV_CS1GW1_EPS[2], DEV_TNR2_EPS[1])
+LINK_CS1GW2_TNR1_ID, LINK_CS1GW2_TNR1 = compose_link(DEV_CS1GW2_EPS[2], DEV_TNR1_EPS[1])
+LINK_CS2GW1_TNR3_ID, LINK_CS2GW1_TNR3 = compose_link(DEV_CS2GW1_EPS[1], DEV_TNR3_EPS[0])
+LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4_EPS[0])
+LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1])
+LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1])
+
+# IntraDomain TN
+LINK_TNR1_TNR2_ID, LINK_TNR1_TNR2 = compose_link(DEV_TNR1_EPS[2], DEV_TNR2_EPS[3])
+LINK_TNR2_TNR3_ID, LINK_TNR2_TNR3 = compose_link(DEV_TNR2_EPS[2], DEV_TNR3_EPS[3])
+LINK_TNR3_TNR4_ID, LINK_TNR3_TNR4 = compose_link(DEV_TNR3_EPS[2], DEV_TNR4_EPS[3])
+LINK_TNR4_TNR1_ID, LINK_TNR4_TNR1 = compose_link(DEV_TNR4_EPS[2], DEV_TNR1_EPS[3])
+LINK_TNR1_TNR3_ID, LINK_TNR1_TNR3 = compose_link(DEV_TNR1_EPS[4], DEV_TNR3_EPS[4])
+LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4])
+
+
+# ----- Service --------------------------------------------------------------------------------------------------------
+SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[
+    json_constraint_custom('bandwidth[gbps]', 10.0),
+    json_constraint_custom('latency[ms]',     20.0),
+])
+
+# ----- Containers -----------------------------------------------------------------------------------------------------
+CONTEXTS   = [  CONTEXT ]
+TOPOLOGIES = [  TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN ]
+DEVICES    = [  DEV_DC1GW, DEV_DC2GW,
+                DEV_CS1GW1, DEV_CS1GW2, DEV_CS2GW1, DEV_CS2GW2,
+                DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4,
+            ]
+LINKS      = [  LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2,
+                LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1,
+                LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3,
+                LINK_TNR1_TNR2, LINK_TNR2_TNR3, LINK_TNR3_TNR4, LINK_TNR4_TNR1, LINK_TNR1_TNR3, LINK_TNR2_TNR4,
+            ]
+SERVICES   = [  SERVICE_DC1GW_DC2GW   ]
+
+OBJECTS_PER_TOPOLOGY = [
+    (TOPO_ADMIN_ID,
+        [   DEV_DC1GW_ID, DEV_DC2GW_ID,
+            DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID,
+            DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+        ],
+        [   LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID,
+            LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID,
+            LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID,
+            LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
+            LINK_TNR2_TNR4_ID,
+        ],
+    ),
+    (TOPO_DC1_ID,
+        [DEV_DC1GW_ID],
+        []),
+    (TOPO_DC2_ID,
+        [DEV_DC2GW_ID],
+        []),
+    (TOPO_CS1_ID,
+        [DEV_CS1GW1_ID, DEV_CS1GW2_ID],
+        []),
+    (TOPO_CS2_ID,
+        [DEV_CS2GW1_ID, DEV_CS2GW2_ID],
+        []),
+    (TOPO_TN_ID,
+        [   DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+        ],
+        [   LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
+            LINK_TNR2_TNR4_ID,
+        ]),
+]
diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py
new file mode 100644
index 0000000000000000000000000000000000000000..99fd83ed9e1a7ca27faa6acb11b07abd573423ef
--- /dev/null
+++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py
@@ -0,0 +1,202 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 uuid
+from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
+from common.tools.object_factory.Constraint import json_constraint_custom
+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_datacenter_disabled,
+    json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled, json_device_id)
+from common.tools.object_factory.EndPoint import json_endpoints
+from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id
+from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+
+# if true, Device component is present and will infeer the endpoints from connect-rules
+# if false, Device component is not present and device objects must contain preconfigured endpoints
+ADD_CONNECT_RULES_TO_DEVICES = False
+
+def compose_router(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_packet_router_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_ols(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'optical', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_tapi_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_datacenter(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_datacenter_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_link(endpoint_a, endpoint_z):
+    link_uuid = get_link_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    link_id   = json_link_id(link_uuid)
+    link      = json_link(link_uuid, [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']])
+    return link_id, link
+
+def compose_service(endpoint_a, endpoint_z, constraints=[]):
+    service_uuid = get_service_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    endpoint_ids = [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']]
+    service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints)
+    return service
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+# ----- Domains --------------------------------------------------------------------------------------------------------
+# Overall network topology
+TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID
+TOPO_ADMIN_ID   = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+TOPO_ADMIN      = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #1 Network
+TOPO_DC1_UUID = 'DC1'
+TOPO_DC1_ID   = json_topology_id(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+TOPO_DC1      = json_topology(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #2 Network
+TOPO_DC2_UUID = 'DC2'
+TOPO_DC2_ID   = json_topology_id(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+TOPO_DC2      = json_topology(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+
+# CellSite #1 Network
+TOPO_CS1_UUID = 'CS1'
+TOPO_CS1_ID   = json_topology_id(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+TOPO_CS1      = json_topology(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+
+# CellSite #2 Network
+TOPO_CS2_UUID = 'CS2'
+TOPO_CS2_ID   = json_topology_id(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+TOPO_CS2      = json_topology(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+
+# Transport Network Network
+TOPO_TN_UUID = 'TN'
+TOPO_TN_ID   = json_topology_id(TOPO_TN_UUID, context_id=CONTEXT_ID)
+TOPO_TN      = json_topology(TOPO_TN_UUID, context_id=CONTEXT_ID)
+
+
+# ----- Devices --------------------------------------------------------------------------------------------------------
+# DataCenters
+DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_datacenter('DC1-GW', ['eth1', 'eth2', 'int'])
+DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_datacenter('DC2-GW', ['eth1', 'eth2', 'int'])
+
+# CellSites
+DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_router('CS1-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_router('CS1-GW2', ['10/1', '1/1', '1/2'])
+DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_router('CS2-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_router('CS2-GW2', ['10/1', '1/1', '1/2'])
+
+# Transport Network
+DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_router('TN-R1', ['1/1', '1/2', '2/1'])
+DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_router('TN-R2', ['1/1', '1/2', '2/1'])
+DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_router('TN-R3', ['1/1', '1/2', '2/1'])
+DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_router('TN-R4', ['1/1', '1/2', '2/1'])
+tols_ep_uuids = [str(uuid.uuid4()).split('-')[-1] for _ in range(4)]
+DEV_TOLS_ID, DEV_TOLS_EPS, DEV_TOLS = compose_ols('TN-OLS', tols_ep_uuids)
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+# InterDomain DC-CSGW
+LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW1 = compose_link(DEV_DC1GW_EPS[0], DEV_CS1GW1_EPS[0])
+LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1GW2_EPS[0])
+LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0])
+LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0])
+
+# InterDomain CSGW-TN
+LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0])
+LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0])
+LINK_CS1GW1_TNR2_ID, LINK_CS1GW1_TNR2 = compose_link(DEV_CS1GW1_EPS[2], DEV_TNR2_EPS[1])
+LINK_CS1GW2_TNR1_ID, LINK_CS1GW2_TNR1 = compose_link(DEV_CS1GW2_EPS[2], DEV_TNR1_EPS[1])
+LINK_CS2GW1_TNR3_ID, LINK_CS2GW1_TNR3 = compose_link(DEV_CS2GW1_EPS[1], DEV_TNR3_EPS[0])
+LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4_EPS[0])
+LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1])
+LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1])
+
+# IntraDomain TN
+LINK_TNR1_TOLS_ID, LINK_TNR1_TOLS = compose_link(DEV_TNR1_EPS[2], DEV_TOLS_EPS[0])
+LINK_TNR2_TOLS_ID, LINK_TNR2_TOLS = compose_link(DEV_TNR2_EPS[2], DEV_TOLS_EPS[1])
+LINK_TNR3_TOLS_ID, LINK_TNR3_TOLS = compose_link(DEV_TNR3_EPS[2], DEV_TOLS_EPS[2])
+LINK_TNR4_TOLS_ID, LINK_TNR4_TOLS = compose_link(DEV_TNR4_EPS[2], DEV_TOLS_EPS[3])
+
+
+# ----- Service --------------------------------------------------------------------------------------------------------
+SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[
+    json_constraint_custom('bandwidth[gbps]', 10.0),
+    json_constraint_custom('latency[ms]',     20.0),
+])
+
+# ----- Containers -----------------------------------------------------------------------------------------------------
+CONTEXTS   = [  CONTEXT ]
+TOPOLOGIES = [  TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN ]
+DEVICES    = [  DEV_DC1GW, DEV_DC2GW,
+                DEV_CS1GW1, DEV_CS1GW2, DEV_CS2GW1, DEV_CS2GW2,
+                DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4,
+                DEV_TOLS,
+            ]
+LINKS      = [  LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2,
+                LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1,
+                LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3,
+                LINK_TNR1_TOLS, LINK_TNR2_TOLS, LINK_TNR3_TOLS, LINK_TNR4_TOLS,
+            ]
+SERVICES   = [  SERVICE_DC1GW_DC2GW   ]
+
+OBJECTS_PER_TOPOLOGY = [
+    (TOPO_ADMIN_ID,
+        [   DEV_DC1GW_ID, DEV_DC2GW_ID,
+            DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID,
+            DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+            DEV_TOLS_ID,
+        ],
+        [   LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID,
+            LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID,
+            LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID,
+            LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID,
+        ],
+    ),
+    (TOPO_DC1_ID,
+        [DEV_DC1GW_ID],
+        []),
+    (TOPO_DC2_ID,
+        [DEV_DC2GW_ID],
+        []),
+    (TOPO_CS1_ID,
+        [DEV_CS1GW1_ID, DEV_CS1GW2_ID],
+        []),
+    (TOPO_CS2_ID,
+        [DEV_CS2GW1_ID, DEV_CS2GW2_ID],
+        []),
+    (TOPO_TN_ID,
+        [   DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+            DEV_TOLS_ID,
+        ],
+        [   LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID,
+        ]),
+]
diff --git a/src/pathcomp/tests/PrepareTestScenario.py b/src/pathcomp/frontend/tests/PrepareTestScenario.py
similarity index 73%
rename from src/pathcomp/tests/PrepareTestScenario.py
rename to src/pathcomp/frontend/tests/PrepareTestScenario.py
index a4efcbdbfc0d311dfb120ab8124a9d2268660daf..2e7002b0f70b81f0bbe728a7b8139730d004221e 100644
--- a/src/pathcomp/tests/PrepareTestScenario.py
+++ b/src/pathcomp/frontend/tests/PrepareTestScenario.py
@@ -17,14 +17,13 @@ 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 pathcomp.client.PathCompClient import PathCompClient
-from pathcomp.service.PathCompService import PathCompService
-from pathcomp.tests.MockService_Dependencies import MockService_Dependencies
+from pathcomp.frontend.client.PathCompClient import PathCompClient
+from pathcomp.frontend.service.PathCompService import PathCompService
+from pathcomp.frontend.tests.MockService_Dependencies import MockService_Dependencies
 
 LOCAL_HOST = '127.0.0.1'
 MOCKSERVICE_PORT = 10000
-PATHCOMP_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.PATHCOMP) # avoid privileged ports
+PATHCOMP_SERVICE_PORT = MOCKSERVICE_PORT + int(get_service_port_grpc(ServiceNameEnum.PATHCOMP)) # avoid privileged ports
 os.environ[get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
 os.environ[get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(PATHCOMP_SERVICE_PORT)
 
@@ -43,15 +42,7 @@ def context_client(mock_service : MockService_Dependencies): # pylint: disable=r
     _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 pathcomp_service(
-    context_client : ContextClient, # pylint: disable=redefined-outer-name
-    device_client : DeviceClient):  # pylint: disable=redefined-outer-name
+def pathcomp_service(context_client : ContextClient):       # pylint: disable=redefined-outer-name
 
     _service = PathCompService()
     _service.start()
diff --git a/src/pathcomp/frontend/tests/__init__.py b/src/pathcomp/frontend/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/pathcomp/frontend/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/pathcomp/frontend/tests/test_unitary.py b/src/pathcomp/frontend/tests/test_unitary.py
new file mode 100644
index 0000000000000000000000000000000000000000..53f4d7065e5ee847cd99f431c87c1231e52bbd63
--- /dev/null
+++ b/src/pathcomp/frontend/tests/test_unitary.py
@@ -0,0 +1,275 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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, os
+from common.proto.context_pb2 import Context, ContextId, DeviceId, Link, LinkId, Topology, Device, TopologyId
+from common.proto.pathcomp_pb2 import PathCompRequest
+from common.tools.grpc.Tools import grpc_message_to_json
+from common.tools.object_factory.Constraint import (
+    json_constraint_custom, json_constraint_endpoint_location_region, json_constraint_endpoint_priority,
+    json_constraint_sla_availability)
+from common.tools.object_factory.Device import json_device_id
+from common.tools.object_factory.EndPoint import json_endpoint_id
+from common.tools.object_factory.Service import json_service_l3nm_planned
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from pathcomp.frontend.client.PathCompClient import PathCompClient
+
+# Scenarios:
+#from .Objects_A_B_C import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES
+#from .Objects_DC_CSGW_TN import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES
+from .Objects_DC_CSGW_TN_OLS import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES
+
+# configure backend environment variables before overwriting them with fixtures to use real backend pathcomp
+DEFAULT_PATHCOMP_BACKEND_SCHEME  = 'http'
+DEFAULT_PATHCOMP_BACKEND_HOST    = '127.0.0.1'
+DEFAULT_PATHCOMP_BACKEND_PORT    = '8081'
+DEFAULT_PATHCOMP_BACKEND_BASEURL = '/pathComp/api/v1/compRoute'
+
+os.environ['PATHCOMP_BACKEND_SCHEME'] = os.environ.get('PATHCOMP_BACKEND_SCHEME', DEFAULT_PATHCOMP_BACKEND_SCHEME)
+os.environ['PATHCOMP_BACKEND_BASEURL'] = os.environ.get('PATHCOMP_BACKEND_BASEURL', DEFAULT_PATHCOMP_BACKEND_BASEURL)
+
+# Find IP:port of backend container as follows:
+# - first check env vars PATHCOMP_BACKEND_HOST & PATHCOMP_BACKEND_PORT
+# - if not set, check env vars PATHCOMPSERVICE_SERVICE_HOST & PATHCOMPSERVICE_SERVICE_PORT_HTTP
+# - if not set, use DEFAULT_PATHCOMP_BACKEND_HOST & DEFAULT_PATHCOMP_BACKEND_PORT
+backend_host = DEFAULT_PATHCOMP_BACKEND_HOST
+backend_host = os.environ.get('PATHCOMPSERVICE_SERVICE_HOST', backend_host)
+os.environ['PATHCOMP_BACKEND_HOST'] = os.environ.get('PATHCOMP_BACKEND_HOST', backend_host)
+
+backend_port = DEFAULT_PATHCOMP_BACKEND_PORT
+backend_port = os.environ.get('PATHCOMPSERVICE_SERVICE_PORT_HTTP', backend_port)
+os.environ['PATHCOMP_BACKEND_PORT'] = os.environ.get('PATHCOMP_BACKEND_PORT', backend_port)
+
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, pathcomp_service, context_client, pathcomp_client)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_prepare_environment(
+    context_client : ContextClient):    # pylint: disable=redefined-outer-name
+
+    for context  in CONTEXTS  : context_client.SetContext (Context (**context ))
+    for topology in TOPOLOGIES: context_client.SetTopology(Topology(**topology))
+    for device   in DEVICES   : context_client.SetDevice  (Device  (**device  ))
+    for link     in LINKS     : context_client.SetLink    (Link    (**link    ))
+
+    for topology_id, device_ids, link_ids in OBJECTS_PER_TOPOLOGY:
+        topology = Topology()
+        topology.CopyFrom(context_client.GetTopology(TopologyId(**topology_id)))
+
+        device_ids_in_topology = {device_id.device_uuid.uuid for device_id in topology.device_ids}
+        func_device_id_not_added = lambda device_id: device_id['device_uuid']['uuid'] not in device_ids_in_topology
+        func_device_id_json_to_grpc = lambda device_id: DeviceId(**device_id)
+        device_ids_to_add = list(map(func_device_id_json_to_grpc, filter(func_device_id_not_added, device_ids)))
+        topology.device_ids.extend(device_ids_to_add)
+
+        link_ids_in_topology = {link_id.link_uuid.uuid for link_id in topology.link_ids}
+        func_link_id_not_added = lambda link_id: link_id['link_uuid']['uuid'] not in link_ids_in_topology
+        func_link_id_json_to_grpc = lambda link_id: LinkId(**link_id)
+        link_ids_to_add = list(map(func_link_id_json_to_grpc, filter(func_link_id_not_added, link_ids)))
+        topology.link_ids.extend(link_ids_to_add)
+
+        context_client.SetTopology(topology)
+
+def test_request_service_shortestpath(
+    pathcomp_client : PathCompClient):  # pylint: disable=redefined-outer-name
+
+    request_services = copy.deepcopy(SERVICES)
+    #request_services[0]['service_constraints'] = [
+    #    json_constraint_custom('bandwidth[gbps]', 1000.0),
+    #    json_constraint_custom('latency[ms]',     1200.0),
+    #]
+    pathcomp_request = PathCompRequest(services=request_services)
+    pathcomp_request.shortest_path.Clear()  # hack to select the shortest path algorithm that has no attributes
+
+    pathcomp_reply = pathcomp_client.Compute(pathcomp_request)
+
+    pathcomp_reply = grpc_message_to_json(pathcomp_reply)
+    reply_services = pathcomp_reply['services']
+    reply_connections = pathcomp_reply['connections']
+    assert len(request_services) <= len(reply_services)
+    request_service_ids = {
+        '{:s}/{:s}'.format(
+            svc['service_id']['context_id']['context_uuid']['uuid'],
+            svc['service_id']['service_uuid']['uuid']
+        )
+        for svc in request_services
+    }
+    reply_service_ids = {
+        '{:s}/{:s}'.format(
+            svc['service_id']['context_id']['context_uuid']['uuid'],
+            svc['service_id']['service_uuid']['uuid']
+        )
+        for svc in reply_services
+    }
+    # Assert all requested services have a reply
+    # It permits having other services not requested (i.e., sub-services)
+    assert len(request_service_ids.difference(reply_service_ids)) == 0
+
+    reply_connection_service_ids = {
+        '{:s}/{:s}'.format(
+            conn['service_id']['context_id']['context_uuid']['uuid'],
+            conn['service_id']['service_uuid']['uuid']
+        )
+        for conn in reply_connections
+    }
+    # Assert all requested services have a connection associated
+    # It permits having other connections not requested (i.e., connections for sub-services)
+    assert len(request_service_ids.difference(reply_connection_service_ids)) == 0
+
+    # TODO: implement other checks. examples:
+    # - request service and reply service endpoints match
+    # - request service and reply connection endpoints match
+    # - reply sub-service and reply sub-connection endpoints match
+    # - others?
+    #for json_service,json_connection in zip(json_services, json_connections):
+
+
+def test_request_service_kshortestpath(
+    pathcomp_client : PathCompClient):  # pylint: disable=redefined-outer-name
+
+    request_services = SERVICES
+    pathcomp_request = PathCompRequest(services=request_services)
+    pathcomp_request.k_shortest_path.k_inspection = 2   #pylint: disable=no-member
+    pathcomp_request.k_shortest_path.k_return = 2       #pylint: disable=no-member
+
+    pathcomp_reply = pathcomp_client.Compute(pathcomp_request)
+
+    pathcomp_reply = grpc_message_to_json(pathcomp_reply)
+    reply_services = pathcomp_reply['services']
+    reply_connections = pathcomp_reply['connections']
+    assert len(request_services) <= len(reply_services)
+    request_service_ids = {
+        '{:s}/{:s}'.format(
+            svc['service_id']['context_id']['context_uuid']['uuid'],
+            svc['service_id']['service_uuid']['uuid']
+        )
+        for svc in request_services
+    }
+    reply_service_ids = {
+        '{:s}/{:s}'.format(
+            svc['service_id']['context_id']['context_uuid']['uuid'],
+            svc['service_id']['service_uuid']['uuid']
+        )
+        for svc in reply_services
+    }
+    # Assert all requested services have a reply
+    # It permits having other services not requested (i.e., sub-services)
+    assert len(request_service_ids.difference(reply_service_ids)) == 0
+
+    reply_connection_service_ids = {
+        '{:s}/{:s}'.format(
+            conn['service_id']['context_id']['context_uuid']['uuid'],
+            conn['service_id']['service_uuid']['uuid']
+        )
+        for conn in reply_connections
+    }
+    # Assert all requested services have a connection associated
+    # It permits having other connections not requested (i.e., connections for sub-services)
+    assert len(request_service_ids.difference(reply_connection_service_ids)) == 0
+
+    # TODO: implement other checks. examples:
+    # - request service and reply service endpoints match
+    # - request service and reply connection endpoints match
+    # - reply sub-service and reply sub-connection endpoints match
+    # - others?
+    #for json_service,json_connection in zip(json_services, json_connections):
+
+
+def test_request_service_kdisjointpath(
+    pathcomp_client : PathCompClient):  # pylint: disable=redefined-outer-name
+
+    service_uuid = 'DC1-DC2'
+    raw_endpoints = [
+        ('CS1-GW1', '10/1', 'DC1', 10),
+        ('CS1-GW2', '10/1', 'DC1', 20),
+        ('CS2-GW1', '10/1', 'DC2', 10),
+        ('CS2-GW2', '10/1', 'DC2', 20),
+    ]
+    
+    endpoint_ids, constraints = [], [
+        json_constraint_custom('bandwidth[gbps]', 10.0),
+        json_constraint_custom('latency[ms]',     12.0),
+        json_constraint_sla_availability(2, True),
+        json_constraint_custom('diversity', {'end-to-end-diverse': 'all-other-accesses'}),
+    ]
+
+    for device_uuid, endpoint_uuid, region, priority in raw_endpoints:
+        device_id = json_device_id(device_uuid)
+        endpoint_id = json_endpoint_id(device_id, endpoint_uuid)
+        endpoint_ids.append(endpoint_id)
+        constraints.extend([
+            json_constraint_endpoint_location_region(endpoint_id, region),
+            json_constraint_endpoint_priority(endpoint_id, priority),
+        ])
+
+    service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints)
+    request_services = [service]
+
+    pathcomp_request = PathCompRequest(services=request_services)
+    pathcomp_request.k_disjoint_path.num_disjoint = 2   #pylint: disable=no-member
+
+    pathcomp_reply = pathcomp_client.Compute(pathcomp_request)
+
+    pathcomp_reply = grpc_message_to_json(pathcomp_reply)
+    reply_services = pathcomp_reply['services']
+    reply_connections = pathcomp_reply['connections']
+    assert len(request_services) <= len(reply_services)
+    request_service_ids = {
+        '{:s}/{:s}'.format(
+            svc['service_id']['context_id']['context_uuid']['uuid'],
+            svc['service_id']['service_uuid']['uuid']
+        )
+        for svc in request_services
+    }
+    reply_service_ids = {
+        '{:s}/{:s}'.format(
+            svc['service_id']['context_id']['context_uuid']['uuid'],
+            svc['service_id']['service_uuid']['uuid']
+        )
+        for svc in reply_services
+    }
+    # Assert all requested services have a reply
+    # It permits having other services not requested (i.e., sub-services)
+    assert len(request_service_ids.difference(reply_service_ids)) == 0
+
+    reply_connection_service_ids = {
+        '{:s}/{:s}'.format(
+            conn['service_id']['context_id']['context_uuid']['uuid'],
+            conn['service_id']['service_uuid']['uuid']
+        )
+        for conn in reply_connections
+    }
+    # Assert all requested services have a connection associated
+    # It permits having other connections not requested (i.e., connections for sub-services)
+    assert len(request_service_ids.difference(reply_connection_service_ids)) == 0
+
+    # TODO: implement other checks. examples:
+    # - request service and reply service endpoints match
+    # - request service and reply connection endpoints match
+    # - reply sub-service and reply sub-connection endpoints match
+    # - others?
+    #for json_service,json_connection in zip(json_services, json_connections):
+
+
+def test_cleanup_environment(
+    context_client : ContextClient):    # pylint: disable=redefined-outer-name
+
+    for link     in LINKS     : context_client.RemoveLink    (LinkId    (**link    ['link_id'    ]))
+    for device   in DEVICES   : context_client.RemoveDevice  (DeviceId  (**device  ['device_id'  ]))
+    for topology in TOPOLOGIES: context_client.RemoveTopology(TopologyId(**topology['topology_id']))
+    for context  in CONTEXTS  : context_client.RemoveContext (ContextId (**context ['context_id' ]))
diff --git a/src/pathcomp/misc/example-results-kdisjointpaths.json b/src/pathcomp/misc/example-results-kdisjointpaths.json
new file mode 100644
index 0000000000000000000000000000000000000000..9eda25d484e45db53471ea3f655d511cbcc42c18
--- /dev/null
+++ b/src/pathcomp/misc/example-results-kdisjointpaths.json
@@ -0,0 +1,73 @@
+{
+    "connections": [
+        {
+            "connection_id": {"connection_uuid": {"uuid": "d8cb463a-77c4-4149-80fc-32c4842a191d"}},
+            "path_hops_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "DC1-GW"}}, "endpoint_uuid": {"uuid": "int"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC1"}}},
+                {"device_id": {"device_uuid": {"uuid": "DC1-GW"}}, "endpoint_uuid": {"uuid": "eth1"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC1"}}},
+                {"device_id": {"device_uuid": {"uuid": "CS1-GW1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "CS1"}}},
+                {"device_id": {"device_uuid": {"uuid": "TN-R2"}}, "endpoint_uuid": {"uuid": "1"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "TN"}}},
+                {"device_id": {"device_uuid": {"uuid": "TN-R3"}}, "endpoint_uuid": {"uuid": "100"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "TN"}}},
+                {"device_id": {"device_uuid": {"uuid": "CS2-GW1"}}, "endpoint_uuid": {"uuid": "1000"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "CS2"}}},
+                {"device_id": {"device_uuid": {"uuid": "DC2-GW"}}, "endpoint_uuid": {"uuid": "int"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC2"}}}
+            ],
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}},
+                "service_uuid": {"uuid": "svc:DC1-GW/int==DC2-GW/int"}
+            },
+            "sub_service_ids": []
+        },
+        {
+            "connection_id": {"connection_uuid": {"uuid": "9f7c5075-0736-4d2a-8435-b8e8c37fa6ea"}},
+            "path_hops_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "DC1-GW"}}, "endpoint_uuid": {"uuid": "int"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC1"}}},
+                {"device_id": {"device_uuid": {"uuid": "DC1-GW"}}, "endpoint_uuid": {"uuid": "eth2"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC1"}}},
+                {"device_id": {"device_uuid": {"uuid": "CS1-GW2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "CS1"}}},
+                {"device_id": {"device_uuid": {"uuid": "TN-R1"}}, "endpoint_uuid": {"uuid": "3"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "TN"}}},
+                {"device_id": {"device_uuid": {"uuid": "TN-R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "TN"}}},
+                {"device_id": {"device_uuid": {"uuid": "CS2-GW2"}}, "endpoint_uuid": {"uuid": "1000"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "CS2"}}},
+                {"device_id": {"device_uuid": {"uuid": "DC2-GW"}}, "endpoint_uuid": {"uuid": "int"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC2"}}}
+            ],
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}},
+                "service_uuid": {"uuid": "svc:DC1-GW/int==DC2-GW/int"}
+            },
+            "sub_service_ids": []
+        }
+    ],
+    "services": [
+        {
+            "service_id": {
+                "context_id": {"context_uuid": {"uuid": "admin"}},
+                "service_uuid": {"uuid": "svc:DC1-GW/int==DC2-GW/int"}
+            },
+            "service_type": "SERVICETYPE_L3NM",
+            "service_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "DC1-GW"}}, "endpoint_uuid": {"uuid": "int"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC1"}}},
+                {"device_id": {"device_uuid": {"uuid": "DC2-GW"}}, "endpoint_uuid": {"uuid": "int"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "DC2"}}}
+            ],
+            "service_status": {"service_status": "SERVICESTATUS_PLANNED"},
+            "service_constraints": [
+                {"custom": {"constraint_type": "bandwidth[gbps]", "constraint_value": "10.0"}},
+                {"custom": {"constraint_type": "latency[ms]", "constraint_value": "12.0"}}
+            ],
+            "service_config": {"config_rules": []}
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/pathcomp/misc/my_deploy-tests.sh b/src/pathcomp/misc/my_deploy-tests.sh
new file mode 100644
index 0000000000000000000000000000000000000000..d744dd5ab491ac9fc0f9f1c69231105276f4dd5b
--- /dev/null
+++ b/src/pathcomp/misc/my_deploy-tests.sh
@@ -0,0 +1,22 @@
+# Set the URL of your local Docker registry where the images will be uploaded to.
+export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
+
+# Set the list of components, separated by comas, you want to build images for, and deploy.
+# Supported components are:
+#   context device automation policy service compute monitoring webui
+#   interdomain slice pathcomp dlt
+#   dbscanserving opticalattackmitigator opticalcentralizedattackdetector
+#   l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector
+export TFS_COMPONENTS="context device pathcomp service"
+
+# Set the tag you want to use for your images.
+export TFS_IMAGE_TAG="dev"
+
+# Set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE="tfs"
+
+# Set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
+
+# Set the neew Grafana admin password
+export TFS_GRAFANA_PASSWORD="admin123+"
diff --git a/src/pathcomp/misc/test-commands.sh b/src/pathcomp/misc/test-commands.sh
new file mode 100644
index 0000000000000000000000000000000000000000..262cb8ed0d035c0abba0178d08cad6e60e72831f
--- /dev/null
+++ b/src/pathcomp/misc/test-commands.sh
@@ -0,0 +1,33 @@
+#!/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.
+
+docker build -t "pathcomp-frontend:latest" -f ./src/pathcomp/frontend/Dockerfile .
+docker build -t "pathcomp-backend:builder" --target builder -f ./src/pathcomp/backend/Dockerfile .
+docker build -t "pathcomp-backend:latest" -f ./src/pathcomp/backend/Dockerfile .
+docker build -t "pathcomp-backend:gdb" -f ./src/pathcomp/backend/Dockerfile-gdb .
+
+docker network create --driver=bridge --subnet=172.28.0.0/24 --gateway=172.28.0.254 tfbr
+
+docker run --name pathcomp-frontend -d --network=tfbr --ip 172.28.0.1 pathcomp-frontend:latest
+docker run --name pathcomp-backend  -d --network=tfbr --ip 172.28.0.2 pathcomp-backend:latest
+
+docker rm -f pathcomp-frontend pathcomp-backend
+docker network rm tfbr
+
+docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+
+docker exec -i pathcomp bash -c "pytest --log-level=INFO --verbose pathcomp/tests/test_unitary.py"
+
+./scripts/run_tests_locally-pathcomp-frontend.sh
diff --git a/src/pathcomp/service/PathCompServiceServicerImpl.py b/src/pathcomp/service/PathCompServiceServicerImpl.py
deleted file mode 100644
index 239ab6ab5bbe8b6051115a8200cc1f6f304e75b5..0000000000000000000000000000000000000000
--- a/src/pathcomp/service/PathCompServiceServicerImpl.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from typing import List
-import grpc, logging, uuid
-from common.proto.context_pb2 import Connection, Empty, EndPointId
-from common.proto.pathcomp_pb2 import PathCompReply, PathCompRequest
-from common.proto.pathcomp_pb2_grpc import PathCompServiceServicer
-from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
-from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string
-from context.client.ContextClient import ContextClient
-
-LOGGER = logging.getLogger(__name__)
-
-SERVICE_NAME = 'PathComp'
-METHOD_NAMES = ['Compute']
-METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
-
-class PathCompServiceServicerImpl(PathCompServiceServicer):
-    def __init__(self) -> None:
-        LOGGER.debug('Creating Servicer...')
-        LOGGER.debug('Servicer Created')
-
-    @safe_and_metered_rpc_method(METRICS, LOGGER)
-    def Compute(self, request : PathCompRequest, context : grpc.ServicerContext) -> PathCompReply:
-        LOGGER.info('[Compute] begin ; request = {:s}'.format(grpc_message_to_json_string(request)))
-
-        context_client = ContextClient()
-
-        # TODO: consider filtering resources
-
-        grpc_contexts = context_client.ListContexts(Empty())
-        grpc_devices = context_client.ListDevices(Empty())
-        grpc_links = context_client.ListLinks(Empty())
-        for grpc_context in grpc_contexts.contexts:
-            # TODO: add context to request
-            grpc_topologies = context_client.ListTopologies(grpc_context.context_id)
-            for grpc_topology in grpc_topologies.topologies:    #pylint: disable=unused-variable
-                # TODO: add topology to request
-                pass
-        for grpc_device in grpc_devices.devices:                #pylint: disable=unused-variable
-            # TODO: add device to request
-            pass
-        for grpc_link in grpc_links.links:                      #pylint: disable=unused-variable
-            # TODO: add link to request
-            pass
-
-        reply = PathCompReply()
-        # TODO: issue path computation request
-        # TODO: compose reply populating reply.services and reply.connections
-
-        for service in request.services:
-            # TODO: implement support for multi-point services
-            service_endpoint_ids = service.service_endpoint_ids
-            if len(service_endpoint_ids) != 2: raise NotImplementedError('Service must have 2 endpoints')
-            a_endpoint_id, z_endpoint_id = service_endpoint_ids[0], service_endpoint_ids[-1]
-
-            connection_uuid = str(uuid.uuid4())
-            connection_path_hops : List[EndPointId] = []
-            connection_path_hops.extend([
-                grpc_message_to_json(a_endpoint_id),
-                grpc_message_to_json(z_endpoint_id),
-            ])
-            connection = Connection(**{
-                'connection_id': {'connection_uuid': {'uuid': connection_uuid}},
-                'service_id': grpc_message_to_json(service.service_id),
-                'path_hops_endpoint_ids': connection_path_hops,
-                'sub_service_ids': [],
-            })
-            reply.connections.append(connection)    #pylint: disable=no-member
-            reply.services.append(service)          #pylint: disable=no-member
-
-        LOGGER.info('[Compute] end ; reply = {:s}'.format(grpc_message_to_json_string(reply)))
-        return reply
diff --git a/src/pathcomp/tests/test_unitary.py b/src/pathcomp/tests/test_unitary.py
deleted file mode 100644
index 23e574e0e1b512b7a69b69847ef5ef034bd2ca41..0000000000000000000000000000000000000000
--- a/src/pathcomp/tests/test_unitary.py
+++ /dev/null
@@ -1,95 +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
-from common.proto.context_pb2 import Context, ContextId, DeviceId, Link, LinkId, Topology, Device, TopologyId
-from common.proto.pathcomp_pb2 import PathCompRequest
-from common.tools.grpc.Tools import grpc_message_to_json
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from pathcomp.client.PathCompClient import PathCompClient
-from .Objects import CONTEXTS, DEVICES, LINKS, SERVICES, TOPOLOGIES
-from .PrepareTestScenario import ( # pylint: disable=unused-import
-    # be careful, order of symbols is important here!
-    mock_service, pathcomp_service, context_client, device_client, pathcomp_client)
-
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
-
-
-def test_prepare_environment(
-    context_client : ContextClient, # pylint: disable=redefined-outer-name
-    device_client : DeviceClient):  # pylint: disable=redefined-outer-name
-
-    for context  in CONTEXTS  : context_client.SetContext (Context (**context ))
-    for topology in TOPOLOGIES: context_client.SetTopology(Topology(**topology))
-    for device   in DEVICES   : device_client .AddDevice  (Device  (**device  ))
-    for link     in LINKS     : context_client.SetLink    (Link    (**link    ))
-
-
-def test_request_service(
-    pathcomp_client : PathCompClient):  # pylint: disable=redefined-outer-name
-
-    request_services = SERVICES
-    pathcomp_request = PathCompRequest(services=request_services)
-    pathcomp_reply = pathcomp_client.Compute(pathcomp_request)
-    pathcomp_reply = grpc_message_to_json(pathcomp_reply)
-    reply_services = pathcomp_reply['services']
-    reply_connections = pathcomp_reply['connections']
-    assert len(request_services) <= len(reply_services)
-    request_service_ids = {
-        '{:s}/{:s}'.format(
-            svc['service_id']['context_id']['context_uuid']['uuid'],
-            svc['service_id']['service_uuid']['uuid']
-        )
-        for svc in request_services
-    }
-    reply_service_ids = {
-        '{:s}/{:s}'.format(
-            svc['service_id']['context_id']['context_uuid']['uuid'],
-            svc['service_id']['service_uuid']['uuid']
-        )
-        for svc in reply_services
-    }
-    # Assert all requested services have a reply
-    # It permits having other services not requested (i.e., sub-services)
-    assert len(request_service_ids.difference(reply_service_ids)) == 0
-
-    reply_connection_service_ids = {
-        '{:s}/{:s}'.format(
-            conn['service_id']['context_id']['context_uuid']['uuid'],
-            conn['service_id']['service_uuid']['uuid']
-        )
-        for conn in reply_connections
-    }
-    # Assert all requested services have a connection associated
-    # It permits having other connections not requested (i.e., connections for sub-services)
-    assert len(request_service_ids.difference(reply_connection_service_ids)) == 0
-
-    # TODO: implement other checks. examples:
-    # - request service and reply service endpoints match
-    # - request service and reply connection endpoints match
-    # - reply sub-service and reply sub-connection endpoints match
-    # - others?
-    #for json_service,json_connection in zip(json_services, json_connections):
-
-
-def test_cleanup_environment(
-    context_client : ContextClient, # pylint: disable=redefined-outer-name
-    device_client : DeviceClient):  # pylint: disable=redefined-outer-name
-
-    for link     in LINKS     : context_client.RemoveLink    (LinkId    (**link    ['link_id'    ]))
-    for device   in DEVICES   : device_client .DeleteDevice  (DeviceId  (**device  ['device_id'  ]))
-    for topology in TOPOLOGIES: context_client.RemoveTopology(TopologyId(**topology['topology_id']))
-    for context  in CONTEXTS  : context_client.RemoveContext (ContextId (**context ['context_id' ]))
diff --git a/src/policy/README.md b/src/policy/README.md
index 4268343577871cf98b9f701a32cd8a1ff4d9a72a..a5ce13c6e68197be7909472c7ff03862909ec059 100644
--- a/src/policy/README.md
+++ b/src/policy/README.md
@@ -1,19 +1,77 @@
-# Policy Management TeraFlow OS service
+# TeraFlowSDN Policy Management service
 
-The Policy Management service is tested on Ubuntu 20.04. Follow the instructions below to build, test, and run this service on your local environment.
+This repository hosts the TeraFlowSDN Policy Management service.
+Follow the instructions below to build, test, and run this service on your local environment.
 
-## Compile code
+## TeraFlowSDN Policy Management service architecture
 
-`
+The TeraFlowSDN Policy Management service architecture consists of ten (10) interfaces listed below:
+
+Interfaces |
+|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|  1. The `PolicyGateway` interface that implements all the RPC functions that are described in `policy.proto` file. |
+|  2. The `MonitoringGateway` interface that communicates with a `Monitoring` service gRPC client to invoke key RPC functions described in `monitoring.proto` file. |
+|  3. The `ContextGateway` interface that communicates with a `Context` service gRPC client to invoke key RPC functions described in `context.proto` file. |
+|  4. The `ServiceGateway` interface that communicates with a `Service` service gRPC client to invoke key RPC functions described in `service.proto` file. |
+|  5. The `DeviceGateway` interface that communicates with a `Device` service gRPC client to invoke key RPC functions described in `device.proto` file. |
+|  6. The `PolicyService` interface that implements the Policy RPC methods by communicating with a `Monitoring` gRPC client, a `Context` gRPC client, a `Service` gRPC client, and a `Device` gRPC client through the `MonitoringService`, `ContextService`, `ServiceService`, and `DeviceService` interfaces respectively. |
+|  7. The `MonitoringService` interface that implements the `SetKpiAlarm()` and `GetAlarmResponseStream()` methods by communicating with a `Monitoring` gRPC client through the use of the `MonitoringGateway` interface. |
+|  8. The `ContextService` interface that implements the `GetService()`, `GetDevice()`, `GetPolicyRule`, `SetPolicyRule`, and `DeletePolicyRule` methods by communicating with a `Context` gRPC client through the use of the `ContextGateway` interface. |
+|  9. The `ServiceService` interface that implements the `UpdateService()` method by communicating with a `Service` gRPC client through the use of the `ServiceGateway` interface. |
+| 10. The `DeviceService` interface that implements the `ConfigureDevice()` method by communicating with a `Device` gRPC client through the use of the `DeviceGateway` interface. |
+
+## Prerequisites
+
+The TeraFlowSDN Policy Management service is currently tested against Ubuntu 20.04 and Java 11.
+
+To quickly install Java 11 on a Debian-based Linux distro do:
+
+```bash
+sudo apt-get install openjdk-11-jdk -y
+```
+
+Feel free to try more recent Java versions.
+
+## Compile
+
+```bash
 ./mvnw compile
-`
-## Execute unit tests
+```
 
-`
+## Run tests
+
+```bash
 ./mvnw test
-`
+```
+
 ## Run service
 
-`
+```bash
 ./mvnw quarkus:dev
-`
+````
+
+## Clean
+
+```bash
+./mvnw clean
+```
+
+## Deploying on a Kubernetes cluster
+
+To create the K8s manifest file under `target/kubernetes/kubernetes.yml` to be used run
+
+```bash
+./mvnw clean package -DskipUTs -DskipITs
+```
+
+To deploy the application in a K8s cluster run
+
+```bash
+kubectl apply -f "manifests/policyservice.yaml"
+```
+
+## Maintainers
+
+This TeraFlowSDN service is implemented by [UBITECH](https://www.ubitech.eu).
+
+Feel free to contact Georgios Katsikas (gkatsikas at ubitech dot eu) in case you have questions.
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyRuleConditionFieldsGetter.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyRuleConditionFieldsGetter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ba1c1535283f292b4dbe0d5b7bffe9bf1149156
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyRuleConditionFieldsGetter.java
@@ -0,0 +1,47 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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 eu.teraflow.policy.model.NumericalOperator;
+import eu.teraflow.policy.model.PolicyRuleCondition;
+import eu.teraflow.policy.monitoring.model.KpiValue;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.inject.Singleton;
+
+@Singleton
+public class PolicyRuleConditionFieldsGetter {
+
+    public List<String> getKpiIds(List<PolicyRuleCondition> policyRuleConditions) {
+        return policyRuleConditions.stream()
+                .map(PolicyRuleCondition::getKpiId)
+                .collect(Collectors.toList());
+    }
+
+    public List<KpiValue> getKpiValues(List<PolicyRuleCondition> policyRuleConditions) {
+        return policyRuleConditions.stream()
+                .map(PolicyRuleCondition::getKpiValue)
+                .collect(Collectors.toList());
+    }
+
+    public List<NumericalOperator> getNumericalOperators(
+            List<PolicyRuleCondition> policyRuleConditions) {
+        return policyRuleConditions.stream()
+                .map(PolicyRuleCondition::getNumericalOperator)
+                .collect(Collectors.toList());
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyRuleConditionValidator.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyRuleConditionValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ca242dbbb860354219c4c85bb367563672572ef
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyRuleConditionValidator.java
@@ -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.
+*/
+
+package eu.teraflow.policy;
+
+import eu.teraflow.policy.context.ContextService;
+import eu.teraflow.policy.context.model.Device;
+import eu.teraflow.policy.context.model.Service;
+import eu.teraflow.policy.context.model.ServiceId;
+import io.smallrye.mutiny.Uni;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import org.jboss.logging.Logger;
+
+@ApplicationScoped
+public class PolicyRuleConditionValidator {
+
+    private static final Logger LOGGER = Logger.getLogger(PolicyRuleConditionValidator.class);
+    private static final String INVALID_MESSAGE = "%s is invalid.";
+    private static final String VALID_MESSAGE = "%s is valid.";
+
+    private final ContextService contextService;
+
+    @Inject
+    public PolicyRuleConditionValidator(ContextService contextService) {
+        this.contextService = contextService;
+    }
+
+    public Uni<Boolean> validateDeviceId(String deviceId) {
+        final var isDeviceIdValid = isDeviceIdValid(deviceId);
+
+        isDeviceIdValid
+                .subscribe()
+                .with(
+                        deviceIdIdBooleanValue -> {
+                            if (Boolean.FALSE.equals(deviceIdIdBooleanValue)) {
+                                LOGGER.errorf(INVALID_MESSAGE, deviceId);
+                            }
+                            LOGGER.infof(VALID_MESSAGE, deviceId);
+                        });
+
+        return isDeviceIdValid;
+    }
+
+    public Uni<Boolean> validateServiceId(ServiceId serviceId) {
+        final var isServiceIdValid = isServiceIdValid(serviceId);
+
+        isServiceIdValid
+                .subscribe()
+                .with(
+                        serviceIdBooleanValue -> {
+                            if (Boolean.FALSE.equals(serviceIdBooleanValue)) {
+                                LOGGER.errorf(INVALID_MESSAGE, serviceId);
+                            }
+                        });
+
+        return isServiceIdValid;
+    }
+
+    private Uni<Boolean> isDeviceIdValid(String deviceId) {
+        return contextService
+                .getDevice(deviceId)
+                .onItem()
+                .transform(device -> checkIfDeviceIdExists(device, deviceId));
+    }
+
+    private boolean checkIfDeviceIdExists(Device device, String deviceId) {
+        final var deviceDeviceId = device.getDeviceId();
+
+        return deviceDeviceId.equals(deviceId);
+    }
+
+    private Uni<Boolean> isServiceIdValid(ServiceId serviceId) {
+        return contextService
+                .getService(serviceId)
+                .onItem()
+                .transform(service -> checkIfServiceIdExists(service, serviceId));
+    }
+
+    private boolean checkIfServiceIdExists(Service service, ServiceId serviceId) {
+        final var serviceServiceIdServiceId = service.getServiceId();
+        final var serviceServiceIdContextId = serviceServiceIdServiceId.getContextId();
+        final var serviceServiceIdId = serviceServiceIdServiceId.getId();
+
+        return serviceServiceIdContextId.equals(serviceId.getContextId())
+                && serviceServiceIdId.equals(serviceId.getId());
+    }
+}
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 66994625ddb2eb6a52e1d0a99acd52a2cd1cc2f2..7cb3935005c6762ee725fd474a2b03cc373f0194 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
@@ -17,6 +17,7 @@
 package eu.teraflow.policy;
 
 import eu.teraflow.policy.context.ContextService;
+import eu.teraflow.policy.model.PolicyRuleBasic;
 import eu.teraflow.policy.model.PolicyRuleDevice;
 import eu.teraflow.policy.model.PolicyRuleService;
 import eu.teraflow.policy.model.PolicyRuleState;
@@ -24,6 +25,8 @@ import eu.teraflow.policy.model.RuleState;
 import eu.teraflow.policy.monitoring.MonitoringService;
 import eu.teraflow.policy.service.ServiceService;
 import io.smallrye.mutiny.Uni;
+import java.util.ArrayList;
+import java.util.List;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import org.jboss.logging.Logger;
@@ -32,23 +35,88 @@ import org.jboss.logging.Logger;
 public class PolicyServiceImpl implements PolicyService {
 
     private static final Logger LOGGER = Logger.getLogger(PolicyServiceImpl.class);
+    private static final String INVALID_MESSAGE = "%s is invalid.";
+    private static final String VALID_MESSAGE = "%s is valid.";
+    private static final PolicyRuleState INSERTED_POLICYRULE_STATE =
+            new PolicyRuleState(RuleState.POLICY_INSERTED);
+    private static final PolicyRuleState VALIDATED_POLICYRULE_STATE =
+            new PolicyRuleState(RuleState.POLICY_VALIDATED);
+    private static final PolicyRuleState FAILED_POLICYRULE_STATE =
+            new PolicyRuleState(RuleState.POLICY_FAILED);
 
     private final ContextService contextService;
     private final MonitoringService monitoringService;
     private final ServiceService serviceService;
+    private final PolicyRuleConditionValidator policyRuleConditionValidator;
+    private final PolicyRuleConditionFieldsGetter policyRuleConditionFieldsGetter;
 
     @Inject
     public PolicyServiceImpl(
             ContextService contextService,
             MonitoringService monitoringService,
-            ServiceService serviceService) {
+            ServiceService serviceService,
+            PolicyRuleConditionValidator policyRuleConditionValidator,
+            PolicyRuleConditionFieldsGetter policyRuleConditionFieldsGetter) {
         this.contextService = contextService;
         this.monitoringService = monitoringService;
         this.serviceService = serviceService;
+        this.policyRuleConditionValidator = policyRuleConditionValidator;
+        this.policyRuleConditionFieldsGetter = policyRuleConditionFieldsGetter;
     }
 
     @Override
     public Uni<PolicyRuleState> addPolicyService(PolicyRuleService policyRuleService) {
+        LOGGER.infof("Received %s", policyRuleService);
+
+        final var serviceId = policyRuleService.getServiceId();
+        final var deviceIds = policyRuleService.getDeviceIds();
+        final var policyRuleBasic = policyRuleService.getPolicyRuleBasic();
+
+        final var policyRuleConditions = policyRuleBasic.getPolicyRuleConditions();
+        final var kpiIds = policyRuleConditionFieldsGetter.getKpiIds(policyRuleConditions);
+        final var kpiValues = policyRuleConditionFieldsGetter.getKpiValues(policyRuleConditions);
+        final var numericalOperators =
+                policyRuleConditionFieldsGetter.getNumericalOperators(policyRuleConditions);
+
+        final var isServiceIdValid = policyRuleConditionValidator.validateServiceId(serviceId);
+
+        logAndSetPolicyRuleState(INSERTED_POLICYRULE_STATE, policyRuleBasic);
+        contextService.setPolicyRule(policyRuleBasic);
+
+        // VALIDATION PHASE
+        isServiceIdValid
+                .subscribe()
+                .with(
+                        serviceIdBooleanValue -> {
+                            if (Boolean.FALSE.equals(serviceIdBooleanValue)) {
+                                LOGGER.errorf(INVALID_MESSAGE, serviceId);
+                                final var invalidDeviceIds = returnInvalidDeviceIds(deviceIds);
+
+                                if (invalidDeviceIds.isEmpty()) {
+                                    LOGGER.info("All Device Ids are valid.");
+                                }
+
+                                logAndSetPolicyRuleState(FAILED_POLICYRULE_STATE, policyRuleBasic);
+                            } else {
+                                LOGGER.infof(VALID_MESSAGE, serviceId);
+
+                                final var invalidDeviceIds = returnInvalidDeviceIds(deviceIds);
+
+                                if (!invalidDeviceIds.isEmpty()) {
+                                    logAndSetPolicyRuleState(FAILED_POLICYRULE_STATE, policyRuleBasic);
+                                    contextService.setPolicyRule(policyRuleBasic);
+                                } else {
+                                    LOGGER.infof("All deviceIds are valid");
+                                }
+
+                                logAndSetPolicyRuleState(VALIDATED_POLICYRULE_STATE, policyRuleBasic);
+                            }
+
+                            contextService.setPolicyRule(policyRuleBasic);
+                        });
+
+        // PROVISION PHASE
+
         final var policyRuleState = new PolicyRuleState(RuleState.POLICY_VALIDATED);
 
         return Uni.createFrom().item(policyRuleState);
@@ -56,8 +124,80 @@ public class PolicyServiceImpl implements PolicyService {
 
     @Override
     public Uni<PolicyRuleState> addPolicyDevice(PolicyRuleDevice policyRuleDevice) {
+        LOGGER.infof("Received %s", policyRuleDevice);
+
+        final var policyRuleBasic = policyRuleDevice.getPolicyRuleBasic();
+        final var deviceIds = policyRuleDevice.getDeviceIds();
+
+        final var policyRuleConditions = policyRuleBasic.getPolicyRuleConditions();
+        final var kpiIds = policyRuleConditionFieldsGetter.getKpiIds(policyRuleConditions);
+        final var kpiValues = policyRuleConditionFieldsGetter.getKpiValues(policyRuleConditions);
+        final var numericalOperators =
+                policyRuleConditionFieldsGetter.getNumericalOperators(policyRuleConditions);
+
+        logAndSetPolicyRuleState(INSERTED_POLICYRULE_STATE, policyRuleBasic);
+        contextService.setPolicyRule(policyRuleBasic);
+
+        // VALIDATION PHASE
+        final var invalidDeviceIds = returnInvalidDeviceIds(deviceIds);
+
+        if (!invalidDeviceIds.isEmpty()) {
+            logAndSetPolicyRuleState(FAILED_POLICYRULE_STATE, policyRuleBasic);
+        } else {
+            LOGGER.infof("All deviceIds are valid");
+            logAndSetPolicyRuleState(VALIDATED_POLICYRULE_STATE, policyRuleBasic);
+        }
+        contextService.setPolicyRule(policyRuleBasic);
+
+        // PROVISION PHASE
+
         final var policyRuleState = new PolicyRuleState(RuleState.POLICY_VALIDATED);
 
         return Uni.createFrom().item(policyRuleState);
     }
+
+    private List<String> returnInvalidDeviceIds(List<String> deviceIds) {
+        var invalidDeviceIds = new ArrayList<String>();
+
+        if (!deviceIds.isEmpty()) {
+
+            for (String deviceId : deviceIds) {
+                final var validatedDeviceId = policyRuleConditionValidator.validateDeviceId(deviceId);
+
+                validatedDeviceId
+                        .subscribe()
+                        .with(
+                                deviceIdBoolean -> {
+                                    if (Boolean.FALSE.equals(deviceIdBoolean)) {
+                                        invalidDeviceIds.add(deviceId);
+                                    }
+                                });
+            }
+
+        } else {
+            LOGGER.warnf("No deviceIds found");
+        }
+
+        return invalidDeviceIds;
+    }
+
+    private void logAndSetPolicyRuleState(
+            PolicyRuleState policyRuleState, PolicyRuleBasic policyRuleBasic) {
+        final var POLICY_RULE_STATE_MESSAGE = "Setting Policy Rule state to [%s]";
+
+        if (policyRuleState.getRuleState() == RuleState.POLICY_INSERTED) {
+            LOGGER.infof(POLICY_RULE_STATE_MESSAGE, RuleState.POLICY_INSERTED.toString());
+            policyRuleBasic.setPolicyRuleState(policyRuleState);
+        }
+
+        if (policyRuleState.getRuleState() == RuleState.POLICY_VALIDATED) {
+            LOGGER.infof(POLICY_RULE_STATE_MESSAGE, RuleState.POLICY_VALIDATED.toString());
+            policyRuleBasic.setPolicyRuleState(policyRuleState);
+        }
+
+        if (policyRuleState.getRuleState() == RuleState.POLICY_FAILED) {
+            LOGGER.errorf(POLICY_RULE_STATE_MESSAGE, RuleState.POLICY_FAILED.toString());
+            policyRuleBasic.setPolicyRuleState(policyRuleState);
+        }
+    }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java
index ede45d0c2dd0c2944be8f31db845e6c05784caca..b7b1913b0a80298646bd35ac9b8eaf6eec0daa96 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/Serializer.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/Serializer.java
@@ -88,6 +88,7 @@ import eu.teraflow.policy.model.PolicyRuleState;
 import eu.teraflow.policy.model.RuleState;
 import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
 import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.AlarmSubscription;
 import eu.teraflow.policy.monitoring.model.BooleanKpiValue;
 import eu.teraflow.policy.monitoring.model.FloatKpiValue;
 import eu.teraflow.policy.monitoring.model.IntegerKpiValue;
@@ -1472,12 +1473,12 @@ public class Serializer {
     public Monitoring.KpiValue serializeIntegerKpiValue(KpiValue<Integer> kpiValue) {
         final var builder = Monitoring.KpiValue.newBuilder();
 
-        return builder.setIntVal(kpiValue.getValue()).build();
+        return builder.setInt32Val(kpiValue.getValue()).build();
     }
 
     public int deserializeIntegerKpiValue(Monitoring.KpiValue serializedKpiValue) {
 
-        return serializedKpiValue.getIntVal();
+        return serializedKpiValue.getInt32Val();
     }
 
     public Monitoring.KpiValue serialize(KpiValue<?> kpiValue) {
@@ -1485,7 +1486,7 @@ public class Serializer {
 
         if (kpiValue.getValue() instanceof Integer) {
             final var serializedIntegerKpiValue = serializeIntegerKpiValue((KpiValue<Integer>) kpiValue);
-            builder.setIntVal(serializedIntegerKpiValue.getIntVal());
+            builder.setInt32Val(serializedIntegerKpiValue.getInt32Val());
         }
         if (kpiValue.getValue() instanceof Float) {
             final var serializedFloatKpiValue = serializeFloatKpiValue((KpiValue<Float>) kpiValue);
@@ -1508,7 +1509,7 @@ public class Serializer {
         final var typeOfKpiValue = serializedKpiValue.getValueCase();
 
         switch (typeOfKpiValue) {
-            case INTVAL:
+            case INT32VAL:
                 final var intValue = deserializeIntegerKpiValue(serializedKpiValue);
                 return new IntegerKpiValue(intValue);
             case BOOLVAL:
@@ -1569,37 +1570,47 @@ public class Serializer {
     public Monitoring.AlarmDescriptor serialize(AlarmDescriptor alarmDescriptor) {
         final var builder = Monitoring.AlarmDescriptor.newBuilder();
 
+        final var alarmId = alarmDescriptor.getAlarmId();
         final var alarmDescription = alarmDescriptor.getAlarmDescription();
         final var name = alarmDescriptor.getName();
-        final var kpiId = alarmDescriptor.getKpiId();
-        final var kpiValueRange = alarmDescriptor.getKpiValueRange();
+        final var kpiIds = alarmDescriptor.getKpiIds();
+        final var kpiValueRanges = alarmDescriptor.getKpiValueRanges();
         final var timestamp = alarmDescriptor.getTimestamp();
 
-        final var serializedKpiIdUuid = serializeUuid(kpiId);
-        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
-        final var serializedKpiValueRange = serialize(kpiValueRange);
+        final var serializedAlarmId = serializeAlarmId(alarmId);
+        final var serializedKpiIds =
+                kpiIds.stream().map(this::serializeKpiId).collect(Collectors.toList());
+        final var serializedKpiValueRanges =
+                kpiValueRanges.stream().map(this::serialize).collect(Collectors.toList());
+        final var serializedTimestamp = serialize(timestamp);
 
+        builder.setAlarmId(serializedAlarmId);
         builder.setAlarmDescription(alarmDescription);
         builder.setName(name);
-        builder.setKpiId(serializedKpiId);
-        builder.setKpiValueRange(serializedKpiValueRange);
-        builder.setTimestamp(timestamp);
+        builder.addAllKpiId(serializedKpiIds);
+        builder.addAllKpiValueRange(serializedKpiValueRanges);
+        builder.setTimestamp(serializedTimestamp);
 
         return builder.build();
     }
 
     public AlarmDescriptor deserialize(Monitoring.AlarmDescriptor serializedAlarmDescriptor) {
 
+        final var serializedAlarmId = serializedAlarmDescriptor.getAlarmId();
         final var alarmDescription = serializedAlarmDescriptor.getAlarmDescription();
         final var name = serializedAlarmDescriptor.getName();
-        final var serializedKpiId = serializedAlarmDescriptor.getKpiId();
-        final var serializedKpiValueRange = serializedAlarmDescriptor.getKpiValueRange();
-        final var timestamp = serializedAlarmDescriptor.getTimestamp();
+        final var serializedKpiIds = serializedAlarmDescriptor.getKpiIdList();
+        final var serializedKpiValueRanges = serializedAlarmDescriptor.getKpiValueRangeList();
+        final var serializeTimestamp = serializedAlarmDescriptor.getTimestamp();
 
-        final var kpiId = deserialize(serializedKpiId);
-        final var kpiValueRange = deserialize(serializedKpiValueRange);
+        final var alarmId = deserialize(serializedAlarmId);
+        final var kpiIds =
+                serializedKpiIds.stream().map(this::deserialize).collect(Collectors.toList());
+        final var kpiValueRanges =
+                serializedKpiValueRanges.stream().map(this::deserialize).collect(Collectors.toList());
+        final var timestamp = deserialize(serializeTimestamp);
 
-        return new AlarmDescriptor(alarmDescription, name, kpiId, kpiValueRange, timestamp);
+        return new AlarmDescriptor(alarmId, alarmDescription, name, kpiIds, kpiValueRanges, timestamp);
     }
 
     public Monitoring.AlarmResponse serialize(AlarmResponse alarmResponse) {
@@ -1635,34 +1646,44 @@ public class Serializer {
     public Monitoring.SubsDescriptor serialize(SubsDescriptor subDescriptor) {
         final var builder = Monitoring.SubsDescriptor.newBuilder();
 
+        final var subscriptionId = subDescriptor.getSubscriptionId();
         final var kpiId = subDescriptor.getKpiId();
         final var samplingDurationS = subDescriptor.getSamplingDurationS();
         final var samplingIntervalS = subDescriptor.getSamplingIntervalS();
-        final var startDate = subDescriptor.getStartDate();
-        final var endDate = subDescriptor.getEndDate();
+        final var startTimestamp = subDescriptor.getStartTimestamp();
+        final var endTimestamp = subDescriptor.getEndTimestamp();
 
+        final var serializedSubscriptionIdUuid = serializeSubscriptionIdId(subscriptionId);
         final var serializedKpiIdUuid = serializeUuid(kpiId);
         final var serializedKpiId = Monitoring.KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedStartTimestamp = serialize(startTimestamp);
+        final var serializedEndTimestamp = serialize(endTimestamp);
 
+        builder.setSubsId(serializedSubscriptionIdUuid);
         builder.setKpiId(serializedKpiId);
         builder.setSamplingDurationS(samplingDurationS);
         builder.setSamplingIntervalS(samplingIntervalS);
-        builder.setStartDate(startDate);
-        builder.setEndDate(endDate);
+        builder.setStartTimestamp(serializedStartTimestamp);
+        builder.setEndTimestamp(serializedEndTimestamp);
 
         return builder.build();
     }
 
     public SubsDescriptor deserialize(Monitoring.SubsDescriptor serializedSubDescriptor) {
+        final var serializedSubscriptionId = serializedSubDescriptor.getSubsId();
         final var serializedKpiId = serializedSubDescriptor.getKpiId();
         final var samplingDurationS = serializedSubDescriptor.getSamplingDurationS();
         final var samplingIntervalS = serializedSubDescriptor.getSamplingIntervalS();
-        final var startDate = serializedSubDescriptor.getStartDate();
-        final var endDate = serializedSubDescriptor.getEndDate();
+        final var serializedStartTimestamp = serializedSubDescriptor.getStartTimestamp();
+        final var serializedEndTimestamp = serializedSubDescriptor.getEndTimestamp();
 
+        final var subscriptionId = deserialize(serializedSubscriptionId);
         final var kpiId = deserialize(serializedKpiId);
+        final var startTimestamp = deserialize(serializedStartTimestamp);
+        final var endTimestamp = deserialize(serializedEndTimestamp);
 
-        return new SubsDescriptor(kpiId, samplingDurationS, samplingIntervalS, startDate, endDate);
+        return new SubsDescriptor(
+                subscriptionId, kpiId, samplingDurationS, samplingIntervalS, startTimestamp, endTimestamp);
     }
 
     public SubscriptionID serializeSubscriptionIdId(String subscriptionId) {
@@ -1930,10 +1951,11 @@ public class Serializer {
         final var kpiValue = kpi.getKpiValue();
 
         final var serializedKpiId = serializeKpiId(kpiId);
+        final var serializedTimestamp = serialize(timestamp);
         final var serializedKpiValue = serialize(kpiValue);
 
         builder.setKpiId(serializedKpiId);
-        builder.setTimestamp(timestamp);
+        builder.setTimestamp(serializedTimestamp);
         builder.setKpiValue(serializedKpiValue);
 
         return builder.build();
@@ -1942,10 +1964,11 @@ public class Serializer {
     public Kpi deserialize(Monitoring.Kpi serializedKpi) {
 
         final var serializedKpiId = serializedKpi.getKpiId();
-        final var timestamp = serializedKpi.getTimestamp();
+        final var serializedTimestamp = serializedKpi.getTimestamp();
         final var serializedKpiValue = serializedKpi.getKpiValue();
 
         final var kpiId = deserialize(serializedKpiId);
+        final var timestamp = deserialize(serializedTimestamp);
         final var kpiValue = deserialize(serializedKpiValue);
 
         return new Kpi(kpiId, timestamp, kpiValue);
@@ -2153,6 +2176,33 @@ public class Serializer {
         return new EndPoint.EndPointBuilder(endPointId, endPointType, kpiSampleTypes).build();
     }
 
+    public Monitoring.AlarmSubscription serialize(AlarmSubscription alarmSubscription) {
+        final var builder = Monitoring.AlarmSubscription.newBuilder();
+
+        final var alarmId = alarmSubscription.getAlarmId();
+        final var subscriptionTimeoutS = alarmSubscription.getSubscriptionTimeoutS();
+        final var subscriptionFrequencyMs = alarmSubscription.getSubscriptionFrequencyMs();
+
+        final var serializedAlarmId = serializeAlarmId(alarmId);
+
+        builder.setAlarmID(serializedAlarmId);
+        builder.setSubscriptionTimeoutS(subscriptionTimeoutS);
+        builder.setSubscriptionFrequencyMs(subscriptionFrequencyMs);
+
+        return builder.build();
+    }
+
+    public AlarmSubscription deserialize(Monitoring.AlarmSubscription serializedAlarmSubscription) {
+
+        final var serializedAlarmId = serializedAlarmSubscription.getAlarmID();
+        final var subscriptionTimeoutS = serializedAlarmSubscription.getSubscriptionTimeoutS();
+        final var subscriptionFrequencyMs = serializedAlarmSubscription.getSubscriptionFrequencyMs();
+
+        final var alarmId = deserialize(serializedAlarmId);
+
+        return new AlarmSubscription(alarmId, subscriptionTimeoutS, subscriptionFrequencyMs);
+    }
+
     public ContextOuterClass.Device serialize(Device device) {
         final var builder = ContextOuterClass.Device.newBuilder();
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleBasic.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleBasic.java
index b32d3cf3008611ea67aee53f5234f1e45b98be8c..6f50dfca8cb43a3d825137e31a83c63855b5aebd 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleBasic.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleBasic.java
@@ -25,7 +25,7 @@ import java.util.List;
 public class PolicyRuleBasic {
 
     private final String policyRuleId;
-    private final PolicyRuleState policyRuleState;
+    private PolicyRuleState policyRuleState;
     private final int priority;
     private final List<PolicyRuleCondition> policyRuleConditions;
     private final BooleanOperator booleanOperator;
@@ -64,6 +64,10 @@ public class PolicyRuleBasic {
         return policyRuleState;
     }
 
+    public void setPolicyRuleState(PolicyRuleState state) {
+        this.policyRuleState = state;
+    }
+
     public int getPriority() {
         return priority;
     }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGateway.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGateway.java
index 4b9849a7649894cb4109fb458dac611e834bd916..925c22aa62588de6d9a364a647f65e74f6b01740 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGateway.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGateway.java
@@ -16,9 +16,9 @@
 
 package eu.teraflow.policy.monitoring;
 
-import eu.teraflow.policy.context.model.Empty;
 import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
 import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.AlarmSubscription;
 import eu.teraflow.policy.monitoring.model.Kpi;
 import eu.teraflow.policy.monitoring.model.KpiDescriptor;
 import eu.teraflow.policy.monitoring.model.SubsDescriptor;
@@ -28,21 +28,17 @@ import java.util.List;
 
 public interface MonitoringGateway {
 
-    Uni<String> createKpi(KpiDescriptor kpiDescriptor);
+    Uni<String> setKpi(KpiDescriptor kpiDescriptor);
 
     Uni<KpiDescriptor> getKpiDescriptor(String kpiId);
 
-    Multi<List<Kpi>> subscribeKpi(SubsDescriptor subsDescriptor);
+    Multi<List<Kpi>> setKpiSubscription(SubsDescriptor subsDescriptor);
 
     Uni<SubsDescriptor> getSubsDescriptor(String subscriptionId);
 
-    Uni<Empty> editKpiSubscription(SubsDescriptor subsDescriptor);
-
-    Uni<String> createKpiAlarm(AlarmDescriptor alarmDescriptor);
-
-    Uni<Empty> editKpiAlarm(AlarmDescriptor alarmDescriptor);
+    Uni<String> setKpiAlarm(AlarmDescriptor alarmDescriptor);
 
     Uni<AlarmDescriptor> getAlarmDescriptor(String alarmId);
 
-    Multi<AlarmResponse> getAlarmResponseStream(String alarmId);
+    Multi<AlarmResponse> getAlarmResponseStream(AlarmSubscription alarmSubscription);
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGatewayImpl.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGatewayImpl.java
index e0b4e088a9e23387f56d956bed5f6e104a68ea56..e500b78c508f8e5b22d78c98f7960ff8ca9e7c13 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGatewayImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringGatewayImpl.java
@@ -17,9 +17,9 @@
 package eu.teraflow.policy.monitoring;
 
 import eu.teraflow.policy.Serializer;
-import eu.teraflow.policy.context.model.Empty;
 import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
 import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.AlarmSubscription;
 import eu.teraflow.policy.monitoring.model.Kpi;
 import eu.teraflow.policy.monitoring.model.KpiDescriptor;
 import eu.teraflow.policy.monitoring.model.SubsDescriptor;
@@ -45,11 +45,11 @@ public class MonitoringGatewayImpl implements MonitoringGateway {
     }
 
     @Override
-    public Uni<String> createKpi(KpiDescriptor kpiDescriptor) {
+    public Uni<String> setKpi(KpiDescriptor kpiDescriptor) {
         final var serializedKpiDescriptor = serializer.serialize(kpiDescriptor);
 
         return streamingDelegateMonitoring
-                .createKpi(serializedKpiDescriptor)
+                .setKpi(serializedKpiDescriptor)
                 .onItem()
                 .transform(serializer::deserialize);
     }
@@ -65,11 +65,11 @@ public class MonitoringGatewayImpl implements MonitoringGateway {
     }
 
     @Override
-    public Multi<List<Kpi>> subscribeKpi(SubsDescriptor subsDescriptor) {
+    public Multi<List<Kpi>> setKpiSubscription(SubsDescriptor subsDescriptor) {
         final var serializedSubsDescriptor = serializer.serialize(subsDescriptor);
 
         return streamingDelegateMonitoring
-                .subscribeKpi(serializedSubsDescriptor)
+                .setKpiSubscription(serializedSubsDescriptor)
                 .onItem()
                 .transform(kpiList -> serializer.deserialize(kpiList.getKpiListList()));
     }
@@ -85,35 +85,15 @@ public class MonitoringGatewayImpl implements MonitoringGateway {
     }
 
     @Override
-    public Uni<Empty> editKpiSubscription(SubsDescriptor subsDescriptor) {
-        final var serializedSubsDescriptor = serializer.serialize(subsDescriptor);
-
-        return streamingDelegateMonitoring
-                .editKpiSubscription(serializedSubsDescriptor)
-                .onItem()
-                .transform(serializer::deserializeEmpty);
-    }
-
-    @Override
-    public Uni<String> createKpiAlarm(AlarmDescriptor alarmDescriptor) {
+    public Uni<String> setKpiAlarm(AlarmDescriptor alarmDescriptor) {
         final var serializedAlarmDescriptor = serializer.serialize(alarmDescriptor);
 
         return streamingDelegateMonitoring
-                .createKpiAlarm(serializedAlarmDescriptor)
+                .setKpiAlarm(serializedAlarmDescriptor)
                 .onItem()
                 .transform(serializer::deserialize);
     }
 
-    @Override
-    public Uni<Empty> editKpiAlarm(AlarmDescriptor alarmDescriptor) {
-        final var serializedAlarmDescriptor = serializer.serialize(alarmDescriptor);
-
-        return streamingDelegateMonitoring
-                .editKpiAlarm(serializedAlarmDescriptor)
-                .onItem()
-                .transform(serializer::deserializeEmpty);
-    }
-
     @Override
     public Uni<AlarmDescriptor> getAlarmDescriptor(String alarmId) {
         final var serializedAlarmId = serializer.serializeAlarmId(alarmId);
@@ -125,11 +105,11 @@ public class MonitoringGatewayImpl implements MonitoringGateway {
     }
 
     @Override
-    public Multi<AlarmResponse> getAlarmResponseStream(String alarmId) {
-        final var serializedAlarmId = serializer.serializeAlarmId(alarmId);
+    public Multi<AlarmResponse> getAlarmResponseStream(AlarmSubscription alarmSubscription) {
+        final var serializedAlarmSubscription = serializer.serialize(alarmSubscription);
 
         return streamingDelegateMonitoring
-                .getAlarmResponseStream(serializedAlarmId)
+                .getAlarmResponseStream(serializedAlarmSubscription)
                 .onItem()
                 .transform(serializer::deserialize);
     }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringService.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringService.java
index 276a9d3632655cf684ae4dff0469d477ff15a88e..5022833ceed4896b1458a077125b4f822127cb6c 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringService.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringService.java
@@ -16,9 +16,9 @@
 
 package eu.teraflow.policy.monitoring;
 
-import eu.teraflow.policy.context.model.Empty;
 import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
 import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.AlarmSubscription;
 import eu.teraflow.policy.monitoring.model.Kpi;
 import eu.teraflow.policy.monitoring.model.KpiDescriptor;
 import eu.teraflow.policy.monitoring.model.SubsDescriptor;
@@ -28,21 +28,17 @@ import java.util.List;
 
 public interface MonitoringService {
 
-    Uni<String> createKpi(KpiDescriptor kpiDescriptor);
+    Uni<String> setKpi(KpiDescriptor kpiDescriptor);
 
     Uni<KpiDescriptor> getKpiDescriptor(String kpiId);
 
-    Multi<List<Kpi>> subscribeKpi(SubsDescriptor subsDescriptor);
+    Multi<List<Kpi>> setKpiSubscription(SubsDescriptor subsDescriptor);
 
     Uni<SubsDescriptor> getSubsDescriptor(String subscriptionId);
 
-    Uni<Empty> editKpiSubscription(SubsDescriptor subsDescriptor);
-
-    Uni<String> createKpiAlarm(AlarmDescriptor alarmDescriptor);
-
-    Uni<Empty> editKpiAlarm(AlarmDescriptor alarmDescriptor);
+    Uni<String> setKpiAlarm(AlarmDescriptor alarmDescriptor);
 
     Uni<AlarmDescriptor> getAlarmDescriptor(String alarmId);
 
-    Multi<AlarmResponse> getAlarmResponseStream(String alarmId);
+    Multi<AlarmResponse> getAlarmResponseStream(AlarmSubscription alarmSubscription);
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringServiceImpl.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringServiceImpl.java
index e1e79af757b9866360040b785fd41dd1f0c70cd4..5cec6e989749ade8083f01be341d0a0fd0982c98 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringServiceImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/MonitoringServiceImpl.java
@@ -16,9 +16,9 @@
 
 package eu.teraflow.policy.monitoring;
 
-import eu.teraflow.policy.context.model.Empty;
 import eu.teraflow.policy.monitoring.model.AlarmDescriptor;
 import eu.teraflow.policy.monitoring.model.AlarmResponse;
+import eu.teraflow.policy.monitoring.model.AlarmSubscription;
 import eu.teraflow.policy.monitoring.model.Kpi;
 import eu.teraflow.policy.monitoring.model.KpiDescriptor;
 import eu.teraflow.policy.monitoring.model.SubsDescriptor;
@@ -39,8 +39,8 @@ public class MonitoringServiceImpl implements MonitoringService {
     }
 
     @Override
-    public Uni<String> createKpi(KpiDescriptor kpiDescriptor) {
-        return monitoringGateway.createKpi(kpiDescriptor);
+    public Uni<String> setKpi(KpiDescriptor kpiDescriptor) {
+        return monitoringGateway.setKpi(kpiDescriptor);
     }
 
     @Override
@@ -49,8 +49,8 @@ public class MonitoringServiceImpl implements MonitoringService {
     }
 
     @Override
-    public Multi<List<Kpi>> subscribeKpi(SubsDescriptor subsDescriptor) {
-        return monitoringGateway.subscribeKpi(subsDescriptor);
+    public Multi<List<Kpi>> setKpiSubscription(SubsDescriptor subsDescriptor) {
+        return monitoringGateway.setKpiSubscription(subsDescriptor);
     }
 
     @Override
@@ -59,18 +59,8 @@ public class MonitoringServiceImpl implements MonitoringService {
     }
 
     @Override
-    public Uni<Empty> editKpiSubscription(SubsDescriptor subsDescriptor) {
-        return monitoringGateway.editKpiSubscription(subsDescriptor);
-    }
-
-    @Override
-    public Uni<String> createKpiAlarm(AlarmDescriptor alarmDescriptor) {
-        return monitoringGateway.createKpiAlarm(alarmDescriptor);
-    }
-
-    @Override
-    public Uni<Empty> editKpiAlarm(AlarmDescriptor alarmDescriptor) {
-        return monitoringGateway.editKpiAlarm(alarmDescriptor);
+    public Uni<String> setKpiAlarm(AlarmDescriptor alarmDescriptor) {
+        return monitoringGateway.setKpiAlarm(alarmDescriptor);
     }
 
     @Override
@@ -79,7 +69,7 @@ public class MonitoringServiceImpl implements MonitoringService {
     }
 
     @Override
-    public Multi<AlarmResponse> getAlarmResponseStream(String alarmId) {
-        return monitoringGateway.getAlarmResponseStream(alarmId);
+    public Multi<AlarmResponse> getAlarmResponseStream(AlarmSubscription alarmSubscription) {
+        return monitoringGateway.getAlarmResponseStream(alarmSubscription);
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmDescriptor.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmDescriptor.java
index ac216ee7cec55efbd7f169679b4e0eebad0f3950..85f0ce9e725845c86edf5bf265524db456076505 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmDescriptor.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmDescriptor.java
@@ -16,26 +16,36 @@
 
 package eu.teraflow.policy.monitoring.model;
 
+import eu.teraflow.policy.common.Util;
+import java.util.List;
+
 public class AlarmDescriptor {
+    private final String alarmId;
     private final String alarmDescription;
     private final String name;
-    private final String kpiId;
-    private final KpiValueRange kpiValueRange;
-    private final String timestamp;
+    private final List<String> kpiIds;
+    private final List<KpiValueRange> kpiValueRanges;
+    private final double timestamp;
 
     public AlarmDescriptor(
+            String alarmId,
             String alarmDescription,
             String name,
-            String kpiId,
-            KpiValueRange kpiValueRange,
-            String timestamp) {
+            List<String> kpiIds,
+            List<KpiValueRange> kpiValueRanges,
+            double timestamp) {
+        this.alarmId = alarmId;
         this.alarmDescription = alarmDescription;
         this.name = name;
-        this.kpiId = kpiId;
-        this.kpiValueRange = kpiValueRange;
+        this.kpiIds = kpiIds;
+        this.kpiValueRanges = kpiValueRanges;
         this.timestamp = timestamp;
     }
 
+    public String getAlarmId() {
+        return alarmId;
+    }
+
     public String getAlarmDescription() {
         return alarmDescription;
     }
@@ -44,22 +54,28 @@ public class AlarmDescriptor {
         return name;
     }
 
-    public String getKpiId() {
-        return kpiId;
+    public List<String> getKpiIds() {
+        return kpiIds;
     }
 
-    public KpiValueRange getKpiValueRange() {
-        return kpiValueRange;
+    public List<KpiValueRange> getKpiValueRanges() {
+        return kpiValueRanges;
     }
 
-    public String getTimestamp() {
+    public double getTimestamp() {
         return timestamp;
     }
 
     @Override
     public String toString() {
         return String.format(
-                "%s:{alarmDescription:\"%s\", name:\"%s\", kpiId:\"%s\", %s, timestamp:\"%s\"}",
-                getClass().getSimpleName(), alarmDescription, name, kpiId, kpiValueRange, timestamp);
+                "%s:{alarmId:\"%s\", alarmDescription:\"%s\", name:\"%s\", [%s], [%s], timestamp:\"%f\"}",
+                getClass().getSimpleName(),
+                alarmId,
+                alarmDescription,
+                name,
+                Util.toString(kpiIds),
+                Util.toString(kpiValueRanges),
+                timestamp);
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmSubscription.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmSubscription.java
new file mode 100644
index 0000000000000000000000000000000000000000..166d791cc4628d64588e17b33da1baca48ef4810
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/AlarmSubscription.java
@@ -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.
+*/
+
+package eu.teraflow.policy.monitoring.model;
+
+public class AlarmSubscription {
+
+    private final String alarmId;
+    private final float subscriptionTimeoutS;
+    private final float subscriptionFrequencyMs;
+
+    public AlarmSubscription(
+            String alarmId, float subscriptionTimeoutS, float subscriptionFrequencyMs) {
+        this.alarmId = alarmId;
+        this.subscriptionTimeoutS = subscriptionTimeoutS;
+        this.subscriptionFrequencyMs = subscriptionFrequencyMs;
+    }
+
+    public String getAlarmId() {
+        return alarmId;
+    }
+
+    public float getSubscriptionTimeoutS() {
+        return subscriptionTimeoutS;
+    }
+
+    public float getSubscriptionFrequencyMs() {
+        return subscriptionFrequencyMs;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{alarmId:\"%s\", subscriptionTimeoutS:\"%f\", subscriptionFrequencyMs:\"%f\"}",
+                getClass().getSimpleName(), alarmId, subscriptionTimeoutS, subscriptionFrequencyMs);
+    }
+}
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
index c042240298fdea49ca1509ac2563e849b16575c5..98b8c510d487ee2f873d84facac390cdcab4391f 100644
--- 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
@@ -19,10 +19,10 @@ package eu.teraflow.policy.monitoring.model;
 public class Kpi {
 
     private final String kpiId;
-    private final String timestamp;
+    private final double timestamp;
     private final KpiValue<?> kpiValue;
 
-    public Kpi(String kpiId, String timestamp, KpiValue<?> kpiValue) {
+    public Kpi(String kpiId, double timestamp, KpiValue<?> kpiValue) {
         this.kpiId = kpiId;
         this.timestamp = timestamp;
         this.kpiValue = kpiValue;
@@ -32,7 +32,7 @@ public class Kpi {
         return kpiId;
     }
 
-    public String getTimestamp() {
+    public double getTimestamp() {
         return timestamp;
     }
 
@@ -43,7 +43,7 @@ public class Kpi {
     @Override
     public String toString() {
         return String.format(
-                "%s:{kpiId:\"%s\", timeStamp:\"%s\", %s}",
+                "%s:{kpiId:\"%s\", timeStamp:\"%f\", %s}",
                 getClass().getSimpleName(), kpiId, timestamp, kpiValue);
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/SubsDescriptor.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/SubsDescriptor.java
index ced38b3f9f76239ee83687f14587da168dc7c320..101d784c3ba796bbaf2be9820263e595630f2578 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/SubsDescriptor.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/SubsDescriptor.java
@@ -17,23 +17,30 @@
 package eu.teraflow.policy.monitoring.model;
 
 public class SubsDescriptor {
+    private final String subscriptionId;
     private final String kpiId;
     private final float samplingDurationS;
     private final float samplingIntervalS;
-    private final String startDate;
-    private final String endDate;
+    private final double startTimestamp;
+    private final double endTimestamp;
 
     public SubsDescriptor(
+            String subscriptionId,
             String kpiId,
             float samplingDurationS,
             float samplingIntervalS,
-            String startDate,
-            String endDate) {
+            double startTimestamp,
+            double endTimestamp) {
+        this.subscriptionId = subscriptionId;
         this.kpiId = kpiId;
         this.samplingDurationS = samplingDurationS;
         this.samplingIntervalS = samplingIntervalS;
-        this.startDate = startDate;
-        this.endDate = endDate;
+        this.startTimestamp = startTimestamp;
+        this.endTimestamp = endTimestamp;
+    }
+
+    public String getSubscriptionId() {
+        return subscriptionId;
     }
 
     public String getKpiId() {
@@ -48,23 +55,24 @@ public class SubsDescriptor {
         return samplingIntervalS;
     }
 
-    public String getStartDate() {
-        return startDate;
+    public double getStartTimestamp() {
+        return startTimestamp;
     }
 
-    public String getEndDate() {
-        return endDate;
+    public double getEndTimestamp() {
+        return endTimestamp;
     }
 
     @Override
     public String toString() {
         return String.format(
-                "%s:{kpiId:\"%s\", samplingDurationS:\"%f\", samplingIntervalS:\"%f\", startDate:\"%s\", endDate:\"%s\"}",
+                "%s:{subscriptionId:\"%s\", kpiId:\"%s\", samplingDurationS:\"%f\", samplingIntervalS:\"%f\", startTimestamp:\"%f\", endTimestamp:\"%f\"}",
                 getClass().getSimpleName(),
+                subscriptionId,
                 kpiId,
                 samplingDurationS,
                 samplingIntervalS,
-                startDate,
-                endDate);
+                startTimestamp,
+                endTimestamp);
     }
 }
diff --git a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java
index 050af7b0bc8ac2ebb75ae558f8592635c47f56b8..a4f6880c8e174ac628ff16b6499f05bd8bb86309 100644
--- a/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java
+++ b/src/policy/src/test/java/eu/teraflow/policy/SerializerTest.java
@@ -2432,7 +2432,7 @@ class SerializerTest {
                 Arguments.of(
                         new BooleanKpiValue(true), Monitoring.KpiValue.newBuilder().setBoolVal(true).build()),
                 Arguments.of(
-                        new IntegerKpiValue(44), Monitoring.KpiValue.newBuilder().setIntVal(44).build()),
+                        new IntegerKpiValue(44), Monitoring.KpiValue.newBuilder().setInt32Val(44).build()),
                 Arguments.of(
                         new FloatKpiValue(12.3f), Monitoring.KpiValue.newBuilder().setFloatVal(12.3f).build()));
     }
@@ -2507,32 +2507,32 @@ class SerializerTest {
                 Arguments.of(
                         new KpiValueRange(new IntegerKpiValue(32), new IntegerKpiValue(42)),
                         Monitoring.KpiValueRange.newBuilder()
-                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
-                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setInt32Val(32).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setInt32Val(42).build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new IntegerKpiValue(32), new FloatKpiValue(42.2f)),
                         Monitoring.KpiValueRange.newBuilder()
-                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setInt32Val(32).build())
                                 .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setFloatVal(42.2f).build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new IntegerKpiValue(32), new BooleanKpiValue(true)),
                         Monitoring.KpiValueRange.newBuilder()
-                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setInt32Val(32).build())
                                 .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new IntegerKpiValue(32), new StringKpiValue("string")),
                         Monitoring.KpiValueRange.newBuilder()
-                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setIntVal(32).build())
+                                .setKpiMinValue(Monitoring.KpiValue.newBuilder().setInt32Val(32).build())
                                 .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new FloatKpiValue(56.2f), new IntegerKpiValue(42)),
                         Monitoring.KpiValueRange.newBuilder()
                                 .setKpiMinValue(Monitoring.KpiValue.newBuilder().setFloatVal(56.2f).build())
-                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setInt32Val(42).build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new FloatKpiValue(56.2f), new FloatKpiValue(42.2f)),
@@ -2556,7 +2556,7 @@ class SerializerTest {
                         new KpiValueRange(new BooleanKpiValue(true), new IntegerKpiValue(42)),
                         Monitoring.KpiValueRange.newBuilder()
                                 .setKpiMinValue(Monitoring.KpiValue.newBuilder().setBoolVal(true).build())
-                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setInt32Val(42).build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new BooleanKpiValue(false), new FloatKpiValue(42.2f)),
@@ -2580,7 +2580,7 @@ class SerializerTest {
                         new KpiValueRange(new StringKpiValue("string"), new IntegerKpiValue(42)),
                         Monitoring.KpiValueRange.newBuilder()
                                 .setKpiMinValue(Monitoring.KpiValue.newBuilder().setStringVal("string").build())
-                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setIntVal(42).build())
+                                .setKpiMaxValue(Monitoring.KpiValue.newBuilder().setInt32Val(42).build())
                                 .build()),
                 Arguments.of(
                         new KpiValueRange(new StringKpiValue("string"), new FloatKpiValue(42.2f)),
@@ -2656,26 +2656,38 @@ class SerializerTest {
 
     @Test
     void shouldSerializeAlarmDescriptor() {
+        final var alarmId = "alarmId";
         final var alarmDescription = "alarmDescription";
         final var name = "name";
         final var kpiId = "kpiId";
-        final var timestamp = "timestamp";
+        final double timestamp = 100.0;
+        final var kpiIds = List.of("kpiId1", "kpiId2");
 
         final var kpiValueRange = new KpiValueRange(new IntegerKpiValue(23), new IntegerKpiValue(1800));
+        final var kpiValueRanges = List.of(kpiValueRange);
+
         final var alarmDescriptor =
-                new AlarmDescriptor(alarmDescription, name, kpiId, kpiValueRange, timestamp);
+                new AlarmDescriptor(alarmId, alarmDescription, name, kpiIds, kpiValueRanges, timestamp);
 
-        final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
-        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedalarmIdUuid = serializer.serializeUuid(alarmId);
+        final var serializedalarmId = AlarmID.newBuilder().setAlarmId(serializedalarmIdUuid).build();
+
+        final var serializedKpiIdUuid = serializer.serializeUuid("kpiId1");
+        final var serializedKpiId1 = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedKpiId2 = KpiId.newBuilder().setKpiId(serializer.serializeUuid("kpiId2"));
         final var serializedKpiValueRange = serializer.serialize(kpiValueRange);
+        final var serializedTimeStamp =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(timestamp);
 
         final var expectedAlarmDescriptor =
                 Monitoring.AlarmDescriptor.newBuilder()
+                        .setAlarmId(serializedalarmId)
                         .setAlarmDescription(alarmDescription)
                         .setName(name)
-                        .setKpiId(serializedKpiId)
-                        .setKpiValueRange(serializedKpiValueRange)
-                        .setTimestamp(timestamp)
+                        .addKpiId(serializedKpiId1)
+                        .addKpiId(serializedKpiId2)
+                        .addKpiValueRange(serializedKpiValueRange)
+                        .setTimestamp(serializedTimeStamp)
                         .build();
 
         final var serializedAlarmDescriptor = serializer.serialize(alarmDescriptor);
@@ -2685,26 +2697,39 @@ class SerializerTest {
 
     @Test
     void shouldDeserializeAlarmDescriptor() {
+        final var alarmId = "alarmId";
         final var alarmDescription = "alarmDescription";
         final var name = "name";
         final var kpiId = "kpiId";
-        final var timestamp = "timestamp";
+        final double timestamp = 100.0;
+        final var kpiIds = List.of("kpiId1", "kpiId2");
 
         final var kpiValueRange = new KpiValueRange(new IntegerKpiValue(23), new IntegerKpiValue(1800));
+        final var kpiValueRanges = List.of(kpiValueRange);
+
         final var expectedAlarmDescriptor =
-                new AlarmDescriptor(alarmDescription, name, kpiId, kpiValueRange, timestamp);
+                new AlarmDescriptor(alarmId, alarmDescription, name, kpiIds, kpiValueRanges, timestamp);
+
+        final var serializedalarmIdUuid = serializer.serializeUuid(alarmId);
+        final var serializedalarmId = AlarmID.newBuilder().setAlarmId(serializedalarmIdUuid).build();
+
+        final var serializedKpiIdUuid = serializer.serializeUuid("kpiId1");
+        final var serializedKpiId1 = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedKpiId2 = KpiId.newBuilder().setKpiId(serializer.serializeUuid("kpiId2"));
 
-        final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
-        final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
         final var serializedKpiValueRange = serializer.serialize(kpiValueRange);
+        final var serializedTimeStamp =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(timestamp);
 
         final var serializedAlarmDescriptor =
                 Monitoring.AlarmDescriptor.newBuilder()
+                        .setAlarmId(serializedalarmId)
                         .setAlarmDescription(alarmDescription)
                         .setName(name)
-                        .setKpiId(serializedKpiId)
-                        .setKpiValueRange(serializedKpiValueRange)
-                        .setTimestamp(timestamp)
+                        .addKpiId(serializedKpiId1)
+                        .addKpiId(serializedKpiId2)
+                        .addKpiValueRange(serializedKpiValueRange)
+                        .setTimestamp(serializedTimeStamp)
                         .build();
 
         final var alarmDescriptor = serializer.deserialize(serializedAlarmDescriptor);
@@ -2762,25 +2787,42 @@ class SerializerTest {
 
     @Test
     void shouldSerializeSubDescriptor() {
+        final var subscriptionId = "subscriptionId";
         final var kpiId = "kpiId";
         final var samplingDurationS = 10f;
         final var samplingIntervalS = 45f;
-        final var startDate = "01/07/2022";
-        final var endDate = "02/07/2022";
+        final var startTimestamp = 1.0;
+        final var endTimestamp = 100.0;
 
         final var subDescriptor =
-                new SubsDescriptor(kpiId, samplingDurationS, samplingIntervalS, startDate, endDate);
-
+                new SubsDescriptor(
+                        subscriptionId,
+                        kpiId,
+                        samplingDurationS,
+                        samplingIntervalS,
+                        startTimestamp,
+                        endTimestamp);
+
+        final var serializedSubscriptionIdUuid = serializer.serializeUuid(subscriptionId);
+        final var serializedSubscriptionId =
+                monitoring.Monitoring.SubscriptionID.newBuilder()
+                        .setSubsId(serializedSubscriptionIdUuid)
+                        .build();
         final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
         final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedStartTimestamp =
+                ContextOuterClass.Timestamp.newBuilder().setTimestamp(startTimestamp);
+        final var serializedEndTimestamp =
+                ContextOuterClass.Timestamp.newBuilder().setTimestamp(endTimestamp);
 
         final var expectedSubDescriptor =
                 Monitoring.SubsDescriptor.newBuilder()
+                        .setSubsId(serializedSubscriptionId)
                         .setKpiId(serializedKpiId)
                         .setSamplingDurationS(samplingDurationS)
                         .setSamplingIntervalS(samplingIntervalS)
-                        .setStartDate(startDate)
-                        .setEndDate(endDate)
+                        .setStartTimestamp(serializedStartTimestamp)
+                        .setEndTimestamp(serializedEndTimestamp)
                         .build();
 
         final var serializedSubDescriptor = serializer.serialize(subDescriptor);
@@ -2790,25 +2832,42 @@ class SerializerTest {
 
     @Test
     void shouldDeserializeSubDescriptor() {
+        final var subscriptionId = "subscriptionId";
         final var kpiId = "kpiId";
         final var samplingDurationS = 10f;
         final var samplingIntervalS = 45f;
-        final var startDate = "01/07/2022";
-        final var endDate = "02/07/2022";
+        final var startTimestamp = 1.0;
+        final var endTimestamp = 100.0;
 
         final var expectedSubDescriptor =
-                new SubsDescriptor(kpiId, samplingDurationS, samplingIntervalS, startDate, endDate);
-
+                new SubsDescriptor(
+                        subscriptionId,
+                        kpiId,
+                        samplingDurationS,
+                        samplingIntervalS,
+                        startTimestamp,
+                        endTimestamp);
+
+        final var serializedSubscriptionIdUuid = serializer.serializeUuid(subscriptionId);
+        final var serializedSubscriptionId =
+                monitoring.Monitoring.SubscriptionID.newBuilder()
+                        .setSubsId(serializedSubscriptionIdUuid)
+                        .build();
         final var serializedKpiIdUuid = serializer.serializeUuid(kpiId);
         final var serializedKpiId = KpiId.newBuilder().setKpiId(serializedKpiIdUuid).build();
+        final var serializedStartTimestamp =
+                ContextOuterClass.Timestamp.newBuilder().setTimestamp(startTimestamp);
+        final var serializedEndTimestamp =
+                ContextOuterClass.Timestamp.newBuilder().setTimestamp(endTimestamp);
 
         final var serializedSubDescriptor =
                 Monitoring.SubsDescriptor.newBuilder()
+                        .setSubsId(serializedSubscriptionId)
                         .setKpiId(serializedKpiId)
                         .setSamplingDurationS(samplingDurationS)
                         .setSamplingIntervalS(samplingIntervalS)
-                        .setStartDate(startDate)
-                        .setEndDate(endDate)
+                        .setStartTimestamp(serializedStartTimestamp)
+                        .setEndTimestamp(serializedEndTimestamp)
                         .build();
 
         final var subDescriptor = serializer.deserialize(serializedSubDescriptor);
@@ -3155,18 +3214,20 @@ class SerializerTest {
     @Test
     void shouldSerializeKpi() {
         final var expectedKpiId = "expectedKpiId";
-        final var expectedTimestamp = "expectedTimestamp";
+        final var expectedTimestamp = 100.0;
         final var expectedKpiValue = new FloatKpiValue(643.45f);
 
         final var kpi = new Kpi(expectedKpiId, expectedTimestamp, expectedKpiValue);
 
         final var serializedKpiId = serializer.serializeKpiId(expectedKpiId);
         final var serializedKpiValue = serializer.serialize(expectedKpiValue);
+        final var serializedexpectedTimestamp =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(expectedTimestamp);
 
         final var expectedKpi =
                 Monitoring.Kpi.newBuilder()
                         .setKpiId(serializedKpiId)
-                        .setTimestamp(expectedTimestamp)
+                        .setTimestamp(serializedexpectedTimestamp)
                         .setKpiValue(serializedKpiValue)
                         .build();
 
@@ -3178,7 +3239,7 @@ class SerializerTest {
     @Test
     void shouldDeserializeKpi() {
         final var expectedKpiId = "expectedKpiId";
-        final var expectedTimestamp = "expectedTimestamp";
+        final var expectedTimestamp = 100.0;
         final var expectedKpiValue = new BooleanKpiValue(true);
         final var expectedKpi = new Kpi(expectedKpiId, expectedTimestamp, expectedKpiValue);
 
@@ -3192,16 +3253,20 @@ class SerializerTest {
     @Test
     void shouldSerializeKpisList() {
         final var expectedKpiIdA = "expectedKpiIdA";
-        final var expectedTimestampA = "expectedTimestampA";
+        final var expectedTimestampA = 100.0;
         final var expectedKpiValueA = new FloatKpiValue(643.45f);
         final var serializedKpiIdA = serializer.serializeKpiId(expectedKpiIdA);
+        final var serializedexpectedTimestampA =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(expectedTimestampA);
         final var serializedKpiValueA = serializer.serialize(expectedKpiValueA);
         final var kpiA = new Kpi(expectedKpiIdA, expectedTimestampA, expectedKpiValueA);
 
         final var expectedKpiIdB = "expectedKpiIdB";
-        final var expectedTimestampB = "expectedTimestampB";
+        final var expectedTimestampB = 100.0;
         final var expectedKpiValueB = new IntegerKpiValue(32);
         final var serializedKpiIdB = serializer.serializeKpiId(expectedKpiIdB);
+        final var serializedexpectedTimestampB =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(expectedTimestampB);
         final var serializedKpiValueB = serializer.serialize(expectedKpiValueB);
         final var kpiB = new Kpi(expectedKpiIdB, expectedTimestampB, expectedKpiValueB);
 
@@ -3210,14 +3275,14 @@ class SerializerTest {
         final var expectedKpiA =
                 Monitoring.Kpi.newBuilder()
                         .setKpiId(serializedKpiIdA)
-                        .setTimestamp(expectedTimestampA)
+                        .setTimestamp(serializedexpectedTimestampA)
                         .setKpiValue(serializedKpiValueA)
                         .build();
 
         final var expectedKpiB =
                 Monitoring.Kpi.newBuilder()
                         .setKpiId(serializedKpiIdB)
-                        .setTimestamp(expectedTimestampB)
+                        .setTimestamp(serializedexpectedTimestampB)
                         .setKpiValue(serializedKpiValueB)
                         .build();
 
@@ -3231,16 +3296,20 @@ class SerializerTest {
     @Test
     void shouldDeserializeKpisList() {
         final var expectedKpiIdA = "expectedKpiIdA";
-        final var expectedTimestampA = "expectedTimestampA";
+        final var expectedTimestampA = 100.0;
         final var expectedKpiValueA = new FloatKpiValue(643.45f);
         final var serializedKpiIdA = serializer.serializeKpiId(expectedKpiIdA);
+        final var serializedexpectedTimestampA =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(expectedTimestampA);
         final var serializedKpiValueA = serializer.serialize(expectedKpiValueA);
         final var expectedKpiA = new Kpi(expectedKpiIdA, expectedTimestampA, expectedKpiValueA);
 
         final var expectedKpiIdB = "expectedKpiIdB";
-        final var expectedTimestampB = "expectedTimestampB";
+        final var expectedTimestampB = 200.0;
         final var expectedKpiValueB = new IntegerKpiValue(32);
         final var serializedKpiIdB = serializer.serializeKpiId(expectedKpiIdB);
+        final var serializedexpectedTimestampB =
+                context.ContextOuterClass.Timestamp.newBuilder().setTimestamp(expectedTimestampB);
         final var serializedKpiValueB = serializer.serialize(expectedKpiValueB);
         final var expectedKpiB = new Kpi(expectedKpiIdB, expectedTimestampB, expectedKpiValueB);
 
@@ -3249,14 +3318,14 @@ class SerializerTest {
         final var serializedKpiA =
                 Monitoring.Kpi.newBuilder()
                         .setKpiId(serializedKpiIdA)
-                        .setTimestamp(expectedTimestampA)
+                        .setTimestamp(serializedexpectedTimestampA)
                         .setKpiValue(serializedKpiValueA)
                         .build();
 
         final var serializedKpiB =
                 Monitoring.Kpi.newBuilder()
                         .setKpiId(serializedKpiIdB)
-                        .setTimestamp(expectedTimestampB)
+                        .setTimestamp(serializedexpectedTimestampB)
                         .setKpiValue(serializedKpiValueB)
                         .build();
 
diff --git a/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java b/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java
index 1e953741471dbe872e491ad8ab836e1d7653a05e..fbbba62a2baa1c2fe2b3c3fe090883d6542996e4 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java
@@ -17340,6 +17340,21 @@ public final class ContextOuterClass {
      * <code>.context.DeviceId device_id = 2;</code>
      */
     context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
+
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return Whether the deviceConfig field is set.
+     */
+    boolean hasDeviceConfig();
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return The deviceConfig.
+     */
+    context.ContextOuterClass.DeviceConfig getDeviceConfig();
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     */
+    context.ContextOuterClass.DeviceConfigOrBuilder getDeviceConfigOrBuilder();
   }
   /**
    * Protobuf type {@code context.DeviceEvent}
@@ -17412,6 +17427,19 @@ public final class ContextOuterClass {
 
               break;
             }
+            case 26: {
+              context.ContextOuterClass.DeviceConfig.Builder subBuilder = null;
+              if (deviceConfig_ != null) {
+                subBuilder = deviceConfig_.toBuilder();
+              }
+              deviceConfig_ = input.readMessage(context.ContextOuterClass.DeviceConfig.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(deviceConfig_);
+                deviceConfig_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -17496,6 +17524,32 @@ public final class ContextOuterClass {
       return getDeviceId();
     }
 
+    public static final int DEVICE_CONFIG_FIELD_NUMBER = 3;
+    private context.ContextOuterClass.DeviceConfig deviceConfig_;
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return Whether the deviceConfig field is set.
+     */
+    @java.lang.Override
+    public boolean hasDeviceConfig() {
+      return deviceConfig_ != null;
+    }
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     * @return The deviceConfig.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceConfig getDeviceConfig() {
+      return deviceConfig_ == null ? context.ContextOuterClass.DeviceConfig.getDefaultInstance() : deviceConfig_;
+    }
+    /**
+     * <code>.context.DeviceConfig device_config = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceConfigOrBuilder getDeviceConfigOrBuilder() {
+      return getDeviceConfig();
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -17516,6 +17570,9 @@ public final class ContextOuterClass {
       if (deviceId_ != null) {
         output.writeMessage(2, getDeviceId());
       }
+      if (deviceConfig_ != null) {
+        output.writeMessage(3, getDeviceConfig());
+      }
       unknownFields.writeTo(output);
     }
 
@@ -17533,6 +17590,10 @@ public final class ContextOuterClass {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, getDeviceId());
       }
+      if (deviceConfig_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getDeviceConfig());
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -17558,6 +17619,11 @@ public final class ContextOuterClass {
         if (!getDeviceId()
             .equals(other.getDeviceId())) return false;
       }
+      if (hasDeviceConfig() != other.hasDeviceConfig()) return false;
+      if (hasDeviceConfig()) {
+        if (!getDeviceConfig()
+            .equals(other.getDeviceConfig())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -17577,6 +17643,10 @@ public final class ContextOuterClass {
         hash = (37 * hash) + DEVICE_ID_FIELD_NUMBER;
         hash = (53 * hash) + getDeviceId().hashCode();
       }
+      if (hasDeviceConfig()) {
+        hash = (37 * hash) + DEVICE_CONFIG_FIELD_NUMBER;
+        hash = (53 * hash) + getDeviceConfig().hashCode();
+      }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -17722,6 +17792,12 @@ public final class ContextOuterClass {
           deviceId_ = null;
           deviceIdBuilder_ = null;
         }
+        if (deviceConfigBuilder_ == null) {
+          deviceConfig_ = null;
+        } else {
+          deviceConfig_ = null;
+          deviceConfigBuilder_ = null;
+        }
         return this;
       }
 
@@ -17758,6 +17834,11 @@ public final class ContextOuterClass {
         } else {
           result.deviceId_ = deviceIdBuilder_.build();
         }
+        if (deviceConfigBuilder_ == null) {
+          result.deviceConfig_ = deviceConfig_;
+        } else {
+          result.deviceConfig_ = deviceConfigBuilder_.build();
+        }
         onBuilt();
         return result;
       }
@@ -17812,6 +17893,9 @@ public final class ContextOuterClass {
         if (other.hasDeviceId()) {
           mergeDeviceId(other.getDeviceId());
         }
+        if (other.hasDeviceConfig()) {
+          mergeDeviceConfig(other.getDeviceConfig());
+        }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
@@ -18078,6 +18162,125 @@ public final class ContextOuterClass {
         }
         return deviceIdBuilder_;
       }
+
+      private context.ContextOuterClass.DeviceConfig deviceConfig_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder> deviceConfigBuilder_;
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       * @return Whether the deviceConfig field is set.
+       */
+      public boolean hasDeviceConfig() {
+        return deviceConfigBuilder_ != null || deviceConfig_ != null;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       * @return The deviceConfig.
+       */
+      public context.ContextOuterClass.DeviceConfig getDeviceConfig() {
+        if (deviceConfigBuilder_ == null) {
+          return deviceConfig_ == null ? context.ContextOuterClass.DeviceConfig.getDefaultInstance() : deviceConfig_;
+        } else {
+          return deviceConfigBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder setDeviceConfig(context.ContextOuterClass.DeviceConfig value) {
+        if (deviceConfigBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          deviceConfig_ = value;
+          onChanged();
+        } else {
+          deviceConfigBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder setDeviceConfig(
+          context.ContextOuterClass.DeviceConfig.Builder builderForValue) {
+        if (deviceConfigBuilder_ == null) {
+          deviceConfig_ = builderForValue.build();
+          onChanged();
+        } else {
+          deviceConfigBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder mergeDeviceConfig(context.ContextOuterClass.DeviceConfig value) {
+        if (deviceConfigBuilder_ == null) {
+          if (deviceConfig_ != null) {
+            deviceConfig_ =
+              context.ContextOuterClass.DeviceConfig.newBuilder(deviceConfig_).mergeFrom(value).buildPartial();
+          } else {
+            deviceConfig_ = value;
+          }
+          onChanged();
+        } else {
+          deviceConfigBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public Builder clearDeviceConfig() {
+        if (deviceConfigBuilder_ == null) {
+          deviceConfig_ = null;
+          onChanged();
+        } else {
+          deviceConfig_ = null;
+          deviceConfigBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceConfig.Builder getDeviceConfigBuilder() {
+        
+        onChanged();
+        return getDeviceConfigFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceConfigOrBuilder getDeviceConfigOrBuilder() {
+        if (deviceConfigBuilder_ != null) {
+          return deviceConfigBuilder_.getMessageOrBuilder();
+        } else {
+          return deviceConfig_ == null ?
+              context.ContextOuterClass.DeviceConfig.getDefaultInstance() : deviceConfig_;
+        }
+      }
+      /**
+       * <code>.context.DeviceConfig device_config = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder> 
+          getDeviceConfigFieldBuilder() {
+        if (deviceConfigBuilder_ == null) {
+          deviceConfigBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.DeviceConfig, context.ContextOuterClass.DeviceConfig.Builder, context.ContextOuterClass.DeviceConfigOrBuilder>(
+                  getDeviceConfig(),
+                  getParentForChildren(),
+                  isClean());
+          deviceConfig_ = null;
+        }
+        return deviceConfigBuilder_;
+      }
       @java.lang.Override
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
@@ -61990,231 +62193,234 @@ public final class ContextOuterClass {
       "(\0132\023.context.ConfigRule\"5\n\014DeviceIdList\022" +
       "%\n\ndevice_ids\030\001 \003(\0132\021.context.DeviceId\"." +
       "\n\nDeviceList\022 \n\007devices\030\001 \003(\0132\017.context." +
-      "Device\"R\n\013DeviceEvent\022\035\n\005event\030\001 \001(\0132\016.c" +
-      "ontext.Event\022$\n\tdevice_id\030\002 \001(\0132\021.contex" +
-      "t.DeviceId\"*\n\006LinkId\022 \n\tlink_uuid\030\001 \001(\0132" +
-      "\r.context.Uuid\"X\n\004Link\022 \n\007link_id\030\001 \001(\0132" +
-      "\017.context.LinkId\022.\n\021link_endpoint_ids\030\002 " +
-      "\003(\0132\023.context.EndPointId\"/\n\nLinkIdList\022!" +
-      "\n\010link_ids\030\001 \003(\0132\017.context.LinkId\"(\n\010Lin" +
-      "kList\022\034\n\005links\030\001 \003(\0132\r.context.Link\"L\n\tL" +
-      "inkEvent\022\035\n\005event\030\001 \001(\0132\016.context.Event\022" +
-      " \n\007link_id\030\002 \001(\0132\017.context.LinkId\"X\n\tSer" +
-      "viceId\022&\n\ncontext_id\030\001 \001(\0132\022.context.Con" +
-      "textId\022#\n\014service_uuid\030\002 \001(\0132\r.context.U" +
-      "uid\"\315\002\n\007Service\022&\n\nservice_id\030\001 \001(\0132\022.co" +
-      "ntext.ServiceId\022.\n\014service_type\030\002 \001(\0162\030." +
-      "context.ServiceTypeEnum\0221\n\024service_endpo" +
-      "int_ids\030\003 \003(\0132\023.context.EndPointId\0220\n\023se" +
-      "rvice_constraints\030\004 \003(\0132\023.context.Constr" +
-      "aint\022.\n\016service_status\030\005 \001(\0132\026.context.S" +
-      "erviceStatus\022.\n\016service_config\030\006 \001(\0132\026.c" +
-      "ontext.ServiceConfig\022%\n\ttimestamp\030\007 \001(\0132" +
-      "\022.context.Timestamp\"C\n\rServiceStatus\0222\n\016" +
-      "service_status\030\001 \001(\0162\032.context.ServiceSt" +
-      "atusEnum\":\n\rServiceConfig\022)\n\014config_rule" +
-      "s\030\001 \003(\0132\023.context.ConfigRule\"8\n\rServiceI" +
-      "dList\022\'\n\013service_ids\030\001 \003(\0132\022.context.Ser" +
-      "viceId\"1\n\013ServiceList\022\"\n\010services\030\001 \003(\0132" +
-      "\020.context.Service\"U\n\014ServiceEvent\022\035\n\005eve" +
-      "nt\030\001 \001(\0132\016.context.Event\022&\n\nservice_id\030\002" +
-      " \001(\0132\022.context.ServiceId\"T\n\007SliceId\022&\n\nc" +
-      "ontext_id\030\001 \001(\0132\022.context.ContextId\022!\n\ns" +
-      "lice_uuid\030\002 \001(\0132\r.context.Uuid\"\222\003\n\005Slice" +
-      "\022\"\n\010slice_id\030\001 \001(\0132\020.context.SliceId\022/\n\022" +
-      "slice_endpoint_ids\030\002 \003(\0132\023.context.EndPo" +
-      "intId\022.\n\021slice_constraints\030\003 \003(\0132\023.conte" +
-      "xt.Constraint\022-\n\021slice_service_ids\030\004 \003(\013" +
-      "2\022.context.ServiceId\022,\n\022slice_subslice_i" +
-      "ds\030\005 \003(\0132\020.context.SliceId\022*\n\014slice_stat" +
-      "us\030\006 \001(\0132\024.context.SliceStatus\022*\n\014slice_" +
-      "config\030\007 \001(\0132\024.context.SliceConfig\022(\n\013sl" +
-      "ice_owner\030\010 \001(\0132\023.context.SliceOwner\022%\n\t" +
-      "timestamp\030\t \001(\0132\022.context.Timestamp\"E\n\nS" +
-      "liceOwner\022!\n\nowner_uuid\030\001 \001(\0132\r.context." +
-      "Uuid\022\024\n\014owner_string\030\002 \001(\t\"=\n\013SliceStatu" +
-      "s\022.\n\014slice_status\030\001 \001(\0162\030.context.SliceS" +
-      "tatusEnum\"8\n\013SliceConfig\022)\n\014config_rules" +
-      "\030\001 \003(\0132\023.context.ConfigRule\"2\n\013SliceIdLi" +
-      "st\022#\n\tslice_ids\030\001 \003(\0132\020.context.SliceId\"" +
-      "+\n\tSliceList\022\036\n\006slices\030\001 \003(\0132\016.context.S" +
-      "lice\"O\n\nSliceEvent\022\035\n\005event\030\001 \001(\0132\016.cont" +
-      "ext.Event\022\"\n\010slice_id\030\002 \001(\0132\020.context.Sl" +
-      "iceId\"6\n\014ConnectionId\022&\n\017connection_uuid" +
-      "\030\001 \001(\0132\r.context.Uuid\"2\n\025ConnectionSetti" +
-      "ngs_L0\022\031\n\021lsp_symbolic_name\030\001 \001(\t\"\236\001\n\025Co" +
-      "nnectionSettings_L2\022\027\n\017src_mac_address\030\001" +
-      " \001(\t\022\027\n\017dst_mac_address\030\002 \001(\t\022\022\n\nether_t" +
-      "ype\030\003 \001(\r\022\017\n\007vlan_id\030\004 \001(\r\022\022\n\nmpls_label" +
-      "\030\005 \001(\r\022\032\n\022mpls_traffic_class\030\006 \001(\r\"t\n\025Co" +
-      "nnectionSettings_L3\022\026\n\016src_ip_address\030\001 " +
-      "\001(\t\022\026\n\016dst_ip_address\030\002 \001(\t\022\014\n\004dscp\030\003 \001(" +
-      "\r\022\020\n\010protocol\030\004 \001(\r\022\013\n\003ttl\030\005 \001(\r\"[\n\025Conn" +
-      "ectionSettings_L4\022\020\n\010src_port\030\001 \001(\r\022\020\n\010d" +
-      "st_port\030\002 \001(\r\022\021\n\ttcp_flags\030\003 \001(\r\022\013\n\003ttl\030" +
-      "\004 \001(\r\"\304\001\n\022ConnectionSettings\022*\n\002l0\030\001 \001(\013" +
-      "2\036.context.ConnectionSettings_L0\022*\n\002l2\030\002" +
-      " \001(\0132\036.context.ConnectionSettings_L2\022*\n\002" +
-      "l3\030\003 \001(\0132\036.context.ConnectionSettings_L3" +
-      "\022*\n\002l4\030\004 \001(\0132\036.context.ConnectionSetting" +
-      "s_L4\"\363\001\n\nConnection\022,\n\rconnection_id\030\001 \001" +
-      "(\0132\025.context.ConnectionId\022&\n\nservice_id\030" +
-      "\002 \001(\0132\022.context.ServiceId\0223\n\026path_hops_e" +
-      "ndpoint_ids\030\003 \003(\0132\023.context.EndPointId\022+" +
-      "\n\017sub_service_ids\030\004 \003(\0132\022.context.Servic" +
-      "eId\022-\n\010settings\030\005 \001(\0132\033.context.Connecti" +
-      "onSettings\"A\n\020ConnectionIdList\022-\n\016connec" +
-      "tion_ids\030\001 \003(\0132\025.context.ConnectionId\":\n" +
-      "\016ConnectionList\022(\n\013connections\030\001 \003(\0132\023.c" +
-      "ontext.Connection\"^\n\017ConnectionEvent\022\035\n\005" +
-      "event\030\001 \001(\0132\016.context.Event\022,\n\rconnectio" +
-      "n_id\030\002 \001(\0132\025.context.ConnectionId\"\202\001\n\nEn" +
-      "dPointId\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.contex" +
-      "t.Uuid\"\264\001\n\010EndPoint\022(\n\013endpoint_id\030\001 \001(\013" +
-      "2\023.context.EndPointId\022\025\n\rendpoint_type\030\002" +
-      " \001(\t\0229\n\020kpi_sample_types\030\003 \003(\0162\037.kpi_sam" +
-      "ple_types.KpiSampleType\022,\n\021endpoint_loca" +
-      "tion\030\004 \001(\0132\021.context.Location\"A\n\021ConfigR" +
-      "ule_Custom\022\024\n\014resource_key\030\001 \001(\t\022\026\n\016reso" +
-      "urce_value\030\002 \001(\t\"]\n\016ConfigRule_ACL\022(\n\013en" +
-      "dpoint_id\030\001 \001(\0132\023.context.EndPointId\022!\n\010" +
-      "rule_set\030\002 \001(\0132\017.acl.AclRuleSet\"\234\001\n\nConf" +
-      "igRule\022)\n\006action\030\001 \001(\0162\031.context.ConfigA" +
-      "ctionEnum\022,\n\006custom\030\002 \001(\0132\032.context.Conf" +
-      "igRule_CustomH\000\022&\n\003acl\030\003 \001(\0132\027.context.C" +
-      "onfigRule_ACLH\000B\r\n\013config_rule\"F\n\021Constr" +
-      "aint_Custom\022\027\n\017constraint_type\030\001 \001(\t\022\030\n\020" +
-      "constraint_value\030\002 \001(\t\"E\n\023Constraint_Sch" +
-      "edule\022\027\n\017start_timestamp\030\001 \001(\002\022\025\n\rdurati" +
-      "on_days\030\002 \001(\002\"3\n\014GPS_Position\022\020\n\010latitud" +
-      "e\030\001 \001(\002\022\021\n\tlongitude\030\002 \001(\002\"W\n\010Location\022\020" +
-      "\n\006region\030\001 \001(\tH\000\022-\n\014gps_position\030\002 \001(\0132\025" +
-      ".context.GPS_PositionH\000B\n\n\010location\"l\n\033C" +
-      "onstraint_EndPointLocation\022(\n\013endpoint_i" +
-      "d\030\001 \001(\0132\023.context.EndPointId\022#\n\010location" +
-      "\030\002 \001(\0132\021.context.Location\"Y\n\033Constraint_" +
-      "EndPointPriority\022(\n\013endpoint_id\030\001 \001(\0132\023." +
-      "context.EndPointId\022\020\n\010priority\030\002 \001(\r\"0\n\026" +
-      "Constraint_SLA_Latency\022\026\n\016e2e_latency_ms" +
-      "\030\001 \001(\002\"0\n\027Constraint_SLA_Capacity\022\025\n\rcap" +
-      "acity_gbps\030\001 \001(\002\"M\n\033Constraint_SLA_Avail" +
-      "ability\022\032\n\022num_disjoint_paths\030\001 \001(\r\022\022\n\na" +
-      "ll_active\030\002 \001(\010\"V\n\036Constraint_SLA_Isolat" +
-      "ion_level\0224\n\017isolation_level\030\001 \003(\0162\033.con" +
-      "text.IsolationLevelEnum\"\366\003\n\nConstraint\022," +
-      "\n\006custom\030\001 \001(\0132\032.context.Constraint_Cust" +
-      "omH\000\0220\n\010schedule\030\002 \001(\0132\034.context.Constra" +
-      "int_ScheduleH\000\022A\n\021endpoint_location\030\003 \001(" +
-      "\0132$.context.Constraint_EndPointLocationH" +
-      "\000\022A\n\021endpoint_priority\030\004 \001(\0132$.context.C" +
-      "onstraint_EndPointPriorityH\000\0228\n\014sla_capa" +
-      "city\030\005 \001(\0132 .context.Constraint_SLA_Capa" +
-      "cityH\000\0226\n\013sla_latency\030\006 \001(\0132\037.context.Co" +
-      "nstraint_SLA_LatencyH\000\022@\n\020sla_availabili" +
-      "ty\030\007 \001(\0132$.context.Constraint_SLA_Availa" +
-      "bilityH\000\022@\n\rsla_isolation\030\010 \001(\0132\'.contex" +
-      "t.Constraint_SLA_Isolation_levelH\000B\014\n\nco" +
-      "nstraint\"^\n\022TeraFlowController\022&\n\ncontex" +
-      "t_id\030\001 \001(\0132\022.context.ContextId\022\022\n\nip_add" +
-      "ress\030\002 \001(\t\022\014\n\004port\030\003 \001(\r\"U\n\024Authenticati" +
-      "onResult\022&\n\ncontext_id\030\001 \001(\0132\022.context.C" +
-      "ontextId\022\025\n\rauthenticated\030\002 \001(\010*j\n\rEvent" +
-      "TypeEnum\022\027\n\023EVENTTYPE_UNDEFINED\020\000\022\024\n\020EVE" +
-      "NTTYPE_CREATE\020\001\022\024\n\020EVENTTYPE_UPDATE\020\002\022\024\n" +
-      "\020EVENTTYPE_REMOVE\020\003*\332\001\n\020DeviceDriverEnum" +
-      "\022\032\n\026DEVICEDRIVER_UNDEFINED\020\000\022\033\n\027DEVICEDR" +
-      "IVER_OPENCONFIG\020\001\022\036\n\032DEVICEDRIVER_TRANSP" +
-      "ORT_API\020\002\022\023\n\017DEVICEDRIVER_P4\020\003\022&\n\"DEVICE" +
-      "DRIVER_IETF_NETWORK_TOPOLOGY\020\004\022\033\n\027DEVICE" +
-      "DRIVER_ONF_TR_352\020\005\022\023\n\017DEVICEDRIVER_XR\020\006" +
-      "*\217\001\n\033DeviceOperationalStatusEnum\022%\n!DEVI" +
-      "CEOPERATIONALSTATUS_UNDEFINED\020\000\022$\n DEVIC" +
-      "EOPERATIONALSTATUS_DISABLED\020\001\022#\n\037DEVICEO" +
-      "PERATIONALSTATUS_ENABLED\020\002*\201\001\n\017ServiceTy" +
-      "peEnum\022\027\n\023SERVICETYPE_UNKNOWN\020\000\022\024\n\020SERVI" +
-      "CETYPE_L3NM\020\001\022\024\n\020SERVICETYPE_L2NM\020\002\022)\n%S" +
-      "ERVICETYPE_TAPI_CONNECTIVITY_SERVICE\020\003*\250" +
-      "\001\n\021ServiceStatusEnum\022\033\n\027SERVICESTATUS_UN" +
-      "DEFINED\020\000\022\031\n\025SERVICESTATUS_PLANNED\020\001\022\030\n\024" +
-      "SERVICESTATUS_ACTIVE\020\002\022!\n\035SERVICESTATUS_" +
-      "PENDING_REMOVAL\020\003\022\036\n\032SERVICESTATUS_SLA_V" +
-      "IOLATED\020\004*\251\001\n\017SliceStatusEnum\022\031\n\025SLICEST" +
-      "ATUS_UNDEFINED\020\000\022\027\n\023SLICESTATUS_PLANNED\020" +
-      "\001\022\024\n\020SLICESTATUS_INIT\020\002\022\026\n\022SLICESTATUS_A" +
-      "CTIVE\020\003\022\026\n\022SLICESTATUS_DEINIT\020\004\022\034\n\030SLICE" +
-      "STATUS_SLA_VIOLATED\020\005*]\n\020ConfigActionEnu" +
-      "m\022\032\n\026CONFIGACTION_UNDEFINED\020\000\022\024\n\020CONFIGA" +
-      "CTION_SET\020\001\022\027\n\023CONFIGACTION_DELETE\020\002*\203\002\n" +
-      "\022IsolationLevelEnum\022\020\n\014NO_ISOLATION\020\000\022\026\n" +
-      "\022PHYSICAL_ISOLATION\020\001\022\025\n\021LOGICAL_ISOLATI" +
-      "ON\020\002\022\025\n\021PROCESS_ISOLATION\020\003\022\035\n\031PHYSICAL_" +
-      "MEMORY_ISOLATION\020\004\022\036\n\032PHYSICAL_NETWORK_I" +
-      "SOLATION\020\005\022\036\n\032VIRTUAL_RESOURCE_ISOLATION" +
-      "\020\006\022\037\n\033NETWORK_FUNCTIONS_ISOLATION\020\007\022\025\n\021S" +
-      "ERVICE_ISOLATION\020\0102\357\022\n\016ContextService\022:\n" +
-      "\016ListContextIds\022\016.context.Empty\032\026.contex" +
-      "t.ContextIdList\"\000\0226\n\014ListContexts\022\016.cont" +
-      "ext.Empty\032\024.context.ContextList\"\000\0224\n\nGet" +
-      "Context\022\022.context.ContextId\032\020.context.Co" +
-      "ntext\"\000\0224\n\nSetContext\022\020.context.Context\032" +
-      "\022.context.ContextId\"\000\0225\n\rRemoveContext\022\022" +
-      ".context.ContextId\032\016.context.Empty\"\000\022=\n\020" +
-      "GetContextEvents\022\016.context.Empty\032\025.conte" +
-      "xt.ContextEvent\"\0000\001\022@\n\017ListTopologyIds\022\022" +
-      ".context.ContextId\032\027.context.TopologyIdL" +
-      "ist\"\000\022=\n\016ListTopologies\022\022.context.Contex" +
-      "tId\032\025.context.TopologyList\"\000\0227\n\013GetTopol" +
-      "ogy\022\023.context.TopologyId\032\021.context.Topol" +
-      "ogy\"\000\0227\n\013SetTopology\022\021.context.Topology\032" +
-      "\023.context.TopologyId\"\000\0227\n\016RemoveTopology" +
-      "\022\023.context.TopologyId\032\016.context.Empty\"\000\022" +
-      "?\n\021GetTopologyEvents\022\016.context.Empty\032\026.c" +
-      "ontext.TopologyEvent\"\0000\001\0228\n\rListDeviceId" +
-      "s\022\016.context.Empty\032\025.context.DeviceIdList" +
-      "\"\000\0224\n\013ListDevices\022\016.context.Empty\032\023.cont" +
-      "ext.DeviceList\"\000\0221\n\tGetDevice\022\021.context." +
-      "DeviceId\032\017.context.Device\"\000\0221\n\tSetDevice" +
-      "\022\017.context.Device\032\021.context.DeviceId\"\000\0223" +
-      "\n\014RemoveDevice\022\021.context.DeviceId\032\016.cont" +
-      "ext.Empty\"\000\022;\n\017GetDeviceEvents\022\016.context" +
-      ".Empty\032\024.context.DeviceEvent\"\0000\001\0224\n\013List" +
-      "LinkIds\022\016.context.Empty\032\023.context.LinkId" +
-      "List\"\000\0220\n\tListLinks\022\016.context.Empty\032\021.co" +
-      "ntext.LinkList\"\000\022+\n\007GetLink\022\017.context.Li" +
-      "nkId\032\r.context.Link\"\000\022+\n\007SetLink\022\r.conte" +
-      "xt.Link\032\017.context.LinkId\"\000\022/\n\nRemoveLink" +
-      "\022\017.context.LinkId\032\016.context.Empty\"\000\0227\n\rG" +
-      "etLinkEvents\022\016.context.Empty\032\022.context.L" +
-      "inkEvent\"\0000\001\022>\n\016ListServiceIds\022\022.context" +
-      ".ContextId\032\026.context.ServiceIdList\"\000\022:\n\014" +
-      "ListServices\022\022.context.ContextId\032\024.conte" +
-      "xt.ServiceList\"\000\0224\n\nGetService\022\022.context" +
-      ".ServiceId\032\020.context.Service\"\000\0224\n\nSetSer" +
-      "vice\022\020.context.Service\032\022.context.Service" +
-      "Id\"\000\0225\n\rRemoveService\022\022.context.ServiceI" +
-      "d\032\016.context.Empty\"\000\022=\n\020GetServiceEvents\022" +
-      "\016.context.Empty\032\025.context.ServiceEvent\"\000" +
-      "0\001\022:\n\014ListSliceIds\022\022.context.ContextId\032\024" +
-      ".context.SliceIdList\"\000\0226\n\nListSlices\022\022.c" +
-      "ontext.ContextId\032\022.context.SliceList\"\000\022." +
-      "\n\010GetSlice\022\020.context.SliceId\032\016.context.S" +
-      "lice\"\000\022.\n\010SetSlice\022\016.context.Slice\032\020.con" +
-      "text.SliceId\"\000\0221\n\013RemoveSlice\022\020.context." +
-      "SliceId\032\016.context.Empty\"\000\0229\n\016GetSliceEve" +
-      "nts\022\016.context.Empty\032\023.context.SliceEvent" +
-      "\"\0000\001\022D\n\021ListConnectionIds\022\022.context.Serv" +
-      "iceId\032\031.context.ConnectionIdList\"\000\022@\n\017Li" +
-      "stConnections\022\022.context.ServiceId\032\027.cont" +
-      "ext.ConnectionList\"\000\022=\n\rGetConnection\022\025." +
-      "context.ConnectionId\032\023.context.Connectio" +
-      "n\"\000\022=\n\rSetConnection\022\023.context.Connectio" +
-      "n\032\025.context.ConnectionId\"\000\022;\n\020RemoveConn" +
-      "ection\022\025.context.ConnectionId\032\016.context." +
-      "Empty\"\000\022C\n\023GetConnectionEvents\022\016.context" +
-      ".Empty\032\030.context.ConnectionEvent\"\0000\001b\006pr" +
-      "oto3"
+      "Device\"\200\001\n\013DeviceEvent\022\035\n\005event\030\001 \001(\0132\016." +
+      "context.Event\022$\n\tdevice_id\030\002 \001(\0132\021.conte" +
+      "xt.DeviceId\022,\n\rdevice_config\030\003 \001(\0132\025.con" +
+      "text.DeviceConfig\"*\n\006LinkId\022 \n\tlink_uuid" +
+      "\030\001 \001(\0132\r.context.Uuid\"X\n\004Link\022 \n\007link_id" +
+      "\030\001 \001(\0132\017.context.LinkId\022.\n\021link_endpoint" +
+      "_ids\030\002 \003(\0132\023.context.EndPointId\"/\n\nLinkI" +
+      "dList\022!\n\010link_ids\030\001 \003(\0132\017.context.LinkId" +
+      "\"(\n\010LinkList\022\034\n\005links\030\001 \003(\0132\r.context.Li" +
+      "nk\"L\n\tLinkEvent\022\035\n\005event\030\001 \001(\0132\016.context" +
+      ".Event\022 \n\007link_id\030\002 \001(\0132\017.context.LinkId" +
+      "\"X\n\tServiceId\022&\n\ncontext_id\030\001 \001(\0132\022.cont" +
+      "ext.ContextId\022#\n\014service_uuid\030\002 \001(\0132\r.co" +
+      "ntext.Uuid\"\315\002\n\007Service\022&\n\nservice_id\030\001 \001" +
+      "(\0132\022.context.ServiceId\022.\n\014service_type\030\002" +
+      " \001(\0162\030.context.ServiceTypeEnum\0221\n\024servic" +
+      "e_endpoint_ids\030\003 \003(\0132\023.context.EndPointI" +
+      "d\0220\n\023service_constraints\030\004 \003(\0132\023.context" +
+      ".Constraint\022.\n\016service_status\030\005 \001(\0132\026.co" +
+      "ntext.ServiceStatus\022.\n\016service_config\030\006 " +
+      "\001(\0132\026.context.ServiceConfig\022%\n\ttimestamp" +
+      "\030\007 \001(\0132\022.context.Timestamp\"C\n\rServiceSta" +
+      "tus\0222\n\016service_status\030\001 \001(\0162\032.context.Se" +
+      "rviceStatusEnum\":\n\rServiceConfig\022)\n\014conf" +
+      "ig_rules\030\001 \003(\0132\023.context.ConfigRule\"8\n\rS" +
+      "erviceIdList\022\'\n\013service_ids\030\001 \003(\0132\022.cont" +
+      "ext.ServiceId\"1\n\013ServiceList\022\"\n\010services" +
+      "\030\001 \003(\0132\020.context.Service\"U\n\014ServiceEvent" +
+      "\022\035\n\005event\030\001 \001(\0132\016.context.Event\022&\n\nservi" +
+      "ce_id\030\002 \001(\0132\022.context.ServiceId\"T\n\007Slice" +
+      "Id\022&\n\ncontext_id\030\001 \001(\0132\022.context.Context" +
+      "Id\022!\n\nslice_uuid\030\002 \001(\0132\r.context.Uuid\"\222\003" +
+      "\n\005Slice\022\"\n\010slice_id\030\001 \001(\0132\020.context.Slic" +
+      "eId\022/\n\022slice_endpoint_ids\030\002 \003(\0132\023.contex" +
+      "t.EndPointId\022.\n\021slice_constraints\030\003 \003(\0132" +
+      "\023.context.Constraint\022-\n\021slice_service_id" +
+      "s\030\004 \003(\0132\022.context.ServiceId\022,\n\022slice_sub" +
+      "slice_ids\030\005 \003(\0132\020.context.SliceId\022*\n\014sli" +
+      "ce_status\030\006 \001(\0132\024.context.SliceStatus\022*\n" +
+      "\014slice_config\030\007 \001(\0132\024.context.SliceConfi" +
+      "g\022(\n\013slice_owner\030\010 \001(\0132\023.context.SliceOw" +
+      "ner\022%\n\ttimestamp\030\t \001(\0132\022.context.Timesta" +
+      "mp\"E\n\nSliceOwner\022!\n\nowner_uuid\030\001 \001(\0132\r.c" +
+      "ontext.Uuid\022\024\n\014owner_string\030\002 \001(\t\"=\n\013Sli" +
+      "ceStatus\022.\n\014slice_status\030\001 \001(\0162\030.context" +
+      ".SliceStatusEnum\"8\n\013SliceConfig\022)\n\014confi" +
+      "g_rules\030\001 \003(\0132\023.context.ConfigRule\"2\n\013Sl" +
+      "iceIdList\022#\n\tslice_ids\030\001 \003(\0132\020.context.S" +
+      "liceId\"+\n\tSliceList\022\036\n\006slices\030\001 \003(\0132\016.co" +
+      "ntext.Slice\"O\n\nSliceEvent\022\035\n\005event\030\001 \001(\013" +
+      "2\016.context.Event\022\"\n\010slice_id\030\002 \001(\0132\020.con" +
+      "text.SliceId\"6\n\014ConnectionId\022&\n\017connecti" +
+      "on_uuid\030\001 \001(\0132\r.context.Uuid\"2\n\025Connecti" +
+      "onSettings_L0\022\031\n\021lsp_symbolic_name\030\001 \001(\t" +
+      "\"\236\001\n\025ConnectionSettings_L2\022\027\n\017src_mac_ad" +
+      "dress\030\001 \001(\t\022\027\n\017dst_mac_address\030\002 \001(\t\022\022\n\n" +
+      "ether_type\030\003 \001(\r\022\017\n\007vlan_id\030\004 \001(\r\022\022\n\nmpl" +
+      "s_label\030\005 \001(\r\022\032\n\022mpls_traffic_class\030\006 \001(" +
+      "\r\"t\n\025ConnectionSettings_L3\022\026\n\016src_ip_add" +
+      "ress\030\001 \001(\t\022\026\n\016dst_ip_address\030\002 \001(\t\022\014\n\004ds" +
+      "cp\030\003 \001(\r\022\020\n\010protocol\030\004 \001(\r\022\013\n\003ttl\030\005 \001(\r\"" +
+      "[\n\025ConnectionSettings_L4\022\020\n\010src_port\030\001 \001" +
+      "(\r\022\020\n\010dst_port\030\002 \001(\r\022\021\n\ttcp_flags\030\003 \001(\r\022" +
+      "\013\n\003ttl\030\004 \001(\r\"\304\001\n\022ConnectionSettings\022*\n\002l" +
+      "0\030\001 \001(\0132\036.context.ConnectionSettings_L0\022" +
+      "*\n\002l2\030\002 \001(\0132\036.context.ConnectionSettings" +
+      "_L2\022*\n\002l3\030\003 \001(\0132\036.context.ConnectionSett" +
+      "ings_L3\022*\n\002l4\030\004 \001(\0132\036.context.Connection" +
+      "Settings_L4\"\363\001\n\nConnection\022,\n\rconnection" +
+      "_id\030\001 \001(\0132\025.context.ConnectionId\022&\n\nserv" +
+      "ice_id\030\002 \001(\0132\022.context.ServiceId\0223\n\026path" +
+      "_hops_endpoint_ids\030\003 \003(\0132\023.context.EndPo" +
+      "intId\022+\n\017sub_service_ids\030\004 \003(\0132\022.context" +
+      ".ServiceId\022-\n\010settings\030\005 \001(\0132\033.context.C" +
+      "onnectionSettings\"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\"\264\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\022,\n\021endpoi" +
+      "nt_location\030\004 \001(\0132\021.context.Location\"A\n\021" +
+      "ConfigRule_Custom\022\024\n\014resource_key\030\001 \001(\t\022" +
+      "\026\n\016resource_value\030\002 \001(\t\"]\n\016ConfigRule_AC" +
+      "L\022(\n\013endpoint_id\030\001 \001(\0132\023.context.EndPoin" +
+      "tId\022!\n\010rule_set\030\002 \001(\0132\017.acl.AclRuleSet\"\234" +
+      "\001\n\nConfigRule\022)\n\006action\030\001 \001(\0162\031.context." +
+      "ConfigActionEnum\022,\n\006custom\030\002 \001(\0132\032.conte" +
+      "xt.ConfigRule_CustomH\000\022&\n\003acl\030\003 \001(\0132\027.co" +
+      "ntext.ConfigRule_ACLH\000B\r\n\013config_rule\"F\n" +
+      "\021Constraint_Custom\022\027\n\017constraint_type\030\001 " +
+      "\001(\t\022\030\n\020constraint_value\030\002 \001(\t\"E\n\023Constra" +
+      "int_Schedule\022\027\n\017start_timestamp\030\001 \001(\002\022\025\n" +
+      "\rduration_days\030\002 \001(\002\"3\n\014GPS_Position\022\020\n\010" +
+      "latitude\030\001 \001(\002\022\021\n\tlongitude\030\002 \001(\002\"W\n\010Loc" +
+      "ation\022\020\n\006region\030\001 \001(\tH\000\022-\n\014gps_position\030" +
+      "\002 \001(\0132\025.context.GPS_PositionH\000B\n\n\010locati" +
+      "on\"l\n\033Constraint_EndPointLocation\022(\n\013end" +
+      "point_id\030\001 \001(\0132\023.context.EndPointId\022#\n\010l" +
+      "ocation\030\002 \001(\0132\021.context.Location\"Y\n\033Cons" +
+      "traint_EndPointPriority\022(\n\013endpoint_id\030\001" +
+      " \001(\0132\023.context.EndPointId\022\020\n\010priority\030\002 " +
+      "\001(\r\"0\n\026Constraint_SLA_Latency\022\026\n\016e2e_lat" +
+      "ency_ms\030\001 \001(\002\"0\n\027Constraint_SLA_Capacity" +
+      "\022\025\n\rcapacity_gbps\030\001 \001(\002\"M\n\033Constraint_SL" +
+      "A_Availability\022\032\n\022num_disjoint_paths\030\001 \001" +
+      "(\r\022\022\n\nall_active\030\002 \001(\010\"V\n\036Constraint_SLA" +
+      "_Isolation_level\0224\n\017isolation_level\030\001 \003(" +
+      "\0162\033.context.IsolationLevelEnum\"\366\003\n\nConst" +
+      "raint\022,\n\006custom\030\001 \001(\0132\032.context.Constrai" +
+      "nt_CustomH\000\0220\n\010schedule\030\002 \001(\0132\034.context." +
+      "Constraint_ScheduleH\000\022A\n\021endpoint_locati" +
+      "on\030\003 \001(\0132$.context.Constraint_EndPointLo" +
+      "cationH\000\022A\n\021endpoint_priority\030\004 \001(\0132$.co" +
+      "ntext.Constraint_EndPointPriorityH\000\0228\n\014s" +
+      "la_capacity\030\005 \001(\0132 .context.Constraint_S" +
+      "LA_CapacityH\000\0226\n\013sla_latency\030\006 \001(\0132\037.con" +
+      "text.Constraint_SLA_LatencyH\000\022@\n\020sla_ava" +
+      "ilability\030\007 \001(\0132$.context.Constraint_SLA" +
+      "_AvailabilityH\000\022@\n\rsla_isolation\030\010 \001(\0132\'" +
+      ".context.Constraint_SLA_Isolation_levelH" +
+      "\000B\014\n\nconstraint\"^\n\022TeraFlowController\022&\n" +
+      "\ncontext_id\030\001 \001(\0132\022.context.ContextId\022\022\n" +
+      "\nip_address\030\002 \001(\t\022\014\n\004port\030\003 \001(\r\"U\n\024Authe" +
+      "nticationResult\022&\n\ncontext_id\030\001 \001(\0132\022.co" +
+      "ntext.ContextId\022\025\n\rauthenticated\030\002 \001(\010*j" +
+      "\n\rEventTypeEnum\022\027\n\023EVENTTYPE_UNDEFINED\020\000" +
+      "\022\024\n\020EVENTTYPE_CREATE\020\001\022\024\n\020EVENTTYPE_UPDA" +
+      "TE\020\002\022\024\n\020EVENTTYPE_REMOVE\020\003*\332\001\n\020DeviceDri" +
+      "verEnum\022\032\n\026DEVICEDRIVER_UNDEFINED\020\000\022\033\n\027D" +
+      "EVICEDRIVER_OPENCONFIG\020\001\022\036\n\032DEVICEDRIVER" +
+      "_TRANSPORT_API\020\002\022\023\n\017DEVICEDRIVER_P4\020\003\022&\n" +
+      "\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\020\004\022\033\n" +
+      "\027DEVICEDRIVER_ONF_TR_352\020\005\022\023\n\017DEVICEDRIV" +
+      "ER_XR\020\006*\217\001\n\033DeviceOperationalStatusEnum\022" +
+      "%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\020\000\022$" +
+      "\n DEVICEOPERATIONALSTATUS_DISABLED\020\001\022#\n\037" +
+      "DEVICEOPERATIONALSTATUS_ENABLED\020\002*\201\001\n\017Se" +
+      "rviceTypeEnum\022\027\n\023SERVICETYPE_UNKNOWN\020\000\022\024" +
+      "\n\020SERVICETYPE_L3NM\020\001\022\024\n\020SERVICETYPE_L2NM" +
+      "\020\002\022)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERV" +
+      "ICE\020\003*\250\001\n\021ServiceStatusEnum\022\033\n\027SERVICEST" +
+      "ATUS_UNDEFINED\020\000\022\031\n\025SERVICESTATUS_PLANNE" +
+      "D\020\001\022\030\n\024SERVICESTATUS_ACTIVE\020\002\022!\n\035SERVICE" +
+      "STATUS_PENDING_REMOVAL\020\003\022\036\n\032SERVICESTATU" +
+      "S_SLA_VIOLATED\020\004*\251\001\n\017SliceStatusEnum\022\031\n\025" +
+      "SLICESTATUS_UNDEFINED\020\000\022\027\n\023SLICESTATUS_P" +
+      "LANNED\020\001\022\024\n\020SLICESTATUS_INIT\020\002\022\026\n\022SLICES" +
+      "TATUS_ACTIVE\020\003\022\026\n\022SLICESTATUS_DEINIT\020\004\022\034" +
+      "\n\030SLICESTATUS_SLA_VIOLATED\020\005*]\n\020ConfigAc" +
+      "tionEnum\022\032\n\026CONFIGACTION_UNDEFINED\020\000\022\024\n\020" +
+      "CONFIGACTION_SET\020\001\022\027\n\023CONFIGACTION_DELET" +
+      "E\020\002*\203\002\n\022IsolationLevelEnum\022\020\n\014NO_ISOLATI" +
+      "ON\020\000\022\026\n\022PHYSICAL_ISOLATION\020\001\022\025\n\021LOGICAL_" +
+      "ISOLATION\020\002\022\025\n\021PROCESS_ISOLATION\020\003\022\035\n\031PH" +
+      "YSICAL_MEMORY_ISOLATION\020\004\022\036\n\032PHYSICAL_NE" +
+      "TWORK_ISOLATION\020\005\022\036\n\032VIRTUAL_RESOURCE_IS" +
+      "OLATION\020\006\022\037\n\033NETWORK_FUNCTIONS_ISOLATION" +
+      "\020\007\022\025\n\021SERVICE_ISOLATION\020\0102\331\023\n\016ContextSer" +
+      "vice\022:\n\016ListContextIds\022\016.context.Empty\032\026" +
+      ".context.ContextIdList\"\000\0226\n\014ListContexts" +
+      "\022\016.context.Empty\032\024.context.ContextList\"\000" +
+      "\0224\n\nGetContext\022\022.context.ContextId\032\020.con" +
+      "text.Context\"\000\0224\n\nSetContext\022\020.context.C" +
+      "ontext\032\022.context.ContextId\"\000\0225\n\rRemoveCo" +
+      "ntext\022\022.context.ContextId\032\016.context.Empt" +
+      "y\"\000\022=\n\020GetContextEvents\022\016.context.Empty\032" +
+      "\025.context.ContextEvent\"\0000\001\022@\n\017ListTopolo" +
+      "gyIds\022\022.context.ContextId\032\027.context.Topo" +
+      "logyIdList\"\000\022=\n\016ListTopologies\022\022.context" +
+      ".ContextId\032\025.context.TopologyList\"\000\0227\n\013G" +
+      "etTopology\022\023.context.TopologyId\032\021.contex" +
+      "t.Topology\"\000\0227\n\013SetTopology\022\021.context.To" +
+      "pology\032\023.context.TopologyId\"\000\0227\n\016RemoveT" +
+      "opology\022\023.context.TopologyId\032\016.context.E" +
+      "mpty\"\000\022?\n\021GetTopologyEvents\022\016.context.Em" +
+      "pty\032\026.context.TopologyEvent\"\0000\001\0228\n\rListD" +
+      "eviceIds\022\016.context.Empty\032\025.context.Devic" +
+      "eIdList\"\000\0224\n\013ListDevices\022\016.context.Empty" +
+      "\032\023.context.DeviceList\"\000\0221\n\tGetDevice\022\021.c" +
+      "ontext.DeviceId\032\017.context.Device\"\000\0221\n\tSe" +
+      "tDevice\022\017.context.Device\032\021.context.Devic" +
+      "eId\"\000\0223\n\014RemoveDevice\022\021.context.DeviceId" +
+      "\032\016.context.Empty\"\000\022;\n\017GetDeviceEvents\022\016." +
+      "context.Empty\032\024.context.DeviceEvent\"\0000\001\022" +
+      "4\n\013ListLinkIds\022\016.context.Empty\032\023.context" +
+      ".LinkIdList\"\000\0220\n\tListLinks\022\016.context.Emp" +
+      "ty\032\021.context.LinkList\"\000\022+\n\007GetLink\022\017.con" +
+      "text.LinkId\032\r.context.Link\"\000\022+\n\007SetLink\022" +
+      "\r.context.Link\032\017.context.LinkId\"\000\022/\n\nRem" +
+      "oveLink\022\017.context.LinkId\032\016.context.Empty" +
+      "\"\000\0227\n\rGetLinkEvents\022\016.context.Empty\032\022.co" +
+      "ntext.LinkEvent\"\0000\001\022>\n\016ListServiceIds\022\022." +
+      "context.ContextId\032\026.context.ServiceIdLis" +
+      "t\"\000\022:\n\014ListServices\022\022.context.ContextId\032" +
+      "\024.context.ServiceList\"\000\0224\n\nGetService\022\022." +
+      "context.ServiceId\032\020.context.Service\"\000\0224\n" +
+      "\nSetService\022\020.context.Service\032\022.context." +
+      "ServiceId\"\000\0226\n\014UnsetService\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\022:\n\014ListSliceId" +
+      "s\022\022.context.ContextId\032\024.context.SliceIdL" +
+      "ist\"\000\0226\n\nListSlices\022\022.context.ContextId\032" +
+      "\022.context.SliceList\"\000\022.\n\010GetSlice\022\020.cont" +
+      "ext.SliceId\032\016.context.Slice\"\000\022.\n\010SetSlic" +
+      "e\022\016.context.Slice\032\020.context.SliceId\"\000\0220\n" +
+      "\nUnsetSlice\022\016.context.Slice\032\020.context.Sl" +
+      "iceId\"\000\0221\n\013RemoveSlice\022\020.context.SliceId" +
+      "\032\016.context.Empty\"\000\0229\n\016GetSliceEvents\022\016.c" +
+      "ontext.Empty\032\023.context.SliceEvent\"\0000\001\022D\n" +
+      "\021ListConnectionIds\022\022.context.ServiceId\032\031" +
+      ".context.ConnectionIdList\"\000\022@\n\017ListConne" +
+      "ctions\022\022.context.ServiceId\032\027.context.Con" +
+      "nectionList\"\000\022=\n\rGetConnection\022\025.context" +
+      ".ConnectionId\032\023.context.Connection\"\000\022=\n\r" +
+      "SetConnection\022\023.context.Connection\032\025.con" +
+      "text.ConnectionId\"\000\022;\n\020RemoveConnection\022" +
+      "\025.context.ConnectionId\032\016.context.Empty\"\000" +
+      "\022C\n\023GetConnectionEvents\022\016.context.Empty\032" +
+      "\030.context.ConnectionEvent\"\0000\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -62341,7 +62547,7 @@ public final class ContextOuterClass {
     internal_static_context_DeviceEvent_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_DeviceEvent_descriptor,
-        new java.lang.String[] { "Event", "DeviceId", });
+        new java.lang.String[] { "Event", "DeviceId", "DeviceConfig", });
     internal_static_context_LinkId_descriptor =
       getDescriptor().getMessageTypes().get(20);
     internal_static_context_LinkId_fieldAccessorTable = new
diff --git a/src/policy/target/generated-sources/grpc/context/ContextService.java b/src/policy/target/generated-sources/grpc/context/ContextService.java
index d54c56057ca53e40071490d3b9aa313a13a77665..814ea98b65370f8fd3ffd752c77bec04997a5dd6 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextService.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextService.java
@@ -56,6 +56,8 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> setService(context.ContextOuterClass.Service request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request);
+    
     io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request);
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request);
@@ -66,6 +68,8 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(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);
diff --git a/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java b/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java
index f552294b8e6d645af41cc30632ae0432504bbc67..2b0099f106265e34d1f60bb3e0ecdc35f81895ee 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java
@@ -208,6 +208,14 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+       try {
+         return delegate.unsetService(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
        try {
          return delegate.removeService(request);
@@ -248,6 +256,14 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
+       try {
+         return delegate.unsetSlice(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);
diff --git a/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java b/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java
index c6493bd4d381967238e5eb87dd717f679d028526..c518a0b4622522728e0eb22fdbeb80442b10f7ef 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java
@@ -117,6 +117,10 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.setService(request);
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+       return stub.unsetService(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
        return stub.removeService(request);
     }
@@ -137,6 +141,10 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.setSlice(request);
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
+       return stub.unsetSlice(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
        return stub.removeSlice(request);
     }
diff --git a/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java b/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java
index be720c127439e50f68c2518332f85f750d6579ee..f59378086c84d0776cc25fb7aa9640403b072c0f 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java
@@ -882,6 +882,37 @@ public final class ContextServiceGrpc {
     return getSetServiceMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
+      context.ContextOuterClass.ServiceId> getUnsetServiceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "UnsetService",
+      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> getUnsetServiceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId> getUnsetServiceMethod;
+    if ((getUnsetServiceMethod = ContextServiceGrpc.getUnsetServiceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getUnsetServiceMethod = ContextServiceGrpc.getUnsetServiceMethod) == null) {
+          ContextServiceGrpc.getUnsetServiceMethod = getUnsetServiceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "UnsetService"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Service.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ServiceId.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("UnsetService"))
+              .build();
+        }
+      }
+    }
+    return getUnsetServiceMethod;
+  }
+
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
       context.ContextOuterClass.Empty> getRemoveServiceMethod;
 
@@ -1068,6 +1099,37 @@ public final class ContextServiceGrpc {
     return getSetSliceMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
+      context.ContextOuterClass.SliceId> getUnsetSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "UnsetSlice",
+      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> getUnsetSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId> getUnsetSliceMethod;
+    if ((getUnsetSliceMethod = ContextServiceGrpc.getUnsetSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getUnsetSliceMethod = ContextServiceGrpc.getUnsetSliceMethod) == null) {
+          ContextServiceGrpc.getUnsetSliceMethod = getUnsetSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "UnsetSlice"))
+              .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("UnsetSlice"))
+              .build();
+        }
+      }
+    }
+    return getUnsetSliceMethod;
+  }
+
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
       context.ContextOuterClass.Empty> getRemoveSliceMethod;
 
@@ -1560,6 +1622,13 @@ public final class ContextServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetServiceMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void unsetService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsetServiceMethod(), responseObserver);
+    }
+
     /**
      */
     public void removeService(context.ContextOuterClass.ServiceId request,
@@ -1602,6 +1671,13 @@ public final class ContextServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetSliceMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void unsetSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsetSliceMethod(), responseObserver);
+    }
+
     /**
      */
     public void removeSlice(context.ContextOuterClass.SliceId request,
@@ -1856,6 +1932,13 @@ public final class ContextServiceGrpc {
                 context.ContextOuterClass.Service,
                 context.ContextOuterClass.ServiceId>(
                   this, METHODID_SET_SERVICE)))
+          .addMethod(
+            getUnsetServiceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Service,
+                context.ContextOuterClass.ServiceId>(
+                  this, METHODID_UNSET_SERVICE)))
           .addMethod(
             getRemoveServiceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -1898,6 +1981,13 @@ public final class ContextServiceGrpc {
                 context.ContextOuterClass.Slice,
                 context.ContextOuterClass.SliceId>(
                   this, METHODID_SET_SLICE)))
+          .addMethod(
+            getUnsetSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Slice,
+                context.ContextOuterClass.SliceId>(
+                  this, METHODID_UNSET_SLICE)))
           .addMethod(
             getRemoveSliceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -2196,6 +2286,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetServiceMethod(), getCallOptions()), request, responseObserver);
     }
 
+    /**
+     */
+    public void unsetService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getUnsetServiceMethod(), getCallOptions()), request, responseObserver);
+    }
+
     /**
      */
     public void removeService(context.ContextOuterClass.ServiceId request,
@@ -2244,6 +2342,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetSliceMethod(), getCallOptions()), request, responseObserver);
     }
 
+    /**
+     */
+    public void unsetSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getUnsetSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
     /**
      */
     public void removeSlice(context.ContextOuterClass.SliceId request,
@@ -2523,6 +2629,13 @@ public final class ContextServiceGrpc {
           getChannel(), getSetServiceMethod(), getCallOptions(), request);
     }
 
+    /**
+     */
+    public context.ContextOuterClass.ServiceId unsetService(context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getUnsetServiceMethod(), getCallOptions(), request);
+    }
+
     /**
      */
     public context.ContextOuterClass.Empty removeService(context.ContextOuterClass.ServiceId request) {
@@ -2566,6 +2679,13 @@ public final class ContextServiceGrpc {
           getChannel(), getSetSliceMethod(), getCallOptions(), request);
     }
 
+    /**
+     */
+    public context.ContextOuterClass.SliceId unsetSlice(context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getUnsetSliceMethod(), getCallOptions(), request);
+    }
+
     /**
      */
     public context.ContextOuterClass.Empty removeSlice(context.ContextOuterClass.SliceId request) {
@@ -2831,6 +2951,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetServiceMethod(), getCallOptions()), request);
     }
 
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ServiceId> unsetService(
+        context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getUnsetServiceMethod(), getCallOptions()), request);
+    }
+
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeService(
@@ -2871,6 +2999,14 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getSetSliceMethod(), getCallOptions()), request);
     }
 
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceId> unsetSlice(
+        context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getUnsetSliceMethod(), getCallOptions()), request);
+    }
+
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeSlice(
@@ -2948,20 +3084,22 @@ public final class ContextServiceGrpc {
   private static final int METHODID_LIST_SERVICES = 25;
   private static final int METHODID_GET_SERVICE = 26;
   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_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 int METHODID_UNSET_SERVICE = 28;
+  private static final int METHODID_REMOVE_SERVICE = 29;
+  private static final int METHODID_GET_SERVICE_EVENTS = 30;
+  private static final int METHODID_LIST_SLICE_IDS = 31;
+  private static final int METHODID_LIST_SLICES = 32;
+  private static final int METHODID_GET_SLICE = 33;
+  private static final int METHODID_SET_SLICE = 34;
+  private static final int METHODID_UNSET_SLICE = 35;
+  private static final int METHODID_REMOVE_SLICE = 36;
+  private static final int METHODID_GET_SLICE_EVENTS = 37;
+  private static final int METHODID_LIST_CONNECTION_IDS = 38;
+  private static final int METHODID_LIST_CONNECTIONS = 39;
+  private static final int METHODID_GET_CONNECTION = 40;
+  private static final int METHODID_SET_CONNECTION = 41;
+  private static final int METHODID_REMOVE_CONNECTION = 42;
+  private static final int METHODID_GET_CONNECTION_EVENTS = 43;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -3092,6 +3230,10 @@ public final class ContextServiceGrpc {
           serviceImpl.setService((context.ContextOuterClass.Service) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
           break;
+        case METHODID_UNSET_SERVICE:
+          serviceImpl.unsetService((context.ContextOuterClass.Service) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
+          break;
         case METHODID_REMOVE_SERVICE:
           serviceImpl.removeService((context.ContextOuterClass.ServiceId) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
@@ -3116,6 +3258,10 @@ public final class ContextServiceGrpc {
           serviceImpl.setSlice((context.ContextOuterClass.Slice) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver);
           break;
+        case METHODID_UNSET_SLICE:
+          serviceImpl.unsetSlice((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);
@@ -3237,12 +3383,14 @@ public final class ContextServiceGrpc {
               .addMethod(getListServicesMethod())
               .addMethod(getGetServiceMethod())
               .addMethod(getSetServiceMethod())
+              .addMethod(getUnsetServiceMethod())
               .addMethod(getRemoveServiceMethod())
               .addMethod(getGetServiceEventsMethod())
               .addMethod(getListSliceIdsMethod())
               .addMethod(getListSlicesMethod())
               .addMethod(getGetSliceMethod())
               .addMethod(getSetSliceMethod())
+              .addMethod(getUnsetSliceMethod())
               .addMethod(getRemoveSliceMethod())
               .addMethod(getGetSliceEventsMethod())
               .addMethod(getListConnectionIdsMethod())
diff --git a/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java b/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
index 9f71b53786e40922546dc59cfd4328040a40bd7c..f7d2cb94e339366b54355c7e11b3ee72fa1e415c 100644
--- a/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
@@ -156,6 +156,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::unsetService);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeService);
         }
@@ -181,6 +186,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(context.ContextOuterClass.Slice request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::unsetSlice);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeSlice);
         }
@@ -383,6 +393,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> unsetService(context.ContextOuterClass.Service request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
@@ -408,6 +423,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> unsetSlice(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);
         }
@@ -670,6 +690,13 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                                             context.ContextOuterClass.Service,
                                             context.ContextOuterClass.ServiceId>(
                                             this, METHODID_SET_SERVICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getUnsetServiceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Service,
+                                            context.ContextOuterClass.ServiceId>(
+                                            this, METHODID_UNSET_SERVICE, compression)))
                     .addMethod(
                             context.ContextServiceGrpc.getRemoveServiceMethod(),
                             asyncUnaryCall(
@@ -712,6 +739,13 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                                             context.ContextOuterClass.Slice,
                                             context.ContextOuterClass.SliceId>(
                                             this, METHODID_SET_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getUnsetSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Slice,
+                                            context.ContextOuterClass.SliceId>(
+                                            this, METHODID_UNSET_SLICE, compression)))
                     .addMethod(
                             context.ContextServiceGrpc.getRemoveSliceMethod(),
                             asyncUnaryCall(
@@ -800,20 +834,22 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
     private static final int METHODID_LIST_SERVICES = 25;
     private static final int METHODID_GET_SERVICE = 26;
     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_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 int METHODID_UNSET_SERVICE = 28;
+    private static final int METHODID_REMOVE_SERVICE = 29;
+    private static final int METHODID_GET_SERVICE_EVENTS = 30;
+    private static final int METHODID_LIST_SLICE_IDS = 31;
+    private static final int METHODID_LIST_SLICES = 32;
+    private static final int METHODID_GET_SLICE = 33;
+    private static final int METHODID_SET_SLICE = 34;
+    private static final int METHODID_UNSET_SLICE = 35;
+    private static final int METHODID_REMOVE_SLICE = 36;
+    private static final int METHODID_GET_SLICE_EVENTS = 37;
+    private static final int METHODID_LIST_CONNECTION_IDS = 38;
+    private static final int METHODID_LIST_CONNECTIONS = 39;
+    private static final int METHODID_GET_CONNECTION = 40;
+    private static final int METHODID_SET_CONNECTION = 41;
+    private static final int METHODID_REMOVE_CONNECTION = 42;
+    private static final int METHODID_GET_CONNECTION_EVENTS = 43;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -1002,6 +1038,12 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                             compression,
                             serviceImpl::setService);
                     break;
+                case METHODID_UNSET_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Service) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver,
+                            compression,
+                            serviceImpl::unsetService);
+                    break;
                 case METHODID_REMOVE_SERVICE:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
@@ -1038,6 +1080,12 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                             compression,
                             serviceImpl::setSlice);
                     break;
+                case METHODID_UNSET_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Slice) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver,
+                            compression,
+                            serviceImpl::unsetSlice);
+                    break;
                 case METHODID_REMOVE_SLICE:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
diff --git a/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java b/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java
index 5d63d4aa45e578957a7a3414c33491cebe98acbe..9d05f3da8a831e74922e65473206539680c8d78b 100644
--- a/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java
+++ b/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java
@@ -19,85 +19,124 @@ public final class Monitoring {
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>string kpi_description = 1;</code>
+     * <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 kpi_description = 2;</code>
      * @return The kpiDescription.
      */
     java.lang.String getKpiDescription();
     /**
-     * <code>string kpi_description = 1;</code>
+     * <code>string kpi_description = 2;</code>
      * @return The bytes for kpiDescription.
      */
     com.google.protobuf.ByteString
         getKpiDescriptionBytes();
 
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiId> 
+        getKpiIdListList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    monitoring.Monitoring.KpiId getKpiIdList(int index);
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    int getKpiIdListCount();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdListOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+        int index);
+
+    /**
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
      * @return The enum numeric value on the wire for kpiSampleType.
      */
     int getKpiSampleTypeValue();
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
      * @return The kpiSampleType.
      */
     kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
 
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return Whether the deviceId field is set.
      */
     boolean hasDeviceId();
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return The deviceId.
      */
     context.ContextOuterClass.DeviceId getDeviceId();
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      */
     context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
 
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return Whether the endpointId field is set.
      */
     boolean hasEndpointId();
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return The endpointId.
      */
     context.ContextOuterClass.EndPointId getEndpointId();
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      */
     context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
 
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return Whether the serviceId field is set.
      */
     boolean hasServiceId();
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return The serviceId.
      */
     context.ContextOuterClass.ServiceId getServiceId();
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      */
     context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
 
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return Whether the sliceId field is set.
      */
     boolean hasSliceId();
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return The sliceId.
      */
     context.ContextOuterClass.SliceId getSliceId();
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      */
     context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
   }
@@ -115,6 +154,7 @@ public final class Monitoring {
     }
     private KpiDescriptor() {
       kpiDescription_ = "";
+      kpiIdList_ = java.util.Collections.emptyList();
       kpiSampleType_ = 0;
     }
 
@@ -138,6 +178,7 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -149,18 +190,40 @@ public final class Monitoring {
               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();
 
               kpiDescription_ = s;
               break;
             }
-            case 16: {
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              kpiIdList_.add(
+                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
+              break;
+            }
+            case 32: {
               int rawValue = input.readEnum();
 
               kpiSampleType_ = rawValue;
               break;
             }
-            case 26: {
+            case 42: {
               context.ContextOuterClass.DeviceId.Builder subBuilder = null;
               if (deviceId_ != null) {
                 subBuilder = deviceId_.toBuilder();
@@ -173,7 +236,7 @@ public final class Monitoring {
 
               break;
             }
-            case 34: {
+            case 50: {
               context.ContextOuterClass.EndPointId.Builder subBuilder = null;
               if (endpointId_ != null) {
                 subBuilder = endpointId_.toBuilder();
@@ -186,7 +249,7 @@ public final class Monitoring {
 
               break;
             }
-            case 42: {
+            case 58: {
               context.ContextOuterClass.ServiceId.Builder subBuilder = null;
               if (serviceId_ != null) {
                 subBuilder = serviceId_.toBuilder();
@@ -199,7 +262,7 @@ public final class Monitoring {
 
               break;
             }
-            case 50: {
+            case 66: {
               context.ContextOuterClass.SliceId.Builder subBuilder = null;
               if (sliceId_ != null) {
                 subBuilder = sliceId_.toBuilder();
@@ -227,6 +290,9 @@ public final class Monitoring {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
@@ -244,10 +310,36 @@ public final class Monitoring {
               monitoring.Monitoring.KpiDescriptor.class, monitoring.Monitoring.KpiDescriptor.Builder.class);
     }
 
-    public static final int KPI_DESCRIPTION_FIELD_NUMBER = 1;
+    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 KPI_DESCRIPTION_FIELD_NUMBER = 2;
     private volatile java.lang.Object kpiDescription_;
     /**
-     * <code>string kpi_description = 1;</code>
+     * <code>string kpi_description = 2;</code>
      * @return The kpiDescription.
      */
     @java.lang.Override
@@ -264,7 +356,7 @@ public final class Monitoring {
       }
     }
     /**
-     * <code>string kpi_description = 1;</code>
+     * <code>string kpi_description = 2;</code>
      * @return The bytes for kpiDescription.
      */
     @java.lang.Override
@@ -282,17 +374,57 @@ public final class Monitoring {
       }
     }
 
-    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 2;
+    public static final int KPI_ID_LIST_FIELD_NUMBER = 3;
+    private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_;
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
+      return kpiIdList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdListOrBuilderList() {
+      return kpiIdList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public int getKpiIdListCount() {
+      return kpiIdList_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiIdList(int index) {
+      return kpiIdList_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+        int index) {
+      return kpiIdList_.get(index);
+    }
+
+    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 4;
     private int kpiSampleType_;
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</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>
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
      * @return The kpiSampleType.
      */
     @java.lang.Override public kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType() {
@@ -301,10 +433,10 @@ public final class Monitoring {
       return result == null ? kpi_sample_types.KpiSampleTypes.KpiSampleType.UNRECOGNIZED : result;
     }
 
-    public static final int DEVICE_ID_FIELD_NUMBER = 3;
+    public static final int DEVICE_ID_FIELD_NUMBER = 5;
     private context.ContextOuterClass.DeviceId deviceId_;
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return Whether the deviceId field is set.
      */
     @java.lang.Override
@@ -312,7 +444,7 @@ public final class Monitoring {
       return deviceId_ != null;
     }
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      * @return The deviceId.
      */
     @java.lang.Override
@@ -320,17 +452,17 @@ public final class Monitoring {
       return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
     }
     /**
-     * <code>.context.DeviceId device_id = 3;</code>
+     * <code>.context.DeviceId device_id = 5;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
       return getDeviceId();
     }
 
-    public static final int ENDPOINT_ID_FIELD_NUMBER = 4;
+    public static final int ENDPOINT_ID_FIELD_NUMBER = 6;
     private context.ContextOuterClass.EndPointId endpointId_;
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return Whether the endpointId field is set.
      */
     @java.lang.Override
@@ -338,7 +470,7 @@ public final class Monitoring {
       return endpointId_ != null;
     }
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      * @return The endpointId.
      */
     @java.lang.Override
@@ -346,17 +478,17 @@ public final class Monitoring {
       return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
     }
     /**
-     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * <code>.context.EndPointId endpoint_id = 6;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
       return getEndpointId();
     }
 
-    public static final int SERVICE_ID_FIELD_NUMBER = 5;
+    public static final int SERVICE_ID_FIELD_NUMBER = 7;
     private context.ContextOuterClass.ServiceId serviceId_;
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return Whether the serviceId field is set.
      */
     @java.lang.Override
@@ -364,7 +496,7 @@ public final class Monitoring {
       return serviceId_ != null;
     }
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      * @return The serviceId.
      */
     @java.lang.Override
@@ -372,17 +504,17 @@ public final class Monitoring {
       return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
     }
     /**
-     * <code>.context.ServiceId service_id = 5;</code>
+     * <code>.context.ServiceId service_id = 7;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
       return getServiceId();
     }
 
-    public static final int SLICE_ID_FIELD_NUMBER = 6;
+    public static final int SLICE_ID_FIELD_NUMBER = 8;
     private context.ContextOuterClass.SliceId sliceId_;
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return Whether the sliceId field is set.
      */
     @java.lang.Override
@@ -390,7 +522,7 @@ public final class Monitoring {
       return sliceId_ != null;
     }
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      * @return The sliceId.
      */
     @java.lang.Override
@@ -398,7 +530,7 @@ public final class Monitoring {
       return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
     }
     /**
-     * <code>.context.SliceId slice_id = 6;</code>
+     * <code>.context.SliceId slice_id = 8;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
@@ -419,23 +551,29 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
+      }
       if (!getKpiDescriptionBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, kpiDescription_);
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, kpiDescription_);
+      }
+      for (int i = 0; i < kpiIdList_.size(); i++) {
+        output.writeMessage(3, kpiIdList_.get(i));
       }
       if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        output.writeEnum(2, kpiSampleType_);
+        output.writeEnum(4, kpiSampleType_);
       }
       if (deviceId_ != null) {
-        output.writeMessage(3, getDeviceId());
+        output.writeMessage(5, getDeviceId());
       }
       if (endpointId_ != null) {
-        output.writeMessage(4, getEndpointId());
+        output.writeMessage(6, getEndpointId());
       }
       if (serviceId_ != null) {
-        output.writeMessage(5, getServiceId());
+        output.writeMessage(7, getServiceId());
       }
       if (sliceId_ != null) {
-        output.writeMessage(6, getSliceId());
+        output.writeMessage(8, getSliceId());
       }
       unknownFields.writeTo(output);
     }
@@ -446,28 +584,36 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
+      }
       if (!getKpiDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, kpiDescription_);
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, kpiDescription_);
+      }
+      for (int i = 0; i < kpiIdList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, kpiIdList_.get(i));
       }
       if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(2, kpiSampleType_);
+          .computeEnumSize(4, kpiSampleType_);
       }
       if (deviceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getDeviceId());
+          .computeMessageSize(5, getDeviceId());
       }
       if (endpointId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getEndpointId());
+          .computeMessageSize(6, getEndpointId());
       }
       if (serviceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getServiceId());
+          .computeMessageSize(7, getServiceId());
       }
       if (sliceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, getSliceId());
+          .computeMessageSize(8, getSliceId());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -484,8 +630,15 @@ public final class Monitoring {
       }
       monitoring.Monitoring.KpiDescriptor other = (monitoring.Monitoring.KpiDescriptor) obj;
 
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
+      }
       if (!getKpiDescription()
           .equals(other.getKpiDescription())) return false;
+      if (!getKpiIdListList()
+          .equals(other.getKpiIdListList())) return false;
       if (kpiSampleType_ != other.kpiSampleType_) return false;
       if (hasDeviceId() != other.hasDeviceId()) return false;
       if (hasDeviceId()) {
@@ -518,8 +671,16 @@ public final class Monitoring {
       }
       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) + KPI_DESCRIPTION_FIELD_NUMBER;
       hash = (53 * hash) + getKpiDescription().hashCode();
+      if (getKpiIdListCount() > 0) {
+        hash = (37 * hash) + KPI_ID_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiIdListList().hashCode();
+      }
       hash = (37 * hash) + KPI_SAMPLE_TYPE_FIELD_NUMBER;
       hash = (53 * hash) + kpiSampleType_;
       if (hasDeviceId()) {
@@ -666,13 +827,26 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getKpiIdListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
         kpiDescription_ = "";
 
+        if (kpiIdListBuilder_ == null) {
+          kpiIdList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          kpiIdListBuilder_.clear();
+        }
         kpiSampleType_ = 0;
 
         if (deviceIdBuilder_ == null) {
@@ -725,7 +899,22 @@ public final class Monitoring {
       @java.lang.Override
       public monitoring.Monitoring.KpiDescriptor buildPartial() {
         monitoring.Monitoring.KpiDescriptor result = new monitoring.Monitoring.KpiDescriptor(this);
+        int from_bitField0_ = bitField0_;
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
         result.kpiDescription_ = kpiDescription_;
+        if (kpiIdListBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.kpiIdList_ = kpiIdList_;
+        } else {
+          result.kpiIdList_ = kpiIdListBuilder_.build();
+        }
         result.kpiSampleType_ = kpiSampleType_;
         if (deviceIdBuilder_ == null) {
           result.deviceId_ = deviceId_;
@@ -795,14 +984,43 @@ public final class Monitoring {
 
       public Builder mergeFrom(monitoring.Monitoring.KpiDescriptor other) {
         if (other == monitoring.Monitoring.KpiDescriptor.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
         if (!other.getKpiDescription().isEmpty()) {
           kpiDescription_ = other.kpiDescription_;
           onChanged();
         }
-        if (other.kpiSampleType_ != 0) {
-          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
-        }
-        if (other.hasDeviceId()) {
+        if (kpiIdListBuilder_ == null) {
+          if (!other.kpiIdList_.isEmpty()) {
+            if (kpiIdList_.isEmpty()) {
+              kpiIdList_ = other.kpiIdList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiIdListIsMutable();
+              kpiIdList_.addAll(other.kpiIdList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.kpiIdList_.isEmpty()) {
+            if (kpiIdListBuilder_.isEmpty()) {
+              kpiIdListBuilder_.dispose();
+              kpiIdListBuilder_ = null;
+              kpiIdList_ = other.kpiIdList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiIdListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiIdListFieldBuilder() : null;
+            } else {
+              kpiIdListBuilder_.addAllMessages(other.kpiIdList_);
+            }
+          }
+        }
+        if (other.kpiSampleType_ != 0) {
+          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
+        }
+        if (other.hasDeviceId()) {
           mergeDeviceId(other.getDeviceId());
         }
         if (other.hasEndpointId()) {
@@ -842,10 +1060,130 @@ public final class Monitoring {
         }
         return this;
       }
+      private int bitField0_;
+
+      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 kpiDescription_ = "";
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @return The kpiDescription.
        */
       public java.lang.String getKpiDescription() {
@@ -861,7 +1199,7 @@ public final class Monitoring {
         }
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @return The bytes for kpiDescription.
        */
       public com.google.protobuf.ByteString
@@ -878,7 +1216,7 @@ public final class Monitoring {
         }
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @param value The kpiDescription to set.
        * @return This builder for chaining.
        */
@@ -893,7 +1231,7 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @return This builder for chaining.
        */
       public Builder clearKpiDescription() {
@@ -903,7 +1241,7 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>string kpi_description = 1;</code>
+       * <code>string kpi_description = 2;</code>
        * @param value The bytes for kpiDescription to set.
        * @return This builder for chaining.
        */
@@ -919,548 +1257,788 @@ public final class Monitoring {
         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;
+      private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiIdListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiIdList_);
+          bitField0_ |= 0x00000001;
+         }
       }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdListBuilder_;
+
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
-       * @param value The kpiSampleType to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setKpiSampleType(kpi_sample_types.KpiSampleTypes.KpiSampleType value) {
-        if (value == null) {
-          throw new NullPointerException();
+      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
+        if (kpiIdListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiIdList_);
+        } else {
+          return kpiIdListBuilder_.getMessageList();
         }
-        
-        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.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public boolean hasDeviceId() {
-        return deviceIdBuilder_ != null || deviceId_ != null;
+      public int getKpiIdListCount() {
+        if (kpiIdListBuilder_ == null) {
+          return kpiIdList_.size();
+        } else {
+          return kpiIdListBuilder_.getCount();
+        }
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
-       * @return The deviceId.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.DeviceId getDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+      public monitoring.Monitoring.KpiId getKpiIdList(int index) {
+        if (kpiIdListBuilder_ == null) {
+          return kpiIdList_.get(index);
         } else {
-          return deviceIdBuilder_.getMessage();
+          return kpiIdListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setDeviceId(context.ContextOuterClass.DeviceId value) {
-        if (deviceIdBuilder_ == null) {
+      public Builder setKpiIdList(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          deviceId_ = value;
+          ensureKpiIdListIsMutable();
+          kpiIdList_.set(index, value);
           onChanged();
         } else {
-          deviceIdBuilder_.setMessage(value);
+          kpiIdListBuilder_.setMessage(index, value);
         }
-
         return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setDeviceId(
-          context.ContextOuterClass.DeviceId.Builder builderForValue) {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = builderForValue.build();
+      public Builder setKpiIdList(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          deviceIdBuilder_.setMessage(builderForValue.build());
+          kpiIdListBuilder_.setMessage(index, builderForValue.build());
         }
-
         return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 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;
+      public Builder addKpiIdList(monitoring.Monitoring.KpiId value) {
+        if (kpiIdListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(value);
           onChanged();
         } else {
-          deviceIdBuilder_.mergeFrom(value);
+          kpiIdListBuilder_.addMessage(value);
         }
-
         return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder clearDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = null;
+      public Builder addKpiIdList(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(index, value);
           onChanged();
         } else {
-          deviceId_ = null;
-          deviceIdBuilder_ = null;
+          kpiIdListBuilder_.addMessage(index, value);
         }
-
         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>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
-        if (deviceIdBuilder_ != null) {
-          return deviceIdBuilder_.getMessageOrBuilder();
+      public Builder addKpiIdList(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(builderForValue.build());
+          onChanged();
         } else {
-          return deviceId_ == null ?
-              context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+          kpiIdListBuilder_.addMessage(builderForValue.build());
         }
+        return this;
       }
       /**
-       * <code>.context.DeviceId device_id = 3;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 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;
+      public Builder addKpiIdList(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdListBuilder_.addMessage(index, builderForValue.build());
         }
-        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;
+        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
-       * @return The endpointId.
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.EndPointId getEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+      public Builder addAllKpiIdList(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiIdList_);
+          onChanged();
         } else {
-          return endpointIdBuilder_.getMessage();
+          kpiIdListBuilder_.addAllMessages(values);
         }
+        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
-        if (endpointIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          endpointId_ = value;
+      public Builder clearKpiIdList() {
+        if (kpiIdListBuilder_ == null) {
+          kpiIdList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          endpointIdBuilder_.setMessage(value);
+          kpiIdListBuilder_.clear();
         }
-
         return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder setEndpointId(
-          context.ContextOuterClass.EndPointId.Builder builderForValue) {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = builderForValue.build();
+      public Builder removeKpiIdList(int index) {
+        if (kpiIdListBuilder_ == null) {
+          ensureKpiIdListIsMutable();
+          kpiIdList_.remove(index);
           onChanged();
         } else {
-          endpointIdBuilder_.setMessage(builderForValue.build());
+          kpiIdListBuilder_.remove(index);
         }
-
         return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</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);
+      public monitoring.Monitoring.KpiId.Builder getKpiIdListBuilder(
+          int index) {
+        return getKpiIdListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+          int index) {
+        if (kpiIdListBuilder_ == null) {
+          return kpiIdList_.get(index);  } else {
+          return kpiIdListBuilder_.getMessageOrBuilder(index);
         }
-
-        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public Builder clearEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = null;
-          onChanged();
+      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+           getKpiIdListOrBuilderList() {
+        if (kpiIdListBuilder_ != null) {
+          return kpiIdListBuilder_.getMessageOrBuilderList();
         } else {
-          endpointId_ = null;
-          endpointIdBuilder_ = null;
+          return java.util.Collections.unmodifiableList(kpiIdList_);
         }
-
-        return this;
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
-        
-        onChanged();
-        return getEndpointIdFieldBuilder().getBuilder();
+      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder() {
+        return getKpiIdListFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiId.getDefaultInstance());
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
        */
-      public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
-        if (endpointIdBuilder_ != null) {
-          return endpointIdBuilder_.getMessageOrBuilder();
-        } else {
-          return endpointId_ == null ?
-              context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
-        }
+      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder(
+          int index) {
+        return getKpiIdListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiId.getDefaultInstance());
       }
       /**
-       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</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(),
+      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
+           getKpiIdListBuilderList() {
+        return getKpiIdListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdListFieldBuilder() {
+        if (kpiIdListBuilder_ == null) {
+          kpiIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  kpiIdList_,
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          endpointId_ = null;
+          kpiIdList_ = null;
         }
-        return endpointIdBuilder_;
+        return kpiIdListBuilder_;
       }
 
-      private context.ContextOuterClass.ServiceId serviceId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
+      private int kpiSampleType_ = 0;
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
-       * @return Whether the serviceId field is set.
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
+       * @return The enum numeric value on the wire for kpiSampleType.
        */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
+      @java.lang.Override public int getKpiSampleTypeValue() {
+        return kpiSampleType_;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
-       * @return The serviceId.
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
+       * @param value The enum numeric value on the wire for kpiSampleType to set.
+       * @return This builder for chaining.
        */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
-        }
+      public Builder setKpiSampleTypeValue(int value) {
+        
+        kpiSampleType_ = value;
+        onChanged();
+        return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
+       * @return The kpiSampleType.
        */
-      public Builder setServiceId(context.ContextOuterClass.ServiceId value) {
-        if (serviceIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          serviceId_ = value;
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(value);
-        }
+      @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 = 4;</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 = 4;</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 = 5;</code>
+       * @return Whether the deviceId field is set.
+       */
+      public boolean hasDeviceId() {
+        return deviceIdBuilder_ != null || deviceId_ != null;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 5;</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 = 5;</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.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
+      public Builder setDeviceId(
+          context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = builderForValue.build();
           onChanged();
         } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
+          deviceIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_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();
+      public Builder mergeDeviceId(context.ContextOuterClass.DeviceId value) {
+        if (deviceIdBuilder_ == null) {
+          if (deviceId_ != null) {
+            deviceId_ =
+              context.ContextOuterClass.DeviceId.newBuilder(deviceId_).mergeFrom(value).buildPartial();
           } else {
-            serviceId_ = value;
+            deviceId_ = value;
           }
           onChanged();
         } else {
-          serviceIdBuilder_.mergeFrom(value);
+          deviceIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
+      public Builder clearDeviceId() {
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = null;
           onChanged();
         } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
+          deviceId_ = null;
+          deviceIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
         
         onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
+        return getDeviceIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_id = 5;</code>
        */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
+        if (deviceIdBuilder_ != null) {
+          return deviceIdBuilder_.getMessageOrBuilder();
         } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+          return deviceId_ == null ?
+              context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
         }
       }
       /**
-       * <code>.context.ServiceId service_id = 5;</code>
+       * <code>.context.DeviceId device_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(),
+          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());
-          serviceId_ = null;
+          deviceId_ = null;
         }
-        return serviceIdBuilder_;
+        return deviceIdBuilder_;
       }
 
-      private context.ContextOuterClass.SliceId sliceId_;
+      private context.ContextOuterClass.EndPointId endpointId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdBuilder_;
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> endpointIdBuilder_;
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
-       * @return Whether the sliceId field is set.
+       * <code>.context.EndPointId endpoint_id = 6;</code>
+       * @return Whether the endpointId field is set.
        */
-      public boolean hasSliceId() {
-        return sliceIdBuilder_ != null || sliceId_ != null;
+      public boolean hasEndpointId() {
+        return endpointIdBuilder_ != null || endpointId_ != null;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
-       * @return The sliceId.
+       * <code>.context.EndPointId endpoint_id = 6;</code>
+       * @return The endpointId.
        */
-      public context.ContextOuterClass.SliceId getSliceId() {
-        if (sliceIdBuilder_ == null) {
-          return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+      public context.ContextOuterClass.EndPointId getEndpointId() {
+        if (endpointIdBuilder_ == null) {
+          return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
         } else {
-          return sliceIdBuilder_.getMessage();
+          return endpointIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder setSliceId(context.ContextOuterClass.SliceId value) {
-        if (sliceIdBuilder_ == null) {
+      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
+        if (endpointIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          sliceId_ = value;
+          endpointId_ = value;
           onChanged();
         } else {
-          sliceIdBuilder_.setMessage(value);
+          endpointIdBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder setSliceId(
-          context.ContextOuterClass.SliceId.Builder builderForValue) {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = builderForValue.build();
+      public Builder setEndpointId(
+          context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = builderForValue.build();
           onChanged();
         } else {
-          sliceIdBuilder_.setMessage(builderForValue.build());
+          endpointIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder mergeSliceId(context.ContextOuterClass.SliceId value) {
-        if (sliceIdBuilder_ == null) {
-          if (sliceId_ != null) {
-            sliceId_ =
-              context.ContextOuterClass.SliceId.newBuilder(sliceId_).mergeFrom(value).buildPartial();
+      public Builder mergeEndpointId(context.ContextOuterClass.EndPointId value) {
+        if (endpointIdBuilder_ == null) {
+          if (endpointId_ != null) {
+            endpointId_ =
+              context.ContextOuterClass.EndPointId.newBuilder(endpointId_).mergeFrom(value).buildPartial();
           } else {
-            sliceId_ = value;
+            endpointId_ = value;
           }
           onChanged();
         } else {
-          sliceIdBuilder_.mergeFrom(value);
+          endpointIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public Builder clearSliceId() {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
+      public Builder clearEndpointId() {
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = null;
           onChanged();
         } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
+          endpointId_ = null;
+          endpointIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
         
         onChanged();
-        return getSliceIdFieldBuilder().getBuilder();
+        return getEndpointIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</code>
        */
-      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
-        if (sliceIdBuilder_ != null) {
-          return sliceIdBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
+        if (endpointIdBuilder_ != null) {
+          return endpointIdBuilder_.getMessageOrBuilder();
         } else {
-          return sliceId_ == null ?
-              context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+          return endpointId_ == null ?
+              context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
         }
       }
       /**
-       * <code>.context.SliceId slice_id = 6;</code>
+       * <code>.context.EndPointId endpoint_id = 6;</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(),
+          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());
-          sliceId_ = null;
+          endpointId_ = null;
         }
-        return sliceIdBuilder_;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+        return endpointIdBuilder_;
       }
 
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      private context.ContextOuterClass.ServiceId serviceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       * @return Whether the serviceId field is set.
+       */
+      public boolean hasServiceId() {
+        return serviceIdBuilder_ != null || serviceId_ != null;
       }
-
-
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       * @return The serviceId.
+       */
+      public context.ContextOuterClass.ServiceId getServiceId() {
+        if (serviceIdBuilder_ == null) {
+          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        } else {
+          return serviceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</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;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public Builder setServiceId(
+          context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          serviceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</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;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public Builder clearServiceId() {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
+          onChanged();
+        } else {
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+        
+        onChanged();
+        return getServiceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</code>
+       */
+      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+        if (serviceIdBuilder_ != null) {
+          return serviceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return serviceId_ == null ?
+              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        }
+      }
+      /**
+       * <code>.context.ServiceId service_id = 7;</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_;
+      }
+
+      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 = 8;</code>
+       * @return Whether the sliceId field is set.
+       */
+      public boolean hasSliceId() {
+        return sliceIdBuilder_ != null || sliceId_ != null;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 8;</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 = 8;</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 = 8;</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 = 8;</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 = 8;</code>
+       */
+      public Builder clearSliceId() {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+          onChanged();
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 8;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+        
+        onChanged();
+        return getSliceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceId slice_id = 8;</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 = 8;</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:monitoring.KpiDescriptor)
     }
 
@@ -1501,140 +2079,61 @@ public final class Monitoring {
 
   }
 
-  public interface BundleKpiDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.BundleKpiDescriptor)
+  public interface MonitorKpiRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.MonitorKpiRequest)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>string kpi_description = 1;</code>
-     * @return The kpiDescription.
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
      */
-    java.lang.String getKpiDescription();
+    boolean hasKpiId();
     /**
-     * <code>string kpi_description = 1;</code>
-     * @return The bytes for kpiDescription.
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
      */
-    com.google.protobuf.ByteString
-        getKpiDescriptionBytes();
-
+    monitoring.Monitoring.KpiId getKpiId();
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
-    java.util.List<monitoring.Monitoring.KpiId> 
-        getKpiIdListList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    monitoring.Monitoring.KpiId getKpiIdList(int index);
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    int getKpiIdListCount();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-        int index);
-
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-     * @return The enum numeric value on the wire for kpiSampleType.
-     */
-    int getKpiSampleTypeValue();
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-     * @return The kpiSampleType.
-     */
-    kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
-
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     * @return Whether the deviceId field is set.
-     */
-    boolean hasDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     * @return The deviceId.
-     */
-    context.ContextOuterClass.DeviceId getDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     */
-    context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
-
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     * @return Whether the endpointId field is set.
-     */
-    boolean hasEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     * @return The endpointId.
-     */
-    context.ContextOuterClass.EndPointId getEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     */
-    context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
 
     /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return Whether the serviceId field is set.
-     */
-    boolean hasServiceId();
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return The serviceId.
-     */
-    context.ContextOuterClass.ServiceId getServiceId();
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
-    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+    float getMonitoringWindowS();
 
     /**
-     * <code>.context.SliceId slice_id = 7;</code>
-     * @return Whether the sliceId field is set.
-     */
-    boolean hasSliceId();
-    /**
-     * <code>.context.SliceId slice_id = 7;</code>
-     * @return The sliceId.
-     */
-    context.ContextOuterClass.SliceId getSliceId();
-    /**
-     * <code>.context.SliceId slice_id = 7;</code>
+     * <pre>
+     * Pending add field to reflect Available Device Protocols
+     * </pre>
+     *
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
-    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+    float getSamplingRateS();
   }
   /**
-   * Protobuf type {@code monitoring.BundleKpiDescriptor}
+   * Protobuf type {@code monitoring.MonitorKpiRequest}
    */
-  public static final class BundleKpiDescriptor extends
+  public static final class MonitorKpiRequest extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.BundleKpiDescriptor)
-      BundleKpiDescriptorOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.MonitorKpiRequest)
+      MonitorKpiRequestOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use BundleKpiDescriptor.newBuilder() to construct.
-    private BundleKpiDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use MonitorKpiRequest.newBuilder() to construct.
+    private MonitorKpiRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private BundleKpiDescriptor() {
-      kpiDescription_ = "";
-      kpiIdList_ = java.util.Collections.emptyList();
-      kpiSampleType_ = 0;
+    private MonitorKpiRequest() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new BundleKpiDescriptor();
+      return new MonitorKpiRequest();
     }
 
     @java.lang.Override
@@ -1642,7 +2141,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private BundleKpiDescriptor(
+    private MonitorKpiRequest(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -1650,7 +2149,6 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
-      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -1662,76 +2160,26 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              kpiDescription_ = s;
-              break;
-            }
-            case 18: {
-              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              kpiIdList_.add(
-                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
-              break;
-            }
-            case 24: {
-              int rawValue = input.readEnum();
-
-              kpiSampleType_ = rawValue;
-              break;
-            }
-            case 34: {
-              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 42: {
-              context.ContextOuterClass.EndPointId.Builder subBuilder = null;
-              if (endpointId_ != null) {
-                subBuilder = endpointId_.toBuilder();
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
+              if (kpiId_ != null) {
+                subBuilder = kpiId_.toBuilder();
               }
-              endpointId_ = input.readMessage(context.ContextOuterClass.EndPointId.parser(), extensionRegistry);
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(endpointId_);
-                endpointId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(kpiId_);
+                kpiId_ = subBuilder.buildPartial();
               }
 
               break;
             }
-            case 50: {
-              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();
-              }
+            case 21: {
 
+              monitoringWindowS_ = input.readFloat();
               break;
             }
-            case 58: {
-              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();
-              }
+            case 29: {
 
+              samplingRateS_ = input.readFloat();
               break;
             }
             default: {
@@ -1749,261 +2197,97 @@ public final class Monitoring {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
-        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.BundleKpiDescriptor.class, monitoring.Monitoring.BundleKpiDescriptor.Builder.class);
+              monitoring.Monitoring.MonitorKpiRequest.class, monitoring.Monitoring.MonitorKpiRequest.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;
-      }
-    }
+    public static final int KPI_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiId kpiId_;
     /**
-     * <code>string kpi_description = 1;</code>
-     * @return The bytes for kpiDescription.
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
      */
     @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 boolean hasKpiId() {
+      return kpiId_ != null;
     }
-
-    public static final int KPI_ID_LIST_FIELD_NUMBER = 2;
-    private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_;
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-      return kpiIdList_;
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
     }
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList() {
-      return kpiIdList_;
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
     }
+
+    public static final int MONITORING_WINDOW_S_FIELD_NUMBER = 2;
+    private float monitoringWindowS_;
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
     @java.lang.Override
-    public int getKpiIdListCount() {
-      return kpiIdList_.size();
+    public float getMonitoringWindowS() {
+      return monitoringWindowS_;
     }
+
+    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
+    private float samplingRateS_;
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+     * <pre>
+     * Pending add field to reflect Available Device Protocols
+     * </pre>
+     *
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-      return kpiIdList_.get(index);
+    public float getSamplingRateS() {
+      return samplingRateS_;
     }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-     */
+
+    private byte memoizedIsInitialized = -1;
     @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-        int index) {
-      return kpiIdList_.get(index);
-    }
-
-    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 3;
-    private int kpiSampleType_;
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</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 = 3;</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 = 4;
-    private context.ContextOuterClass.DeviceId deviceId_;
-    /**
-     * <code>.context.DeviceId device_id = 4;</code>
-     * @return Whether the deviceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasDeviceId() {
-      return deviceId_ != null;
-    }
-    /**
-     * <code>.context.DeviceId device_id = 4;</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 = 4;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
-      return getDeviceId();
-    }
-
-    public static final int ENDPOINT_ID_FIELD_NUMBER = 5;
-    private context.ContextOuterClass.EndPointId endpointId_;
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</code>
-     * @return Whether the endpointId field is set.
-     */
-    @java.lang.Override
-    public boolean hasEndpointId() {
-      return endpointId_ != null;
-    }
-    /**
-     * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
-      return getEndpointId();
-    }
-
-    public static final int SERVICE_ID_FIELD_NUMBER = 6;
-    private context.ContextOuterClass.ServiceId serviceId_;
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return Whether the serviceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasServiceId() {
-      return serviceId_ != null;
-    }
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     * @return The serviceId.
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.ServiceId getServiceId() {
-      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-    }
-    /**
-     * <code>.context.ServiceId service_id = 6;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-      return getServiceId();
-    }
-
-    public static final int SLICE_ID_FIELD_NUMBER = 7;
-    private context.ContextOuterClass.SliceId sliceId_;
-    /**
-     * <code>.context.SliceId slice_id = 7;</code>
-     * @return Whether the sliceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasSliceId() {
-      return sliceId_ != null;
-    }
-    /**
-     * <code>.context.SliceId slice_id = 7;</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 = 7;</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;
+    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_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        output.writeMessage(2, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        output.writeEnum(3, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        output.writeMessage(4, getDeviceId());
-      }
-      if (endpointId_ != null) {
-        output.writeMessage(5, getEndpointId());
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
       }
-      if (serviceId_ != null) {
-        output.writeMessage(6, getServiceId());
+      if (monitoringWindowS_ != 0F) {
+        output.writeFloat(2, monitoringWindowS_);
       }
-      if (sliceId_ != null) {
-        output.writeMessage(7, getSliceId());
+      if (samplingRateS_ != 0F) {
+        output.writeFloat(3, samplingRateS_);
       }
       unknownFields.writeTo(output);
     }
@@ -2014,32 +2298,17 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (!getKpiDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, kpiDescription_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(3, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getDeviceId());
-      }
-      if (endpointId_ != null) {
+      if (kpiId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getEndpointId());
+          .computeMessageSize(1, getKpiId());
       }
-      if (serviceId_ != null) {
+      if (monitoringWindowS_ != 0F) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, getServiceId());
+          .computeFloatSize(2, monitoringWindowS_);
       }
-      if (sliceId_ != null) {
+      if (samplingRateS_ != 0F) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, getSliceId());
+          .computeFloatSize(3, samplingRateS_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -2051,36 +2320,22 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.BundleKpiDescriptor)) {
+      if (!(obj instanceof monitoring.Monitoring.MonitorKpiRequest)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.BundleKpiDescriptor other = (monitoring.Monitoring.BundleKpiDescriptor) obj;
+      monitoring.Monitoring.MonitorKpiRequest other = (monitoring.Monitoring.MonitorKpiRequest) obj;
 
-      if (!getKpiDescription()
-          .equals(other.getKpiDescription())) return false;
-      if (!getKpiIdListList()
-          .equals(other.getKpiIdListList())) 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 (hasSliceId() != other.hasSliceId()) return false;
-      if (hasSliceId()) {
-        if (!getSliceId()
-            .equals(other.getSliceId())) return false;
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
       }
+      if (java.lang.Float.floatToIntBits(getMonitoringWindowS())
+          != java.lang.Float.floatToIntBits(
+              other.getMonitoringWindowS())) return false;
+      if (java.lang.Float.floatToIntBits(getSamplingRateS())
+          != java.lang.Float.floatToIntBits(
+              other.getSamplingRateS())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -2092,98 +2347,84 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + KPI_DESCRIPTION_FIELD_NUMBER;
-      hash = (53 * hash) + getKpiDescription().hashCode();
-      if (getKpiIdListCount() > 0) {
-        hash = (37 * hash) + KPI_ID_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiIdListList().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();
-      }
-      if (hasSliceId()) {
-        hash = (37 * hash) + SLICE_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getSliceId().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
       }
+      hash = (37 * hash) + MONITORING_WINDOW_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getMonitoringWindowS());
+      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSamplingRateS());
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(byte[] data)
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(java.io.InputStream input)
+    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.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseDelimitedFrom(java.io.InputStream input)
+    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.BundleKpiDescriptor parseDelimitedFrom(
+    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.BundleKpiDescriptor parseFrom(
+    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.BundleKpiDescriptor parseFrom(
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -2196,7 +2437,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.BundleKpiDescriptor prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.MonitorKpiRequest prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -2212,26 +2453,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.BundleKpiDescriptor}
+     * Protobuf type {@code monitoring.MonitorKpiRequest}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.BundleKpiDescriptor)
-        monitoring.Monitoring.BundleKpiDescriptorOrBuilder {
+        // @@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_BundleKpiDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.BundleKpiDescriptor.class, monitoring.Monitoring.BundleKpiDescriptor.Builder.class);
+                monitoring.Monitoring.MonitorKpiRequest.class, monitoring.Monitoring.MonitorKpiRequest.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.BundleKpiDescriptor.newBuilder()
+      // Construct using monitoring.Monitoring.MonitorKpiRequest.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -2244,63 +2485,38 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiIdListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        kpiDescription_ = "";
-
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
         } else {
-          kpiIdListBuilder_.clear();
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
-        kpiSampleType_ = 0;
+        monitoringWindowS_ = 0F;
+
+        samplingRateS_ = 0F;
 
-        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;
-        }
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_BundleKpiDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.BundleKpiDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.BundleKpiDescriptor.getDefaultInstance();
+      public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
+        return monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.BundleKpiDescriptor build() {
-        monitoring.Monitoring.BundleKpiDescriptor result = buildPartial();
+      public monitoring.Monitoring.MonitorKpiRequest build() {
+        monitoring.Monitoring.MonitorKpiRequest result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -2308,40 +2524,15 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.BundleKpiDescriptor buildPartial() {
-        monitoring.Monitoring.BundleKpiDescriptor result = new monitoring.Monitoring.BundleKpiDescriptor(this);
-        int from_bitField0_ = bitField0_;
-        result.kpiDescription_ = kpiDescription_;
-        if (kpiIdListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.kpiIdList_ = kpiIdList_;
-        } else {
-          result.kpiIdList_ = kpiIdListBuilder_.build();
-        }
-        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();
-        }
-        if (sliceIdBuilder_ == null) {
-          result.sliceId_ = sliceId_;
+      public monitoring.Monitoring.MonitorKpiRequest buildPartial() {
+        monitoring.Monitoring.MonitorKpiRequest result = new monitoring.Monitoring.MonitorKpiRequest(this);
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
         } else {
-          result.sliceId_ = sliceIdBuilder_.build();
+          result.kpiId_ = kpiIdBuilder_.build();
         }
+        result.monitoringWindowS_ = monitoringWindowS_;
+        result.samplingRateS_ = samplingRateS_;
         onBuilt();
         return result;
       }
@@ -2380,60 +2571,24 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.BundleKpiDescriptor) {
-          return mergeFrom((monitoring.Monitoring.BundleKpiDescriptor)other);
+        if (other instanceof monitoring.Monitoring.MonitorKpiRequest) {
+          return mergeFrom((monitoring.Monitoring.MonitorKpiRequest)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.BundleKpiDescriptor other) {
-        if (other == monitoring.Monitoring.BundleKpiDescriptor.getDefaultInstance()) return this;
-        if (!other.getKpiDescription().isEmpty()) {
-          kpiDescription_ = other.kpiDescription_;
-          onChanged();
-        }
-        if (kpiIdListBuilder_ == null) {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdList_.isEmpty()) {
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiIdListIsMutable();
-              kpiIdList_.addAll(other.kpiIdList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdListBuilder_.isEmpty()) {
-              kpiIdListBuilder_.dispose();
-              kpiIdListBuilder_ = null;
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiIdListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiIdListFieldBuilder() : null;
-            } else {
-              kpiIdListBuilder_.addAllMessages(other.kpiIdList_);
-            }
-          }
-        }
-        if (other.kpiSampleType_ != 0) {
-          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
-        }
-        if (other.hasDeviceId()) {
-          mergeDeviceId(other.getDeviceId());
-        }
-        if (other.hasEndpointId()) {
-          mergeEndpointId(other.getEndpointId());
+      public Builder mergeFrom(monitoring.Monitoring.MonitorKpiRequest other) {
+        if (other == monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
         }
-        if (other.hasServiceId()) {
-          mergeServiceId(other.getServiceId());
+        if (other.getMonitoringWindowS() != 0F) {
+          setMonitoringWindowS(other.getMonitoringWindowS());
         }
-        if (other.hasSliceId()) {
-          mergeSliceId(other.getSliceId());
+        if (other.getSamplingRateS() != 0F) {
+          setSamplingRateS(other.getSamplingRateS());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -2450,11 +2605,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.BundleKpiDescriptor parsedMessage = null;
+        monitoring.Monitoring.MonitorKpiRequest parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.BundleKpiDescriptor) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.MonitorKpiRequest) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -2463,1055 +2618,377 @@ public final class Monitoring {
         }
         return this;
       }
-      private int bitField0_;
 
-      private java.lang.Object kpiDescription_ = "";
+      private monitoring.Monitoring.KpiId kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
       /**
-       * <code>string kpi_description = 1;</code>
-       * @return The kpiDescription.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
        */
-      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;
-        }
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
       }
       /**
-       * <code>string kpi_description = 1;</code>
-       * @return The bytes for kpiDescription.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return The kpiId.
        */
-      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;
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          return kpiIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>string kpi_description = 1;</code>
-       * @param value The kpiDescription to set.
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder setKpiDescription(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        kpiDescription_ = value;
-        onChanged();
+      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>string kpi_description = 1;</code>
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder clearKpiDescription() {
-        
-        kpiDescription_ = getDefaultInstance().getKpiDescription();
-        onChanged();
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
         return this;
       }
       /**
-       * <code>string kpi_description = 1;</code>
-       * @param value The bytes for kpiDescription to set.
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder setKpiDescriptionBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        kpiDescription_ = value;
-        onChanged();
-        return this;
-      }
+      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);
+        }
 
-      private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiIdListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiIdList_);
-          bitField0_ |= 0x00000001;
-         }
+        return this;
       }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdListBuilder_;
-
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-        if (kpiIdListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
         } else {
-          return kpiIdListBuilder_.getMessageList();
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public int getKpiIdListCount() {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.size();
-        } else {
-          return kpiIdListBuilder_.getCount();
-        }
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);
-        } else {
-          return kpiIdListBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder addAllKpiIdList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiIdList_);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addAllMessages(values);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder clearKpiIdList() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.clear();
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public Builder removeKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.remove(index);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.remove(index);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-          int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);  } else {
-          return kpiIdListBuilder_.getMessageOrBuilder(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-           getKpiIdListOrBuilderList() {
-        if (kpiIdListBuilder_ != null) {
-          return kpiIdListBuilder_.getMessageOrBuilderList();
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
         } else {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         }
       }
       /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder() {
-        return getKpiIdListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 2;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
-           getKpiIdListBuilderList() {
-        return getKpiIdListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
+      private com.google.protobuf.SingleFieldBuilderV3<
           monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
-          getKpiIdListFieldBuilder() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
-                  kpiIdList_,
-                  ((bitField0_ & 0x00000001) != 0),
+                  getKpiId(),
                   getParentForChildren(),
                   isClean());
-          kpiIdList_ = null;
+          kpiId_ = null;
         }
-        return kpiIdListBuilder_;
+        return kpiIdBuilder_;
       }
 
-      private int kpiSampleType_ = 0;
+      private float monitoringWindowS_ ;
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @return The enum numeric value on the wire for kpiSampleType.
+       * <code>float monitoring_window_s = 2;</code>
+       * @return The monitoringWindowS.
        */
-      @java.lang.Override public int getKpiSampleTypeValue() {
-        return kpiSampleType_;
+      @java.lang.Override
+      public float getMonitoringWindowS() {
+        return monitoringWindowS_;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @param value The enum numeric value on the wire for kpiSampleType to set.
+       * <code>float monitoring_window_s = 2;</code>
+       * @param value The monitoringWindowS to set.
        * @return This builder for chaining.
        */
-      public Builder setKpiSampleTypeValue(int value) {
+      public Builder setMonitoringWindowS(float value) {
         
-        kpiSampleType_ = value;
+        monitoringWindowS_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @return The kpiSampleType.
+       * <code>float monitoring_window_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearMonitoringWindowS() {
+        
+        monitoringWindowS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float samplingRateS_ ;
+      /**
+       * <pre>
+       * Pending add field to reflect Available Device Protocols
+       * </pre>
+       *
+       * <code>float sampling_rate_s = 3;</code>
+       * @return The samplingRateS.
        */
       @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 float getSamplingRateS() {
+        return samplingRateS_;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
-       * @param value The kpiSampleType to set.
+       * <pre>
+       * Pending add field to reflect Available Device Protocols
+       * </pre>
+       *
+       * <code>float sampling_rate_s = 3;</code>
+       * @param value The samplingRateS to set.
        * @return This builder for chaining.
        */
-      public Builder setKpiSampleType(kpi_sample_types.KpiSampleTypes.KpiSampleType value) {
-        if (value == null) {
-          throw new NullPointerException();
-        }
+      public Builder setSamplingRateS(float value) {
         
-        kpiSampleType_ = value.getNumber();
+        samplingRateS_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 3;</code>
+       * <pre>
+       * Pending add field to reflect Available Device Protocols
+       * </pre>
+       *
+       * <code>float sampling_rate_s = 3;</code>
        * @return This builder for chaining.
        */
-      public Builder clearKpiSampleType() {
+      public Builder clearSamplingRateS() {
         
-        kpiSampleType_ = 0;
+        samplingRateS_ = 0F;
         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 = 4;</code>
-       * @return Whether the deviceId field is set.
-       */
-      public boolean hasDeviceId() {
-        return deviceIdBuilder_ != null || deviceId_ != null;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 4;</code>
-       * @return The deviceId.
-       */
-      public context.ContextOuterClass.DeviceId getDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
-        } else {
-          return deviceIdBuilder_.getMessage();
-        }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
       }
-      /**
-       * <code>.context.DeviceId device_id = 4;</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;
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
-      /**
-       * <code>.context.DeviceId device_id = 4;</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 = 4;</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 = 4;</code>
-       */
-      public Builder clearDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = null;
-          onChanged();
-        } else {
-          deviceId_ = null;
-          deviceIdBuilder_ = null;
-        }
+      // @@protoc_insertion_point(builder_scope:monitoring.MonitorKpiRequest)
+    }
 
-        return this;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 4;</code>
-       */
-      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
-        
-        onChanged();
-        return getDeviceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.DeviceId device_id = 4;</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 = 4;</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_;
-      }
+    // @@protoc_insertion_point(class_scope:monitoring.MonitorKpiRequest)
+    private static final monitoring.Monitoring.MonitorKpiRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.MonitorKpiRequest();
+    }
 
-      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 = 5;</code>
-       * @return Whether the endpointId field is set.
-       */
-      public boolean hasEndpointId() {
-        return endpointIdBuilder_ != null || endpointId_ != null;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</code>
-       */
-      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
-        if (endpointIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          endpointId_ = value;
-          onChanged();
-        } else {
-          endpointIdBuilder_.setMessage(value);
-        }
+    public static monitoring.Monitoring.MonitorKpiRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
 
-        return this;
+    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);
       }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</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);
-        }
+    public static com.google.protobuf.Parser<MonitorKpiRequest> parser() {
+      return PARSER;
+    }
 
-        return this;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</code>
-       */
-      public Builder clearEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = null;
-          onChanged();
-        } else {
-          endpointId_ = null;
-          endpointIdBuilder_ = null;
-        }
+    @java.lang.Override
+    public com.google.protobuf.Parser<MonitorKpiRequest> getParserForType() {
+      return PARSER;
+    }
 
-        return this;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</code>
-       */
-      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
-        
-        onChanged();
-        return getEndpointIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 5;</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 = 5;</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_;
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       * @return Whether the serviceId field is set.
-       */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       * @return The serviceId.
-       */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
-          onChanged();
-        } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
-        
-        onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</code>
-       */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
-        } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 6;</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_;
-      }
-
-      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 = 7;</code>
-       * @return Whether the sliceId field is set.
-       */
-      public boolean hasSliceId() {
-        return sliceIdBuilder_ != null || sliceId_ != null;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 7;</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 = 7;</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 = 7;</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 = 7;</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 = 7;</code>
-       */
-      public Builder clearSliceId() {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-          onChanged();
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 7;</code>
-       */
-      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
-        
-        onChanged();
-        return getSliceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.SliceId slice_id = 7;</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 = 7;</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:monitoring.BundleKpiDescriptor)
-    }
-
-    // @@protoc_insertion_point(class_scope:monitoring.BundleKpiDescriptor)
-    private static final monitoring.Monitoring.BundleKpiDescriptor DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.BundleKpiDescriptor();
-    }
-
-    public static monitoring.Monitoring.BundleKpiDescriptor getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<BundleKpiDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<BundleKpiDescriptor>() {
-      @java.lang.Override
-      public BundleKpiDescriptor parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new BundleKpiDescriptor(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<BundleKpiDescriptor> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<BundleKpiDescriptor> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.BundleKpiDescriptor getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
+    @java.lang.Override
+    public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
 
   }
 
-  public interface EditedKpiDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.EditedKpiDescriptor)
+  public interface KpiQueryOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiQuery)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    boolean hasKpiId();
+    java.util.List<monitoring.Monitoring.KpiId> 
+        getKpiIdList();
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    monitoring.Monitoring.KpiId getKpiId();
-    /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
-
-    /**
-     * <code>string kpi_description = 2;</code>
-     * @return The kpiDescription.
-     */
-    java.lang.String getKpiDescription();
-    /**
-     * <code>string kpi_description = 2;</code>
-     * @return The bytes for kpiDescription.
-     */
-    com.google.protobuf.ByteString
-        getKpiDescriptionBytes();
-
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    java.util.List<monitoring.Monitoring.KpiId> 
-        getKpiIdListList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    monitoring.Monitoring.KpiId getKpiIdList(int index);
+    monitoring.Monitoring.KpiId getKpiId(int index);
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    int getKpiIdListCount();
+    int getKpiIdCount();
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList();
+        getKpiIdOrBuilderList();
     /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
         int index);
 
     /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
-     * @return The enum numeric value on the wire for kpiSampleType.
-     */
-    int getKpiSampleTypeValue();
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</code>
-     * @return The kpiSampleType.
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
-    kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
+    float getMonitoringWindowS();
 
     /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return Whether the deviceId field is set.
-     */
-    boolean hasDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return The deviceId.
-     */
-    context.ContextOuterClass.DeviceId getDeviceId();
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
-    context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
+    float getSamplingRateS();
 
     /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return Whether the endpointId field is set.
-     */
-    boolean hasEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return The endpointId.
-     */
-    context.ContextOuterClass.EndPointId getEndpointId();
-    /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
+     * <pre>
+     * used when you want something like "get the last N many samples
+     * </pre>
+     *
+     * <code>uint32 last_n_samples = 4;</code>
+     * @return The lastNSamples.
      */
-    context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
+    int getLastNSamples();
 
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return Whether the serviceId field is set.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
      */
-    boolean hasServiceId();
+    boolean hasStartTimestamp();
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return The serviceId.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
      */
-    context.ContextOuterClass.ServiceId getServiceId();
+    context.ContextOuterClass.Timestamp getStartTimestamp();
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
      */
-    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+    context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder();
 
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return Whether the sliceId field is set.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
      */
-    boolean hasSliceId();
+    boolean hasEndTimestamp();
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return The sliceId.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
      */
-    context.ContextOuterClass.SliceId getSliceId();
+    context.ContextOuterClass.Timestamp getEndTimestamp();
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
      */
-    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+    context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.EditedKpiDescriptor}
+   * Protobuf type {@code monitoring.KpiQuery}
    */
-  public static final class EditedKpiDescriptor extends
+  public static final class KpiQuery extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.EditedKpiDescriptor)
-      EditedKpiDescriptorOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiQuery)
+      KpiQueryOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use EditedKpiDescriptor.newBuilder() to construct.
-    private EditedKpiDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiQuery.newBuilder() to construct.
+    private KpiQuery(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private EditedKpiDescriptor() {
-      kpiDescription_ = "";
-      kpiIdList_ = java.util.Collections.emptyList();
-      kpiSampleType_ = 0;
+    private KpiQuery() {
+      kpiId_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new EditedKpiDescriptor();
+      return new KpiQuery();
     }
 
     @java.lang.Override
@@ -3519,7 +2996,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private EditedKpiDescriptor(
+    private KpiQuery(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -3539,87 +3016,51 @@ public final class Monitoring {
               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();
-
-              kpiDescription_ = s;
-              break;
-            }
-            case 26: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
+                kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              kpiIdList_.add(
+              kpiId_.add(
                   input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
               break;
             }
-            case 32: {
-              int rawValue = input.readEnum();
+            case 21: {
 
-              kpiSampleType_ = rawValue;
+              monitoringWindowS_ = input.readFloat();
               break;
             }
-            case 42: {
-              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();
-              }
+            case 29: {
 
+              samplingRateS_ = input.readFloat();
               break;
             }
-            case 50: {
-              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();
-              }
+            case 32: {
 
+              lastNSamples_ = input.readUInt32();
               break;
             }
-            case 58: {
-              context.ContextOuterClass.ServiceId.Builder subBuilder = null;
-              if (serviceId_ != null) {
-                subBuilder = serviceId_.toBuilder();
+            case 42: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (startTimestamp_ != null) {
+                subBuilder = startTimestamp_.toBuilder();
               }
-              serviceId_ = input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry);
+              startTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(serviceId_);
-                serviceId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(startTimestamp_);
+                startTimestamp_ = subBuilder.buildPartial();
               }
 
               break;
             }
-            case 66: {
-              context.ContextOuterClass.SliceId.Builder subBuilder = null;
-              if (sliceId_ != null) {
-                subBuilder = sliceId_.toBuilder();
+            case 50: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (endTimestamp_ != null) {
+                subBuilder = endTimestamp_.toBuilder();
               }
-              sliceId_ = input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry);
+              endTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(sliceId_);
-                sliceId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(endTimestamp_);
+                endTimestamp_ = subBuilder.buildPartial();
               }
 
               break;
@@ -3640,7 +3081,7 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
+          kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -3648,242 +3089,168 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.EditedKpiDescriptor.class, monitoring.Monitoring.EditedKpiDescriptor.Builder.class);
+              monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
     }
 
     public static final int KPI_ID_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.KpiId kpiId_;
+    private java.util.List<monitoring.Monitoring.KpiId> kpiId_;
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public boolean hasKpiId() {
-      return kpiId_ != null;
+    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+      return kpiId_;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiId() {
-      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdOrBuilderList() {
+      return kpiId_;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-      return getKpiId();
+    public int getKpiIdCount() {
+      return kpiId_.size();
     }
-
-    public static final int KPI_DESCRIPTION_FIELD_NUMBER = 2;
-    private volatile java.lang.Object kpiDescription_;
     /**
-     * <code>string kpi_description = 2;</code>
-     * @return The kpiDescription.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @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;
-      }
+    public monitoring.Monitoring.KpiId getKpiId(int index) {
+      return kpiId_.get(index);
     }
     /**
-     * <code>string kpi_description = 2;</code>
-     * @return The bytes for kpiDescription.
+     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
      */
     @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_ID_LIST_FIELD_NUMBER = 3;
-    private java.util.List<monitoring.Monitoring.KpiId> kpiIdList_;
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-      return kpiIdList_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdListOrBuilderList() {
-      return kpiIdList_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public int getKpiIdListCount() {
-      return kpiIdList_.size();
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-      return kpiIdList_.get(index);
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
         int index) {
-      return kpiIdList_.get(index);
-    }
-
-    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 4;
-    private int kpiSampleType_;
-    /**
-     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</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 = 4;</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;
+      return kpiId_.get(index);
     }
 
-    public static final int DEVICE_ID_FIELD_NUMBER = 5;
-    private context.ContextOuterClass.DeviceId deviceId_;
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return Whether the deviceId field is set.
-     */
-    @java.lang.Override
-    public boolean hasDeviceId() {
-      return deviceId_ != null;
-    }
-    /**
-     * <code>.context.DeviceId device_id = 5;</code>
-     * @return The deviceId.
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.DeviceId getDeviceId() {
-      return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
-    }
+    public static final int MONITORING_WINDOW_S_FIELD_NUMBER = 2;
+    private float monitoringWindowS_;
     /**
-     * <code>.context.DeviceId device_id = 5;</code>
+     * <code>float monitoring_window_s = 2;</code>
+     * @return The monitoringWindowS.
      */
     @java.lang.Override
-    public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
-      return getDeviceId();
+    public float getMonitoringWindowS() {
+      return monitoringWindowS_;
     }
 
-    public static final int ENDPOINT_ID_FIELD_NUMBER = 6;
-    private context.ContextOuterClass.EndPointId endpointId_;
-    /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return Whether the endpointId field is set.
-     */
-    @java.lang.Override
-    public boolean hasEndpointId() {
-      return endpointId_ != null;
-    }
+    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
+    private float samplingRateS_;
     /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
-     * @return The endpointId.
+     * <code>float sampling_rate_s = 3;</code>
+     * @return The samplingRateS.
      */
     @java.lang.Override
-    public context.ContextOuterClass.EndPointId getEndpointId() {
-      return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+    public float getSamplingRateS() {
+      return samplingRateS_;
     }
+
+    public static final int LAST_N_SAMPLES_FIELD_NUMBER = 4;
+    private int lastNSamples_;
     /**
-     * <code>.context.EndPointId endpoint_id = 6;</code>
+     * <pre>
+     * used when you want something like "get the last N many samples
+     * </pre>
+     *
+     * <code>uint32 last_n_samples = 4;</code>
+     * @return The lastNSamples.
      */
     @java.lang.Override
-    public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
-      return getEndpointId();
+    public int getLastNSamples() {
+      return lastNSamples_;
     }
 
-    public static final int SERVICE_ID_FIELD_NUMBER = 7;
-    private context.ContextOuterClass.ServiceId serviceId_;
+    public static final int START_TIMESTAMP_FIELD_NUMBER = 5;
+    private context.ContextOuterClass.Timestamp startTimestamp_;
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return Whether the serviceId field is set.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
      */
     @java.lang.Override
-    public boolean hasServiceId() {
-      return serviceId_ != null;
+    public boolean hasStartTimestamp() {
+      return startTimestamp_ != null;
     }
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
-     * @return The serviceId.
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceId getServiceId() {
-      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+    public context.ContextOuterClass.Timestamp getStartTimestamp() {
+      return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
     }
     /**
-     * <code>.context.ServiceId service_id = 7;</code>
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-      return getServiceId();
+    public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+      return getStartTimestamp();
     }
 
-    public static final int SLICE_ID_FIELD_NUMBER = 8;
-    private context.ContextOuterClass.SliceId sliceId_;
+    public static final int END_TIMESTAMP_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.Timestamp endTimestamp_;
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return Whether the sliceId field is set.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
      */
     @java.lang.Override
-    public boolean hasSliceId() {
-      return sliceId_ != null;
+    public boolean hasEndTimestamp() {
+      return endTimestamp_ != null;
     }
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
-     * @return The sliceId.
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
      */
     @java.lang.Override
-    public context.ContextOuterClass.SliceId getSliceId() {
-      return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+    public context.ContextOuterClass.Timestamp getEndTimestamp() {
+      return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
     }
     /**
-     * <code>.context.SliceId slice_id = 8;</code>
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
-      return getSliceId();
+    public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+      return getEndTimestamp();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -3894,3670 +3261,1729 @@ public final class Monitoring {
       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 (!getKpiDescriptionBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, kpiDescription_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        output.writeMessage(3, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        output.writeEnum(4, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        output.writeMessage(5, getDeviceId());
-      }
-      if (endpointId_ != null) {
-        output.writeMessage(6, getEndpointId());
-      }
-      if (serviceId_ != null) {
-        output.writeMessage(7, getServiceId());
-      }
-      if (sliceId_ != null) {
-        output.writeMessage(8, getSliceId());
-      }
-      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 (!getKpiDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, kpiDescription_);
-      }
-      for (int i = 0; i < kpiIdList_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, kpiIdList_.get(i));
-      }
-      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(4, kpiSampleType_);
-      }
-      if (deviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, getDeviceId());
-      }
-      if (endpointId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, getEndpointId());
-      }
-      if (serviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, getServiceId());
-      }
-      if (sliceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(8, 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 monitoring.Monitoring.EditedKpiDescriptor)) {
-        return super.equals(obj);
-      }
-      monitoring.Monitoring.EditedKpiDescriptor other = (monitoring.Monitoring.EditedKpiDescriptor) obj;
-
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
-      }
-      if (!getKpiDescription()
-          .equals(other.getKpiDescription())) return false;
-      if (!getKpiIdListList()
-          .equals(other.getKpiIdListList())) 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 (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 (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
-      }
-      hash = (37 * hash) + KPI_DESCRIPTION_FIELD_NUMBER;
-      hash = (53 * hash) + getKpiDescription().hashCode();
-      if (getKpiIdListCount() > 0) {
-        hash = (37 * hash) + KPI_ID_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiIdListList().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();
-      }
-      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 monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.EditedKpiDescriptor 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.EditedKpiDescriptor 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.EditedKpiDescriptor}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.EditedKpiDescriptor)
-        monitoring.Monitoring.EditedKpiDescriptorOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_descriptor;
-      }
-
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.EditedKpiDescriptor.class, monitoring.Monitoring.EditedKpiDescriptor.Builder.class);
-      }
-
-      // Construct using monitoring.Monitoring.EditedKpiDescriptor.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-          getKpiIdListFieldBuilder();
-        }
-      }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
-        } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
-        }
-        kpiDescription_ = "";
-
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-        } else {
-          kpiIdListBuilder_.clear();
-        }
-        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;
-        }
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_EditedKpiDescriptor_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.EditedKpiDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.EditedKpiDescriptor.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.EditedKpiDescriptor build() {
-        monitoring.Monitoring.EditedKpiDescriptor result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.EditedKpiDescriptor buildPartial() {
-        monitoring.Monitoring.EditedKpiDescriptor result = new monitoring.Monitoring.EditedKpiDescriptor(this);
-        int from_bitField0_ = bitField0_;
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
-        } else {
-          result.kpiId_ = kpiIdBuilder_.build();
-        }
-        result.kpiDescription_ = kpiDescription_;
-        if (kpiIdListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiIdList_ = java.util.Collections.unmodifiableList(kpiIdList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.kpiIdList_ = kpiIdList_;
-        } else {
-          result.kpiIdList_ = kpiIdListBuilder_.build();
-        }
-        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();
-        }
-        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 monitoring.Monitoring.EditedKpiDescriptor) {
-          return mergeFrom((monitoring.Monitoring.EditedKpiDescriptor)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(monitoring.Monitoring.EditedKpiDescriptor other) {
-        if (other == monitoring.Monitoring.EditedKpiDescriptor.getDefaultInstance()) return this;
-        if (other.hasKpiId()) {
-          mergeKpiId(other.getKpiId());
-        }
-        if (!other.getKpiDescription().isEmpty()) {
-          kpiDescription_ = other.kpiDescription_;
-          onChanged();
-        }
-        if (kpiIdListBuilder_ == null) {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdList_.isEmpty()) {
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiIdListIsMutable();
-              kpiIdList_.addAll(other.kpiIdList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.kpiIdList_.isEmpty()) {
-            if (kpiIdListBuilder_.isEmpty()) {
-              kpiIdListBuilder_.dispose();
-              kpiIdListBuilder_ = null;
-              kpiIdList_ = other.kpiIdList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiIdListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiIdListFieldBuilder() : null;
-            } else {
-              kpiIdListBuilder_.addAllMessages(other.kpiIdList_);
-            }
-          }
-        }
-        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());
-        }
-        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 {
-        monitoring.Monitoring.EditedKpiDescriptor parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.EditedKpiDescriptor) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      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 kpiDescription_ = "";
-      /**
-       * <code>string kpi_description = 2;</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 = 2;</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 = 2;</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 = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearKpiDescription() {
-        
-        kpiDescription_ = getDefaultInstance().getKpiDescription();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string kpi_description = 2;</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 java.util.List<monitoring.Monitoring.KpiId> kpiIdList_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiIdListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiIdList_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiIdList_);
-          bitField0_ |= 0x00000001;
-         }
-      }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdListBuilder_;
-
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdListList() {
-        if (kpiIdListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
-        } else {
-          return kpiIdListBuilder_.getMessageList();
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public int getKpiIdListCount() {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.size();
-        } else {
-          return kpiIdListBuilder_.getCount();
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId getKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);
-        } else {
-          return kpiIdListBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder setKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, value);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addKpiIdList(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder addAllKpiIdList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiIdList_);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.addAllMessages(values);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder clearKpiIdList() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.clear();
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public Builder removeKpiIdList(int index) {
-        if (kpiIdListBuilder_ == null) {
-          ensureKpiIdListIsMutable();
-          kpiIdList_.remove(index);
-          onChanged();
-        } else {
-          kpiIdListBuilder_.remove(index);
-        }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdListOrBuilder(
-          int index) {
-        if (kpiIdListBuilder_ == null) {
-          return kpiIdList_.get(index);  } else {
-          return kpiIdListBuilder_.getMessageOrBuilder(index);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-           getKpiIdListOrBuilderList() {
-        if (kpiIdListBuilder_ != null) {
-          return kpiIdListBuilder_.getMessageOrBuilderList();
-        } else {
-          return java.util.Collections.unmodifiableList(kpiIdList_);
-        }
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder() {
-        return getKpiIdListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdListBuilder(
-          int index) {
-        return getKpiIdListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id_list = 3;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
-           getKpiIdListBuilderList() {
-        return getKpiIdListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
-          getKpiIdListFieldBuilder() {
-        if (kpiIdListBuilder_ == null) {
-          kpiIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
-                  kpiIdList_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          kpiIdList_ = null;
-        }
-        return kpiIdListBuilder_;
-      }
-
-      private int kpiSampleType_ = 0;
-      /**
-       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 4;</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 = 4;</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 = 4;</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 = 4;</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 = 4;</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 = 5;</code>
-       * @return Whether the deviceId field is set.
-       */
-      public boolean hasDeviceId() {
-        return deviceIdBuilder_ != null || deviceId_ != null;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 5;</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 = 5;</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 = 5;</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 = 5;</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 = 5;</code>
-       */
-      public Builder clearDeviceId() {
-        if (deviceIdBuilder_ == null) {
-          deviceId_ = null;
-          onChanged();
-        } else {
-          deviceId_ = null;
-          deviceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.DeviceId device_id = 5;</code>
-       */
-      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
-        
-        onChanged();
-        return getDeviceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.DeviceId device_id = 5;</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 = 5;</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 = 6;</code>
-       * @return Whether the endpointId field is set.
-       */
-      public boolean hasEndpointId() {
-        return endpointIdBuilder_ != null || endpointId_ != null;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 6;</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 = 6;</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 = 6;</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 = 6;</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 = 6;</code>
-       */
-      public Builder clearEndpointId() {
-        if (endpointIdBuilder_ == null) {
-          endpointId_ = null;
-          onChanged();
-        } else {
-          endpointId_ = null;
-          endpointIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 6;</code>
-       */
-      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
-        
-        onChanged();
-        return getEndpointIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.EndPointId endpoint_id = 6;</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 = 6;</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_;
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       * @return Whether the serviceId field is set.
-       */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       * @return The serviceId.
-       */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</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;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
-          onChanged();
-        } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
-        
-        onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
-        } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        }
-      }
-      /**
-       * <code>.context.ServiceId service_id = 7;</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_;
-      }
-
-      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 = 8;</code>
-       * @return Whether the sliceId field is set.
-       */
-      public boolean hasSliceId() {
-        return sliceIdBuilder_ != null || sliceId_ != null;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 8;</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 = 8;</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 = 8;</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 = 8;</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 = 8;</code>
-       */
-      public Builder clearSliceId() {
-        if (sliceIdBuilder_ == null) {
-          sliceId_ = null;
-          onChanged();
-        } else {
-          sliceId_ = null;
-          sliceIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.SliceId slice_id = 8;</code>
-       */
-      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
-        
-        onChanged();
-        return getSliceIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.SliceId slice_id = 8;</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 = 8;</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:monitoring.EditedKpiDescriptor)
-    }
-
-    // @@protoc_insertion_point(class_scope:monitoring.EditedKpiDescriptor)
-    private static final monitoring.Monitoring.EditedKpiDescriptor DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.EditedKpiDescriptor();
-    }
-
-    public static monitoring.Monitoring.EditedKpiDescriptor getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<EditedKpiDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<EditedKpiDescriptor>() {
-      @java.lang.Override
-      public EditedKpiDescriptor parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new EditedKpiDescriptor(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<EditedKpiDescriptor> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<EditedKpiDescriptor> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.EditedKpiDescriptor 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 monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    float getMonitoringWindowS();
-
-    /**
-     * <pre>
-     * Pending add field to reflect Available Device Protocols
-     * </pre>
-     *
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    float getSamplingRateS();
-  }
-  /**
-   * 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: {
-
-              monitoringWindowS_ = input.readFloat();
-              break;
-            }
-            case 29: {
-
-              samplingRateS_ = 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 MONITORING_WINDOW_S_FIELD_NUMBER = 2;
-    private float monitoringWindowS_;
-    /**
-     * <code>float monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    @java.lang.Override
-    public float getMonitoringWindowS() {
-      return monitoringWindowS_;
-    }
-
-    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
-    private float samplingRateS_;
-    /**
-     * <pre>
-     * Pending add field to reflect Available Device Protocols
-     * </pre>
-     *
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    @java.lang.Override
-    public float getSamplingRateS() {
-      return samplingRateS_;
-    }
-
-    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 (monitoringWindowS_ != 0F) {
-        output.writeFloat(2, monitoringWindowS_);
-      }
-      if (samplingRateS_ != 0F) {
-        output.writeFloat(3, samplingRateS_);
-      }
-      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 (monitoringWindowS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(2, monitoringWindowS_);
-      }
-      if (samplingRateS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(3, samplingRateS_);
-      }
-      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(getMonitoringWindowS())
-          != java.lang.Float.floatToIntBits(
-              other.getMonitoringWindowS())) return false;
-      if (java.lang.Float.floatToIntBits(getSamplingRateS())
-          != java.lang.Float.floatToIntBits(
-              other.getSamplingRateS())) 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) + MONITORING_WINDOW_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getMonitoringWindowS());
-      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getSamplingRateS());
-      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;
-        }
-        monitoringWindowS_ = 0F;
-
-        samplingRateS_ = 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.monitoringWindowS_ = monitoringWindowS_;
-        result.samplingRateS_ = samplingRateS_;
-        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.getMonitoringWindowS() != 0F) {
-          setMonitoringWindowS(other.getMonitoringWindowS());
-        }
-        if (other.getSamplingRateS() != 0F) {
-          setSamplingRateS(other.getSamplingRateS());
-        }
-        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_;
-      }
+      return true;
+    }
 
-      private float monitoringWindowS_ ;
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return The monitoringWindowS.
-       */
-      @java.lang.Override
-      public float getMonitoringWindowS() {
-        return monitoringWindowS_;
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < kpiId_.size(); i++) {
+        output.writeMessage(1, kpiId_.get(i));
       }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @param value The monitoringWindowS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMonitoringWindowS(float value) {
-        
-        monitoringWindowS_ = value;
-        onChanged();
-        return this;
+      if (monitoringWindowS_ != 0F) {
+        output.writeFloat(2, monitoringWindowS_);
       }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMonitoringWindowS() {
-        
-        monitoringWindowS_ = 0F;
-        onChanged();
-        return this;
+      if (samplingRateS_ != 0F) {
+        output.writeFloat(3, samplingRateS_);
+      }
+      if (lastNSamples_ != 0) {
+        output.writeUInt32(4, lastNSamples_);
+      }
+      if (startTimestamp_ != null) {
+        output.writeMessage(5, getStartTimestamp());
       }
+      if (endTimestamp_ != null) {
+        output.writeMessage(6, getEndTimestamp());
+      }
+      unknownFields.writeTo(output);
+    }
 
-      private float samplingRateS_ ;
-      /**
-       * <pre>
-       * Pending add field to reflect Available Device Protocols
-       * </pre>
-       *
-       * <code>float sampling_rate_s = 3;</code>
-       * @return The samplingRateS.
-       */
-      @java.lang.Override
-      public float getSamplingRateS() {
-        return samplingRateS_;
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < kpiId_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, kpiId_.get(i));
       }
-      /**
-       * <pre>
-       * Pending add field to reflect Available Device Protocols
-       * </pre>
-       *
-       * <code>float sampling_rate_s = 3;</code>
-       * @param value The samplingRateS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSamplingRateS(float value) {
-        
-        samplingRateS_ = value;
-        onChanged();
-        return this;
+      if (monitoringWindowS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(2, monitoringWindowS_);
       }
-      /**
-       * <pre>
-       * Pending add field to reflect Available Device Protocols
-       * </pre>
-       *
-       * <code>float sampling_rate_s = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSamplingRateS() {
-        
-        samplingRateS_ = 0F;
-        onChanged();
-        return this;
+      if (samplingRateS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, samplingRateS_);
       }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+      if (lastNSamples_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(4, lastNSamples_);
       }
-
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      if (startTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, getStartTimestamp());
       }
+      if (endTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getEndTimestamp());
+      }
+      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.KpiQuery)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.KpiQuery other = (monitoring.Monitoring.KpiQuery) obj;
 
-      // @@protoc_insertion_point(builder_scope:monitoring.MonitorKpiRequest)
+      if (!getKpiIdList()
+          .equals(other.getKpiIdList())) return false;
+      if (java.lang.Float.floatToIntBits(getMonitoringWindowS())
+          != java.lang.Float.floatToIntBits(
+              other.getMonitoringWindowS())) return false;
+      if (java.lang.Float.floatToIntBits(getSamplingRateS())
+          != java.lang.Float.floatToIntBits(
+              other.getSamplingRateS())) return false;
+      if (getLastNSamples()
+          != other.getLastNSamples()) return false;
+      if (hasStartTimestamp() != other.hasStartTimestamp()) return false;
+      if (hasStartTimestamp()) {
+        if (!getStartTimestamp()
+            .equals(other.getStartTimestamp())) return false;
+      }
+      if (hasEndTimestamp() != other.hasEndTimestamp()) return false;
+      if (hasEndTimestamp()) {
+        if (!getEndTimestamp()
+            .equals(other.getEndTimestamp())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.MonitorKpiRequest)
-    private static final monitoring.Monitoring.MonitorKpiRequest DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.MonitorKpiRequest();
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getKpiIdCount() > 0) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiIdList().hashCode();
+      }
+      hash = (37 * hash) + MONITORING_WINDOW_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getMonitoringWindowS());
+      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSamplingRateS());
+      hash = (37 * hash) + LAST_N_SAMPLES_FIELD_NUMBER;
+      hash = (53 * hash) + getLastNSamples();
+      if (hasStartTimestamp()) {
+        hash = (37 * hash) + START_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getStartTimestamp().hashCode();
+      }
+      if (hasEndTimestamp()) {
+        hash = (37 * hash) + END_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getEndTimestamp().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
-    public static monitoring.Monitoring.MonitorKpiRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiQuery parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    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 Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.KpiQuery prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
-
     @java.lang.Override
-    public com.google.protobuf.Parser<MonitorKpiRequest> getParserForType() {
-      return PARSER;
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
     }
-
-  }
-
-  public interface KpiQueryOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiQuery)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    java.util.List<monitoring.Monitoring.KpiId> 
-        getKpiIdList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    monitoring.Monitoring.KpiId getKpiId(int index);
     /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    int getKpiIdCount();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdOrBuilderList();
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+     * Protobuf type {@code monitoring.KpiQuery}
      */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
-        int index);
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiQuery)
+        monitoring.Monitoring.KpiQueryOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
+      }
 
-    /**
-     * <code>float monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    float getMonitoringWindowS();
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
+      }
 
-    /**
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    float getSamplingRateS();
+      // Construct using monitoring.Monitoring.KpiQuery.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
 
-    /**
-     * <pre>
-     * used when you want something like "get the last N many samples
-     * </pre>
-     *
-     * <code>uint32 last_n_samples = 4;</code>
-     * @return The lastNSamples.
-     */
-    int getLastNSamples();
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getKpiIdFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          kpiIdBuilder_.clear();
+        }
+        monitoringWindowS_ = 0F;
 
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The startDate.
-     */
-    java.lang.String getStartDate();
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The bytes for startDate.
-     */
-    com.google.protobuf.ByteString
-        getStartDateBytes();
+        samplingRateS_ = 0F;
 
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The endDate.
-     */
-    java.lang.String getEndDate();
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The bytes for endDate.
-     */
-    com.google.protobuf.ByteString
-        getEndDateBytes();
-  }
-  /**
-   * Protobuf type {@code monitoring.KpiQuery}
-   */
-  public static final class KpiQuery extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiQuery)
-      KpiQueryOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use KpiQuery.newBuilder() to construct.
-    private KpiQuery(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private KpiQuery() {
-      kpiId_ = java.util.Collections.emptyList();
-      startDate_ = "";
-      endDate_ = "";
-    }
+        lastNSamples_ = 0;
 
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new KpiQuery();
-    }
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
+        } else {
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
+        }
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
+        } else {
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
+        }
+        return this;
+      }
 
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private KpiQuery(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
       }
-      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)) {
-                kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              kpiId_.add(
-                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
-              break;
-            }
-            case 21: {
 
-              monitoringWindowS_ = input.readFloat();
-              break;
-            }
-            case 29: {
+      @java.lang.Override
+      public monitoring.Monitoring.KpiQuery getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiQuery.getDefaultInstance();
+      }
 
-              samplingRateS_ = input.readFloat();
-              break;
-            }
-            case 32: {
+      @java.lang.Override
+      public monitoring.Monitoring.KpiQuery build() {
+        monitoring.Monitoring.KpiQuery result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
 
-              lastNSamples_ = input.readUInt32();
-              break;
-            }
-            case 42: {
-              java.lang.String s = input.readStringRequireUtf8();
+      @java.lang.Override
+      public monitoring.Monitoring.KpiQuery buildPartial() {
+        monitoring.Monitoring.KpiQuery result = new monitoring.Monitoring.KpiQuery(this);
+        int from_bitField0_ = bitField0_;
+        if (kpiIdBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.monitoringWindowS_ = monitoringWindowS_;
+        result.samplingRateS_ = samplingRateS_;
+        result.lastNSamples_ = lastNSamples_;
+        if (startTimestampBuilder_ == null) {
+          result.startTimestamp_ = startTimestamp_;
+        } else {
+          result.startTimestamp_ = startTimestampBuilder_.build();
+        }
+        if (endTimestampBuilder_ == null) {
+          result.endTimestamp_ = endTimestamp_;
+        } else {
+          result.endTimestamp_ = endTimestampBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
 
-              startDate_ = s;
-              break;
-            }
-            case 50: {
-              java.lang.String s = input.readStringRequireUtf8();
+      @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.KpiQuery) {
+          return mergeFrom((monitoring.Monitoring.KpiQuery)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
 
-              endDate_ = s;
-              break;
+      public Builder mergeFrom(monitoring.Monitoring.KpiQuery other) {
+        if (other == monitoring.Monitoring.KpiQuery.getDefaultInstance()) return this;
+        if (kpiIdBuilder_ == null) {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiId_.isEmpty()) {
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiIdIsMutable();
+              kpiId_.addAll(other.kpiId_);
             }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
+            onChanged();
+          }
+        } else {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiIdBuilder_.isEmpty()) {
+              kpiIdBuilder_.dispose();
+              kpiIdBuilder_ = null;
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiIdBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiIdFieldBuilder() : null;
+            } else {
+              kpiIdBuilder_.addAllMessages(other.kpiId_);
             }
           }
         }
-      } 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)) {
-          kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+        if (other.getMonitoringWindowS() != 0F) {
+          setMonitoringWindowS(other.getMonitoringWindowS());
         }
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
+        if (other.getSamplingRateS() != 0F) {
+          setSamplingRateS(other.getSamplingRateS());
+        }
+        if (other.getLastNSamples() != 0) {
+          setLastNSamples(other.getLastNSamples());
+        }
+        if (other.hasStartTimestamp()) {
+          mergeStartTimestamp(other.getStartTimestamp());
+        }
+        if (other.hasEndTimestamp()) {
+          mergeEndTimestamp(other.getEndTimestamp());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
       }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
-    }
-
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
-    }
-
-    public static final int KPI_ID_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.KpiId> kpiId_;
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
-      return kpiId_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-        getKpiIdOrBuilderList() {
-      return kpiId_;
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public int getKpiIdCount() {
-      return kpiId_.size();
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiId(int index) {
-      return kpiId_.get(index);
-    }
-    /**
-     * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
-        int index) {
-      return kpiId_.get(index);
-    }
-
-    public static final int MONITORING_WINDOW_S_FIELD_NUMBER = 2;
-    private float monitoringWindowS_;
-    /**
-     * <code>float monitoring_window_s = 2;</code>
-     * @return The monitoringWindowS.
-     */
-    @java.lang.Override
-    public float getMonitoringWindowS() {
-      return monitoringWindowS_;
-    }
-
-    public static final int SAMPLING_RATE_S_FIELD_NUMBER = 3;
-    private float samplingRateS_;
-    /**
-     * <code>float sampling_rate_s = 3;</code>
-     * @return The samplingRateS.
-     */
-    @java.lang.Override
-    public float getSamplingRateS() {
-      return samplingRateS_;
-    }
-
-    public static final int LAST_N_SAMPLES_FIELD_NUMBER = 4;
-    private int lastNSamples_;
-    /**
-     * <pre>
-     * used when you want something like "get the last N many samples
-     * </pre>
-     *
-     * <code>uint32 last_n_samples = 4;</code>
-     * @return The lastNSamples.
-     */
-    @java.lang.Override
-    public int getLastNSamples() {
-      return lastNSamples_;
-    }
 
-    public static final int START_DATE_FIELD_NUMBER = 5;
-    private volatile java.lang.Object startDate_;
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The startDate.
-     */
-    @java.lang.Override
-    public java.lang.String getStartDate() {
-      java.lang.Object ref = startDate_;
-      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();
-        startDate_ = s;
-        return s;
-      }
-    }
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 5;</code>
-     * @return The bytes for startDate.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStartDateBytes() {
-      java.lang.Object ref = startDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        startDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
       }
-    }
 
-    public static final int END_DATE_FIELD_NUMBER = 6;
-    private volatile java.lang.Object endDate_;
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The endDate.
-     */
-    @java.lang.Override
-    public java.lang.String getEndDate() {
-      java.lang.Object ref = endDate_;
-      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();
-        endDate_ = s;
-        return s;
-      }
-    }
-    /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 6;</code>
-     * @return The bytes for endDate.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getEndDateBytes() {
-      java.lang.Object ref = endDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        endDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.KpiQuery parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.KpiQuery) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
       }
-    }
+      private int bitField0_;
 
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
+      private java.util.List<monitoring.Monitoring.KpiId> kpiId_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiIdIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiId_);
+          bitField0_ |= 0x00000001;
+         }
+      }
 
-      memoizedIsInitialized = 1;
-      return true;
-    }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
 
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      for (int i = 0; i < kpiId_.size(); i++) {
-        output.writeMessage(1, kpiId_.get(i));
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+        if (kpiIdBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        } else {
+          return kpiIdBuilder_.getMessageList();
+        }
       }
-      if (monitoringWindowS_ != 0F) {
-        output.writeFloat(2, monitoringWindowS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public int getKpiIdCount() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.size();
+        } else {
+          return kpiIdBuilder_.getCount();
+        }
       }
-      if (samplingRateS_ != 0F) {
-        output.writeFloat(3, samplingRateS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId getKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);
+        } else {
+          return kpiIdBuilder_.getMessage(index);
+        }
       }
-      if (lastNSamples_ != 0) {
-        output.writeUInt32(4, lastNSamples_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, value);
+        }
+        return this;
       }
-      if (!getStartDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, startDate_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (!getEndDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, endDate_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(value);
+        }
+        return this;
       }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      for (int i = 0; i < kpiId_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, kpiId_.get(i));
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, value);
+        }
+        return this;
       }
-      if (monitoringWindowS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(2, monitoringWindowS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
       }
-      if (samplingRateS_ != 0F) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(3, samplingRateS_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (lastNSamples_ != 0) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(4, lastNSamples_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder addAllKpiId(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiId_);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiIdBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder removeKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.remove(index);
+          onChanged();
+        } else {
+          kpiIdBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
+          int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);  } else {
+          return kpiIdBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+           getKpiIdOrBuilderList() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder() {
+        return getKpiIdFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiId.getDefaultInstance());
       }
-      if (!getStartDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, startDate_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
+           getKpiIdBuilderList() {
+        return getKpiIdFieldBuilder().getBuilderList();
       }
-      if (!getEndDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, endDate_);
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  kpiId_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
       }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
 
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
+      private float monitoringWindowS_ ;
+      /**
+       * <code>float monitoring_window_s = 2;</code>
+       * @return The monitoringWindowS.
+       */
+      @java.lang.Override
+      public float getMonitoringWindowS() {
+        return monitoringWindowS_;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiQuery)) {
-        return super.equals(obj);
+      /**
+       * <code>float monitoring_window_s = 2;</code>
+       * @param value The monitoringWindowS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setMonitoringWindowS(float value) {
+        
+        monitoringWindowS_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float monitoring_window_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearMonitoringWindowS() {
+        
+        monitoringWindowS_ = 0F;
+        onChanged();
+        return this;
       }
-      monitoring.Monitoring.KpiQuery other = (monitoring.Monitoring.KpiQuery) obj;
-
-      if (!getKpiIdList()
-          .equals(other.getKpiIdList())) return false;
-      if (java.lang.Float.floatToIntBits(getMonitoringWindowS())
-          != java.lang.Float.floatToIntBits(
-              other.getMonitoringWindowS())) return false;
-      if (java.lang.Float.floatToIntBits(getSamplingRateS())
-          != java.lang.Float.floatToIntBits(
-              other.getSamplingRateS())) return false;
-      if (getLastNSamples()
-          != other.getLastNSamples()) return false;
-      if (!getStartDate()
-          .equals(other.getStartDate())) return false;
-      if (!getEndDate()
-          .equals(other.getEndDate())) return false;
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
 
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
+      private float samplingRateS_ ;
+      /**
+       * <code>float sampling_rate_s = 3;</code>
+       * @return The samplingRateS.
+       */
+      @java.lang.Override
+      public float getSamplingRateS() {
+        return samplingRateS_;
       }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      if (getKpiIdCount() > 0) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiIdList().hashCode();
+      /**
+       * <code>float sampling_rate_s = 3;</code>
+       * @param value The samplingRateS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSamplingRateS(float value) {
+        
+        samplingRateS_ = value;
+        onChanged();
+        return this;
       }
-      hash = (37 * hash) + MONITORING_WINDOW_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getMonitoringWindowS());
-      hash = (37 * hash) + SAMPLING_RATE_S_FIELD_NUMBER;
-      hash = (53 * hash) + java.lang.Float.floatToIntBits(
-          getSamplingRateS());
-      hash = (37 * hash) + LAST_N_SAMPLES_FIELD_NUMBER;
-      hash = (53 * hash) + getLastNSamples();
-      hash = (37 * hash) + START_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getStartDate().hashCode();
-      hash = (37 * hash) + END_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getEndDate().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.KpiQuery parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.KpiQuery 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.KpiQuery 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.KpiQuery}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiQuery)
-        monitoring.Monitoring.KpiQueryOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
+      /**
+       * <code>float sampling_rate_s = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingRateS() {
+        
+        samplingRateS_ = 0F;
+        onChanged();
+        return this;
       }
 
+      private int lastNSamples_ ;
+      /**
+       * <pre>
+       * used when you want something like "get the last N many samples
+       * </pre>
+       *
+       * <code>uint32 last_n_samples = 4;</code>
+       * @return The lastNSamples.
+       */
       @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiQuery.class, monitoring.Monitoring.KpiQuery.Builder.class);
+      public int getLastNSamples() {
+        return lastNSamples_;
       }
-
-      // Construct using monitoring.Monitoring.KpiQuery.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
+      /**
+       * <pre>
+       * used when you want something like "get the last N many samples
+       * </pre>
+       *
+       * <code>uint32 last_n_samples = 4;</code>
+       * @param value The lastNSamples to set.
+       * @return This builder for chaining.
+       */
+      public Builder setLastNSamples(int value) {
+        
+        lastNSamples_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the last N many samples
+       * </pre>
+       *
+       * <code>uint32 last_n_samples = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearLastNSamples() {
+        
+        lastNSamples_ = 0;
+        onChanged();
+        return this;
       }
 
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
+      private context.ContextOuterClass.Timestamp startTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> startTimestampBuilder_;
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return Whether the startTimestamp field is set.
+       */
+      public boolean hasStartTimestamp() {
+        return startTimestampBuilder_ != null || startTimestamp_ != null;
       }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-          getKpiIdFieldBuilder();
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return The startTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
+        } else {
+          return startTimestampBuilder_.getMessage();
         }
       }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder setStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          startTimestamp_ = value;
+          onChanged();
         } else {
-          kpiIdBuilder_.clear();
+          startTimestampBuilder_.setMessage(value);
         }
-        monitoringWindowS_ = 0F;
-
-        samplingRateS_ = 0F;
-
-        lastNSamples_ = 0;
-
-        startDate_ = "";
-
-        endDate_ = "";
 
         return this;
       }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiQuery_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.KpiQuery getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiQuery.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.KpiQuery build() {
-        monitoring.Monitoring.KpiQuery result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder setStartTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          startTimestampBuilder_.setMessage(builderForValue.build());
         }
-        return result;
-      }
 
-      @java.lang.Override
-      public monitoring.Monitoring.KpiQuery buildPartial() {
-        monitoring.Monitoring.KpiQuery result = new monitoring.Monitoring.KpiQuery(this);
-        int from_bitField0_ = bitField0_;
-        if (kpiIdBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
-            bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder mergeStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (startTimestamp_ != null) {
+            startTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(startTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            startTimestamp_ = value;
           }
-          result.kpiId_ = kpiId_;
+          onChanged();
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          startTimestampBuilder_.mergeFrom(value);
         }
-        result.monitoringWindowS_ = monitoringWindowS_;
-        result.samplingRateS_ = samplingRateS_;
-        result.lastNSamples_ = lastNSamples_;
-        result.startDate_ = startDate_;
-        result.endDate_ = endDate_;
-        onBuilt();
-        return result;
-      }
 
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
+        return this;
       }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public Builder clearStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
+          onChanged();
+        } else {
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
+        }
+
+        return this;
       }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getStartTimestampBuilder() {
+        
+        onChanged();
+        return getStartTimestampFieldBuilder().getBuilder();
       }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+        if (startTimestampBuilder_ != null) {
+          return startTimestampBuilder_.getMessageOrBuilder();
+        } else {
+          return startTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
+        }
       }
-      @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>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getStartTimestampFieldBuilder() {
+        if (startTimestampBuilder_ == null) {
+          startTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getStartTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          startTimestamp_ = null;
+        }
+        return startTimestampBuilder_;
       }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
+
+      private context.ContextOuterClass.Timestamp endTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> endTimestampBuilder_;
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return Whether the endTimestamp field is set.
+       */
+      public boolean hasEndTimestamp() {
+        return endTimestampBuilder_ != null || endTimestamp_ != null;
       }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiQuery) {
-          return mergeFrom((monitoring.Monitoring.KpiQuery)other);
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return The endTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
         } else {
-          super.mergeFrom(other);
-          return this;
+          return endTimestampBuilder_.getMessage();
         }
       }
-
-      public Builder mergeFrom(monitoring.Monitoring.KpiQuery other) {
-        if (other == monitoring.Monitoring.KpiQuery.getDefaultInstance()) return this;
-        if (kpiIdBuilder_ == null) {
-          if (!other.kpiId_.isEmpty()) {
-            if (kpiId_.isEmpty()) {
-              kpiId_ = other.kpiId_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiIdIsMutable();
-              kpiId_.addAll(other.kpiId_);
-            }
-            onChanged();
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder setEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          endTimestamp_ = value;
+          onChanged();
         } else {
-          if (!other.kpiId_.isEmpty()) {
-            if (kpiIdBuilder_.isEmpty()) {
-              kpiIdBuilder_.dispose();
-              kpiIdBuilder_ = null;
-              kpiId_ = other.kpiId_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiIdBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiIdFieldBuilder() : null;
-            } else {
-              kpiIdBuilder_.addAllMessages(other.kpiId_);
-            }
-          }
-        }
-        if (other.getMonitoringWindowS() != 0F) {
-          setMonitoringWindowS(other.getMonitoringWindowS());
+          endTimestampBuilder_.setMessage(value);
         }
-        if (other.getSamplingRateS() != 0F) {
-          setSamplingRateS(other.getSamplingRateS());
-        }
-        if (other.getLastNSamples() != 0) {
-          setLastNSamples(other.getLastNSamples());
+
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder setEndTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          endTimestampBuilder_.setMessage(builderForValue.build());
         }
-        if (!other.getStartDate().isEmpty()) {
-          startDate_ = other.startDate_;
+
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder mergeEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (endTimestamp_ != null) {
+            endTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(endTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            endTimestamp_ = value;
+          }
           onChanged();
+        } else {
+          endTimestampBuilder_.mergeFrom(value);
         }
-        if (!other.getEndDate().isEmpty()) {
-          endDate_ = other.endDate_;
+
+        return this;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public Builder clearEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
           onChanged();
+        } else {
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
         }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
+
         return this;
       }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getEndTimestampBuilder() {
+        
+        onChanged();
+        return getEndTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+        if (endTimestampBuilder_ != null) {
+          return endTimestampBuilder_.getMessageOrBuilder();
+        } else {
+          return endTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
+        }
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getEndTimestampFieldBuilder() {
+        if (endTimestampBuilder_ == null) {
+          endTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getEndTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          endTimestamp_ = null;
+        }
+        return endTimestampBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
 
       @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
 
+
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiQuery)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.KpiQuery)
+    private static final monitoring.Monitoring.KpiQuery DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiQuery();
+    }
+
+    public static monitoring.Monitoring.KpiQuery getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<KpiQuery>
+        PARSER = new com.google.protobuf.AbstractParser<KpiQuery>() {
       @java.lang.Override
-      public Builder mergeFrom(
+      public KpiQuery parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        monitoring.Monitoring.KpiQuery parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiQuery) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new KpiQuery(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<KpiQuery> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<KpiQuery> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.KpiQuery 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;
+            }
           }
         }
-        return this;
+      } 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();
       }
-      private int bitField0_;
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+    }
 
-      private java.util.List<monitoring.Monitoring.KpiId> kpiId_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiIdIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiId_);
-          bitField0_ |= 0x00000001;
-         }
+    @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);
+    }
 
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
 
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
-        if (kpiIdBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiId_);
-        } else {
-          return kpiIdBuilder_.getMessageList();
-        }
+      size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public int getKpiIdCount() {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_.size();
-        } else {
-          return kpiIdBuilder_.getCount();
-        }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId getKpiId(int index) {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_.get(index);
-        } else {
-          return kpiIdBuilder_.getMessage(index);
-        }
+      if (!(obj instanceof monitoring.Monitoring.KpiId)) {
+        return super.equals(obj);
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder setKpiId(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdIsMutable();
-          kpiId_.set(index, value);
-          onChanged();
-        } else {
-          kpiIdBuilder_.setMessage(index, value);
-        }
-        return this;
+      monitoring.Monitoring.KpiId other = (monitoring.Monitoring.KpiId) obj;
+
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder setKpiId(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdIsMutable();
-          kpiId_.add(value);
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(value);
-        }
-        return this;
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(
-          int index, monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiIdIsMutable();
-          kpiId_.add(index, value);
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(index, value);
-        }
-        return this;
+      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;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.add(builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
+
+      @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);
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addKpiId(
-          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          kpiIdBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
+
+      // Construct using monitoring.Monitoring.KpiId.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder addAllKpiId(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
-        if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiId_);
-          onChanged();
-        } else {
-          kpiIdBuilder_.addAllMessages(values);
-        }
-        return this;
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder clearKpiId() {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
-        } else {
-          kpiIdBuilder_.clear();
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
-        return this;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public Builder removeKpiId(int index) {
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
         if (kpiIdBuilder_ == null) {
-          ensureKpiIdIsMutable();
-          kpiId_.remove(index);
-          onChanged();
+          kpiId_ = null;
         } else {
-          kpiIdBuilder_.remove(index);
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
         return this;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder(
-          int index) {
-        return getKpiIdFieldBuilder().getBuilder(index);
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
-          int index) {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_.get(index);  } else {
-          return kpiIdBuilder_.getMessageOrBuilder(index);
-        }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiId.getDefaultInstance();
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
-           getKpiIdOrBuilderList() {
-        if (kpiIdBuilder_ != null) {
-          return kpiIdBuilder_.getMessageOrBuilderList();
-        } else {
-          return java.util.Collections.unmodifiableList(kpiId_);
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId build() {
+        monitoring.Monitoring.KpiId result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
+        return result;
       }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder() {
-        return getKpiIdFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder(
-          int index) {
-        return getKpiIdFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiId.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.KpiId kpi_id = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
-           getKpiIdBuilderList() {
-        return getKpiIdFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
-          getKpiIdFieldBuilder() {
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId buildPartial() {
+        monitoring.Monitoring.KpiId result = new monitoring.Monitoring.KpiId(this);
         if (kpiIdBuilder_ == null) {
-          kpiIdBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
-                  kpiId_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          kpiId_ = null;
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
         }
-        return kpiIdBuilder_;
+        onBuilt();
+        return result;
       }
 
-      private float monitoringWindowS_ ;
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return The monitoringWindowS.
-       */
       @java.lang.Override
-      public float getMonitoringWindowS() {
-        return monitoringWindowS_;
-      }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @param value The monitoringWindowS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setMonitoringWindowS(float value) {
-        
-        monitoringWindowS_ = value;
-        onChanged();
-        return this;
+      public Builder clone() {
+        return super.clone();
       }
-      /**
-       * <code>float monitoring_window_s = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearMonitoringWindowS() {
-        
-        monitoringWindowS_ = 0F;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
       }
-
-      private float samplingRateS_ ;
-      /**
-       * <code>float sampling_rate_s = 3;</code>
-       * @return The samplingRateS.
-       */
       @java.lang.Override
-      public float getSamplingRateS() {
-        return samplingRateS_;
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
       }
-      /**
-       * <code>float sampling_rate_s = 3;</code>
-       * @param value The samplingRateS to set.
-       * @return This builder for chaining.
-       */
-      public Builder setSamplingRateS(float value) {
-        
-        samplingRateS_ = value;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
       }
-      /**
-       * <code>float sampling_rate_s = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSamplingRateS() {
-        
-        samplingRateS_ = 0F;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
       }
-
-      private int lastNSamples_ ;
-      /**
-       * <pre>
-       * used when you want something like "get the last N many samples
-       * </pre>
-       *
-       * <code>uint32 last_n_samples = 4;</code>
-       * @return The lastNSamples.
-       */
       @java.lang.Override
-      public int getLastNSamples() {
-        return lastNSamples_;
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
       }
-      /**
-       * <pre>
-       * used when you want something like "get the last N many samples
-       * </pre>
-       *
-       * <code>uint32 last_n_samples = 4;</code>
-       * @param value The lastNSamples to set.
-       * @return This builder for chaining.
-       */
-      public Builder setLastNSamples(int value) {
-        
-        lastNSamples_ = 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;
       }
-      /**
-       * <pre>
-       * used when you want something like "get the last N many samples
-       * </pre>
-       *
-       * <code>uint32 last_n_samples = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearLastNSamples() {
-        
-        lastNSamples_ = 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 {
+        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 java.lang.Object startDate_ = "";
+      private context.ContextOuterClass.Uuid kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> kpiIdBuilder_;
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @return The startDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
        */
-      public java.lang.String getStartDate() {
-        java.lang.Object ref = startDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          startDate_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @return The bytes for startDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
+       * @return The kpiId.
        */
-      public com.google.protobuf.ByteString
-          getStartDateBytes() {
-        java.lang.Object ref = startDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          startDate_ = b;
-          return b;
+      public context.ContextOuterClass.Uuid getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          return kpiIdBuilder_.getMessage();
         }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @param value The startDate to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStartDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        startDate_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder clearStartDate() {
-        
-        startDate_ = getDefaultInstance().getStartDate();
-        onChanged();
+      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;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 5;</code>
-       * @param value The bytes for startDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder setStartDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        startDate_ = value;
-        onChanged();
+      public Builder setKpiId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
         return this;
       }
-
-      private java.lang.Object endDate_ = "";
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @return The endDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public java.lang.String getEndDate() {
-        java.lang.Object ref = endDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          endDate_ = s;
-          return s;
+      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 {
-          return (java.lang.String) ref;
+          kpiIdBuilder_.mergeFrom(value);
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @return The bytes for endDate.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public com.google.protobuf.ByteString
-          getEndDateBytes() {
-        java.lang.Object ref = endDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          endDate_ = b;
-          return b;
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @param value The endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder setEndDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        endDate_ = value;
+      public context.ContextOuterClass.Uuid.Builder getKpiIdBuilder() {
+        
         onChanged();
-        return this;
+        return getKpiIdFieldBuilder().getBuilder();
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder clearEndDate() {
-        
-        endDate_ = getDefaultInstance().getEndDate();
-        onChanged();
-        return this;
+      public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+        }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 6;</code>
-       * @param value The bytes for endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid kpi_id = 1;</code>
        */
-      public Builder setEndDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        endDate_ = value;
-        onChanged();
-        return this;
+      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(
@@ -7572,85 +4998,115 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiQuery)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiId)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiQuery)
-    private static final monitoring.Monitoring.KpiQuery DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiId)
+    private static final monitoring.Monitoring.KpiId DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiQuery();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiId();
     }
 
-    public static monitoring.Monitoring.KpiQuery getDefaultInstance() {
+    public static monitoring.Monitoring.KpiId getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiQuery>
-        PARSER = new com.google.protobuf.AbstractParser<KpiQuery>() {
+    private static final com.google.protobuf.Parser<KpiId>
+        PARSER = new com.google.protobuf.AbstractParser<KpiId>() {
       @java.lang.Override
-      public KpiQuery parsePartialFrom(
+      public KpiId parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiQuery(input, extensionRegistry);
+        return new KpiId(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiQuery> parser() {
+    public static com.google.protobuf.Parser<KpiId> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiQuery> getParserForType() {
+    public com.google.protobuf.Parser<KpiId> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiQuery getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiIdOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiId)
+  public interface KpiOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.Kpi)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return Whether the kpiId field is set.
      */
     boolean hasKpiId();
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return The kpiId.
      */
-    context.ContextOuterClass.Uuid getKpiId();
+    monitoring.Monitoring.KpiId getKpiId();
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder();
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return Whether the timestamp field is set.
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return The timestamp.
+     */
+    context.ContextOuterClass.Timestamp getTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder();
+
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    boolean hasKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * @return The kpiValue.
+     */
+    monitoring.Monitoring.KpiValue getKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     */
+    monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.KpiId}
+   * Protobuf type {@code monitoring.Kpi}
    */
-  public static final class KpiId extends
+  public static final class Kpi extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiId)
-      KpiIdOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.Kpi)
+      KpiOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiId.newBuilder() to construct.
-    private KpiId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use Kpi.newBuilder() to construct.
+    private Kpi(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiId() {
+    private Kpi() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiId();
+      return new Kpi();
     }
 
     @java.lang.Override
@@ -7658,7 +5114,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiId(
+    private Kpi(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -7677,11 +5133,11 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
               if (kpiId_ != null) {
                 subBuilder = kpiId_.toBuilder();
               }
-              kpiId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(kpiId_);
                 kpiId_ = subBuilder.buildPartial();
@@ -7689,6 +5145,32 @@ public final class Monitoring {
 
               break;
             }
+            case 18: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (timestamp_ != null) {
+                subBuilder = timestamp_.toBuilder();
+              }
+              timestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(timestamp_);
+                timestamp_ = subBuilder.buildPartial();
+              }
+
+              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)) {
@@ -7710,21 +5192,21 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiId_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiId.class, monitoring.Monitoring.KpiId.Builder.class);
+              monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
     }
 
     public static final int KPI_ID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid kpiId_;
+    private monitoring.Monitoring.KpiId kpiId_;
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return Whether the kpiId field is set.
      */
     @java.lang.Override
@@ -7732,21 +5214,73 @@ public final class Monitoring {
       return kpiId_ != null;
     }
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      * @return The kpiId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getKpiId() {
-      return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
     }
     /**
-     * <code>.context.Uuid kpi_id = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
       return getKpiId();
     }
 
+    public static final int TIMESTAMP_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.Timestamp timestamp_;
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return Whether the timestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasTimestamp() {
+      return timestamp_ != null;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getTimestamp() {
+      return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+      return getTimestamp();
+    }
+
+    public static final int KPI_VALUE_FIELD_NUMBER = 3;
+    private monitoring.Monitoring.KpiValue kpiValue_;
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiValue() {
+      return kpiValue_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 3;</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 = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
+      return getKpiValue();
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -7764,6 +5298,12 @@ public final class Monitoring {
       if (kpiId_ != null) {
         output.writeMessage(1, getKpiId());
       }
+      if (timestamp_ != null) {
+        output.writeMessage(2, getTimestamp());
+      }
+      if (kpiValue_ != null) {
+        output.writeMessage(3, getKpiValue());
+      }
       unknownFields.writeTo(output);
     }
 
@@ -7777,6 +5317,14 @@ public final class Monitoring {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getKpiId());
       }
+      if (timestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getTimestamp());
+      }
+      if (kpiValue_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getKpiValue());
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -7787,16 +5335,26 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiId)) {
+      if (!(obj instanceof monitoring.Monitoring.Kpi)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiId other = (monitoring.Monitoring.KpiId) 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 (hasTimestamp() != other.hasTimestamp()) return false;
+      if (hasTimestamp()) {
+        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;
     }
@@ -7812,74 +5370,82 @@ public final class Monitoring {
         hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
         hash = (53 * hash) + getKpiId().hashCode();
       }
+      if (hasTimestamp()) {
+        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.KpiId parseFrom(
+    public static monitoring.Monitoring.Kpi parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiId parseFrom(
+    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.KpiId parseFrom(
+    public static monitoring.Monitoring.Kpi parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiId parseFrom(
+    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.KpiId parseFrom(byte[] data)
+    public static monitoring.Monitoring.Kpi parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiId parseFrom(
+    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.KpiId parseFrom(java.io.InputStream input)
+    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.KpiId parseFrom(
+    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.KpiId parseDelimitedFrom(java.io.InputStream input)
+    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.KpiId parseDelimitedFrom(
+    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.KpiId parseFrom(
+    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.KpiId parseFrom(
+    public static monitoring.Monitoring.Kpi parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -7892,7 +5458,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiId prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.Kpi prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -7908,26 +5474,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiId}
+     * Protobuf type {@code monitoring.Kpi}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiId)
-        monitoring.Monitoring.KpiIdOrBuilder {
+        // @@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_KpiId_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiId_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiId.class, monitoring.Monitoring.KpiId.Builder.class);
+                monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiId.newBuilder()
+      // Construct using monitoring.Monitoring.Kpi.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -7951,23 +5517,35 @@ public final class Monitoring {
           kpiId_ = null;
           kpiIdBuilder_ = null;
         }
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
+        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_KpiId_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiId.getDefaultInstance();
+      public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
+        return monitoring.Monitoring.Kpi.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiId build() {
-        monitoring.Monitoring.KpiId result = buildPartial();
+      public monitoring.Monitoring.Kpi build() {
+        monitoring.Monitoring.Kpi result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -7975,13 +5553,23 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiId buildPartial() {
-        monitoring.Monitoring.KpiId result = new monitoring.Monitoring.KpiId(this);
+      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();
         }
+        if (timestampBuilder_ == null) {
+          result.timestamp_ = timestamp_;
+        } else {
+          result.timestamp_ = timestampBuilder_.build();
+        }
+        if (kpiValueBuilder_ == null) {
+          result.kpiValue_ = kpiValue_;
+        } else {
+          result.kpiValue_ = kpiValueBuilder_.build();
+        }
         onBuilt();
         return result;
       }
@@ -8020,19 +5608,25 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiId) {
-          return mergeFrom((monitoring.Monitoring.KpiId)other);
+        if (other instanceof monitoring.Monitoring.Kpi) {
+          return mergeFrom((monitoring.Monitoring.Kpi)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.KpiId other) {
-        if (other == monitoring.Monitoring.KpiId.getDefaultInstance()) 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.hasTimestamp()) {
+          mergeTimestamp(other.getTimestamp());
+        }
+        if (other.hasKpiValue()) {
+          mergeKpiValue(other.getKpiValue());
+        }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
@@ -8048,11 +5642,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiId parsedMessage = null;
+        monitoring.Monitoring.Kpi parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiId) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.Kpi) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -8062,31 +5656,31 @@ public final class Monitoring {
         return this;
       }
 
-      private context.ContextOuterClass.Uuid kpiId_;
+      private monitoring.Monitoring.KpiId kpiId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> kpiIdBuilder_;
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId 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>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        * @return The kpiId.
        */
-      public context.ContextOuterClass.Uuid getKpiId() {
+      public monitoring.Monitoring.KpiId getKpiId() {
         if (kpiIdBuilder_ == null) {
-          return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         } else {
           return kpiIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder setKpiId(context.ContextOuterClass.Uuid value) {
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
         if (kpiIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
@@ -8100,10 +5694,10 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
       public Builder setKpiId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
         if (kpiIdBuilder_ == null) {
           kpiId_ = builderForValue.build();
           onChanged();
@@ -8114,13 +5708,13 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public Builder mergeKpiId(context.ContextOuterClass.Uuid value) {
+      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
         if (kpiIdBuilder_ == null) {
           if (kpiId_ != null) {
             kpiId_ =
-              context.ContextOuterClass.Uuid.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
           } else {
             kpiId_ = value;
           }
@@ -8132,7 +5726,7 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
       public Builder clearKpiId() {
         if (kpiIdBuilder_ == null) {
@@ -8146,33 +5740,33 @@ public final class Monitoring {
         return this;
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public context.ContextOuterClass.Uuid.Builder getKpiIdBuilder() {
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
         
         onChanged();
         return getKpiIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
-      public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
         if (kpiIdBuilder_ != null) {
           return kpiIdBuilder_.getMessageOrBuilder();
         } else {
           return kpiId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         }
       }
       /**
-       * <code>.context.Uuid kpi_id = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
           getKpiIdFieldBuilder() {
         if (kpiIdBuilder_ == null) {
           kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
                   getKpiId(),
                   getParentForChildren(),
                   isClean());
@@ -8180,6 +5774,244 @@ public final class Monitoring {
         }
         return kpiIdBuilder_;
       }
+
+      private context.ContextOuterClass.Timestamp timestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> timestampBuilder_;
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       * @return Whether the timestamp field is set.
+       */
+      public boolean hasTimestamp() {
+        return timestampBuilder_ != null || timestamp_ != null;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       * @return The timestamp.
+       */
+      public context.ContextOuterClass.Timestamp getTimestamp() {
+        if (timestampBuilder_ == null) {
+          return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        } else {
+          return timestampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder setTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          timestamp_ = value;
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder setTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (timestampBuilder_ == null) {
+          timestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder mergeTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (timestamp_ != null) {
+            timestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(timestamp_).mergeFrom(value).buildPartial();
+          } else {
+            timestamp_ = value;
+          }
+          onChanged();
+        } else {
+          timestampBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public Builder clearTimestamp() {
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+          onChanged();
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getTimestampBuilder() {
+        
+        onChanged();
+        return getTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+        if (timestampBuilder_ != null) {
+          return timestampBuilder_.getMessageOrBuilder();
+        } else {
+          return timestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getTimestampFieldBuilder() {
+        if (timestampBuilder_ == null) {
+          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          timestamp_ = null;
+        }
+        return timestampBuilder_;
+      }
+
+      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 = 3;</code>
+       * @return Whether the kpiValue field is set.
+       */
+      public boolean hasKpiValue() {
+        return kpiValueBuilder_ != null || kpiValue_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 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 kpi_value = 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 kpi_value = 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 kpi_value = 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 kpi_value = 3;</code>
+       */
+      public Builder clearKpiValue() {
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = null;
+          onChanged();
+        } else {
+          kpiValue_ = null;
+          kpiValueBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       */
+      public monitoring.Monitoring.KpiValue.Builder getKpiValueBuilder() {
+        
+        onChanged();
+        return getKpiValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 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 kpi_value = 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) {
@@ -8193,113 +6025,130 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiId)
+      // @@protoc_insertion_point(builder_scope:monitoring.Kpi)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiId)
-    private static final monitoring.Monitoring.KpiId DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.Kpi)
+    private static final monitoring.Monitoring.Kpi DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiId();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.Kpi();
     }
 
-    public static monitoring.Monitoring.KpiId getDefaultInstance() {
+    public static monitoring.Monitoring.Kpi getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiId>
-        PARSER = new com.google.protobuf.AbstractParser<KpiId>() {
+    private static final com.google.protobuf.Parser<Kpi>
+        PARSER = new com.google.protobuf.AbstractParser<Kpi>() {
       @java.lang.Override
-      public KpiId parsePartialFrom(
+      public Kpi parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiId(input, extensionRegistry);
+        return new Kpi(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiId> parser() {
+    public static com.google.protobuf.Parser<Kpi> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiId> getParserForType() {
+    public com.google.protobuf.Parser<Kpi> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
+    public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.Kpi)
+  public interface KpiValueRangeOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiValueRange)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return Whether the kpiMinValue field is set.
      */
-    boolean hasKpiId();
+    boolean hasKpiMinValue();
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return The kpiMinValue.
      */
-    monitoring.Monitoring.KpiId getKpiId();
+    monitoring.Monitoring.KpiValue getKpiMinValue();
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
      */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+    monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder();
 
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return Whether the kpiMaxValue field is set.
      */
-    java.lang.String getTimestamp();
+    boolean hasKpiMaxValue();
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The bytes for timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return The kpiMaxValue.
      */
-    com.google.protobuf.ByteString
-        getTimestampBytes();
+    monitoring.Monitoring.KpiValue getKpiMaxValue();
+    /**
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     */
+    monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder();
 
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return Whether the kpiValue field is set.
+     * <pre>
+     * by default True
+     * </pre>
+     *
+     * <code>bool inRange = 3;</code>
+     * @return The inRange.
      */
-    boolean hasKpiValue();
+    boolean getInRange();
+
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return The kpiValue.
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMinValue = 4;</code>
+     * @return The includeMinValue.
      */
-    monitoring.Monitoring.KpiValue getKpiValue();
+    boolean getIncludeMinValue();
+
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMaxValue = 5;</code>
+     * @return The includeMaxValue.
      */
-    monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
+    boolean getIncludeMaxValue();
   }
   /**
-   * Protobuf type {@code monitoring.Kpi}
+   * Protobuf type {@code monitoring.KpiValueRange}
    */
-  public static final class Kpi extends
+  public static final class KpiValueRange extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.Kpi)
-      KpiOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiValueRange)
+      KpiValueRangeOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use Kpi.newBuilder() to construct.
-    private Kpi(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiValueRange.newBuilder() to construct.
+    private KpiValueRange(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private Kpi() {
-      timestamp_ = "";
+    private KpiValueRange() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new Kpi();
+      return new KpiValueRange();
     }
 
     @java.lang.Override
@@ -8307,7 +6156,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private Kpi(
+    private KpiValueRange(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -8326,37 +6175,46 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              monitoring.Monitoring.KpiId.Builder subBuilder = null;
-              if (kpiId_ != null) {
-                subBuilder = kpiId_.toBuilder();
+              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
+              if (kpiMinValue_ != null) {
+                subBuilder = kpiMinValue_.toBuilder();
               }
-              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              kpiMinValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiId_);
-                kpiId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(kpiMinValue_);
+                kpiMinValue_ = subBuilder.buildPartial();
               }
 
               break;
             }
             case 18: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              timestamp_ = s;
-              break;
-            }
-            case 26: {
               monitoring.Monitoring.KpiValue.Builder subBuilder = null;
-              if (kpiValue_ != null) {
-                subBuilder = kpiValue_.toBuilder();
+              if (kpiMaxValue_ != null) {
+                subBuilder = kpiMaxValue_.toBuilder();
               }
-              kpiValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
+              kpiMaxValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiValue_);
-                kpiValue_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(kpiMaxValue_);
+                kpiMaxValue_ = subBuilder.buildPartial();
               }
 
               break;
             }
+            case 24: {
+
+              inRange_ = input.readBool();
+              break;
+            }
+            case 32: {
+
+              includeMinValue_ = input.readBool();
+              break;
+            }
+            case 40: {
+
+              includeMaxValue_ = input.readBool();
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -8378,105 +6236,112 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
+              monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
     }
 
-    public static final int KPI_ID_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.KpiId kpiId_;
+    public static final int KPIMINVALUE_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiValue kpiMinValue_;
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return Whether the kpiId field is set.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return Whether the kpiMinValue field is set.
      */
     @java.lang.Override
-    public boolean hasKpiId() {
-      return kpiId_ != null;
+    public boolean hasKpiMinValue() {
+      return kpiMinValue_ != null;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
-     * @return The kpiId.
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * @return The kpiMinValue.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiId getKpiId() {
-      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    public monitoring.Monitoring.KpiValue getKpiMinValue() {
+      return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
     }
     /**
-     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-      return getKpiId();
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
+      return getKpiMinValue();
     }
 
-    public static final int TIMESTAMP_FIELD_NUMBER = 2;
-    private volatile java.lang.Object timestamp_;
+    public static final int KPIMAXVALUE_FIELD_NUMBER = 2;
+    private monitoring.Monitoring.KpiValue kpiMaxValue_;
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return Whether the kpiMaxValue field is set.
      */
     @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;
-      }
+    public boolean hasKpiMaxValue() {
+      return kpiMaxValue_ != null;
     }
     /**
-     * <code>string timestamp = 2;</code>
-     * @return The bytes for timestamp.
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * @return The kpiMaxValue.
      */
     @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 monitoring.Monitoring.KpiValue getKpiMaxValue() {
+      return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
+      return getKpiMaxValue();
     }
 
-    public static final int KPI_VALUE_FIELD_NUMBER = 3;
-    private monitoring.Monitoring.KpiValue kpiValue_;
+    public static final int INRANGE_FIELD_NUMBER = 3;
+    private boolean inRange_;
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return Whether the kpiValue field is set.
+     * <pre>
+     * by default True
+     * </pre>
+     *
+     * <code>bool inRange = 3;</code>
+     * @return The inRange.
      */
     @java.lang.Override
-    public boolean hasKpiValue() {
-      return kpiValue_ != null;
+    public boolean getInRange() {
+      return inRange_;
     }
+
+    public static final int INCLUDEMINVALUE_FIELD_NUMBER = 4;
+    private boolean includeMinValue_;
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
-     * @return The kpiValue.
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMinValue = 4;</code>
+     * @return The includeMinValue.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getKpiValue() {
-      return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+    public boolean getIncludeMinValue() {
+      return includeMinValue_;
     }
+
+    public static final int INCLUDEMAXVALUE_FIELD_NUMBER = 5;
+    private boolean includeMaxValue_;
     /**
-     * <code>.monitoring.KpiValue kpi_value = 3;</code>
+     * <pre>
+     * False is outside the interval
+     * </pre>
+     *
+     * <code>bool includeMaxValue = 5;</code>
+     * @return The includeMaxValue.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
-      return getKpiValue();
+    public boolean getIncludeMaxValue() {
+      return includeMaxValue_;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -8493,14 +6358,20 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (kpiId_ != null) {
-        output.writeMessage(1, getKpiId());
+      if (kpiMinValue_ != null) {
+        output.writeMessage(1, getKpiMinValue());
       }
-      if (!getTimestampBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, timestamp_);
+      if (kpiMaxValue_ != null) {
+        output.writeMessage(2, getKpiMaxValue());
       }
-      if (kpiValue_ != null) {
-        output.writeMessage(3, getKpiValue());
+      if (inRange_ != false) {
+        output.writeBool(3, inRange_);
+      }
+      if (includeMinValue_ != false) {
+        output.writeBool(4, includeMinValue_);
+      }
+      if (includeMaxValue_ != false) {
+        output.writeBool(5, includeMaxValue_);
       }
       unknownFields.writeTo(output);
     }
@@ -8511,16 +6382,25 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (kpiId_ != null) {
+      if (kpiMinValue_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getKpiId());
+          .computeMessageSize(1, getKpiMinValue());
       }
-      if (!getTimestampBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, timestamp_);
+      if (kpiMaxValue_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getKpiMaxValue());
       }
-      if (kpiValue_ != null) {
+      if (inRange_ != false) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getKpiValue());
+          .computeBoolSize(3, inRange_);
+      }
+      if (includeMinValue_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(4, includeMinValue_);
+      }
+      if (includeMaxValue_ != false) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(5, includeMaxValue_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -8532,23 +6412,27 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.Kpi)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiValueRange)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.Kpi other = (monitoring.Monitoring.Kpi) obj;
+      monitoring.Monitoring.KpiValueRange other = (monitoring.Monitoring.KpiValueRange) obj;
 
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
+      if (hasKpiMinValue() != other.hasKpiMinValue()) return false;
+      if (hasKpiMinValue()) {
+        if (!getKpiMinValue()
+            .equals(other.getKpiMinValue())) 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 (hasKpiMaxValue() != other.hasKpiMaxValue()) return false;
+      if (hasKpiMaxValue()) {
+        if (!getKpiMaxValue()
+            .equals(other.getKpiMaxValue())) return false;
       }
+      if (getInRange()
+          != other.getInRange()) return false;
+      if (getIncludeMinValue()
+          != other.getIncludeMinValue()) return false;
+      if (getIncludeMaxValue()
+          != other.getIncludeMaxValue()) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -8560,84 +6444,91 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
+      if (hasKpiMinValue()) {
+        hash = (37 * hash) + KPIMINVALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiMinValue().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();
+      if (hasKpiMaxValue()) {
+        hash = (37 * hash) + KPIMAXVALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiMaxValue().hashCode();
       }
+      hash = (37 * hash) + INRANGE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+          getInRange());
+      hash = (37 * hash) + INCLUDEMINVALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+          getIncludeMinValue());
+      hash = (37 * hash) + INCLUDEMAXVALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+          getIncludeMaxValue());
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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)
+    public static monitoring.Monitoring.KpiValueRange parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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)
+    public static monitoring.Monitoring.KpiValueRange parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange 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)
+    public static monitoring.Monitoring.KpiValueRange parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.Kpi parseDelimitedFrom(
+    public static monitoring.Monitoring.KpiValueRange 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(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.Kpi parseFrom(
+    public static monitoring.Monitoring.KpiValueRange parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -8650,7 +6541,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.Kpi prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiValueRange prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -8666,26 +6557,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.Kpi}
+     * Protobuf type {@code monitoring.KpiValueRange}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.Kpi)
-        monitoring.Monitoring.KpiOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiValueRange)
+        monitoring.Monitoring.KpiValueRangeOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
+                monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.Kpi.newBuilder()
+      // Construct using monitoring.Monitoring.KpiValueRange.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -8703,37 +6594,41 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValue_ = null;
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          kpiMinValue_ = null;
+          kpiMinValueBuilder_ = null;
         }
-        timestamp_ = "";
-
-        if (kpiValueBuilder_ == null) {
-          kpiValue_ = null;
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValue_ = null;
         } else {
-          kpiValue_ = null;
-          kpiValueBuilder_ = null;
+          kpiMaxValue_ = null;
+          kpiMaxValueBuilder_ = null;
         }
+        inRange_ = false;
+
+        includeMinValue_ = false;
+
+        includeMaxValue_ = false;
+
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
-        return monitoring.Monitoring.Kpi.getDefaultInstance();
+      public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiValueRange.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.Kpi build() {
-        monitoring.Monitoring.Kpi result = buildPartial();
+      public monitoring.Monitoring.KpiValueRange build() {
+        monitoring.Monitoring.KpiValueRange result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -8741,19 +6636,21 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.Kpi buildPartial() {
-        monitoring.Monitoring.Kpi result = new monitoring.Monitoring.Kpi(this);
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
+      public monitoring.Monitoring.KpiValueRange buildPartial() {
+        monitoring.Monitoring.KpiValueRange result = new monitoring.Monitoring.KpiValueRange(this);
+        if (kpiMinValueBuilder_ == null) {
+          result.kpiMinValue_ = kpiMinValue_;
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          result.kpiMinValue_ = kpiMinValueBuilder_.build();
         }
-        result.timestamp_ = timestamp_;
-        if (kpiValueBuilder_ == null) {
-          result.kpiValue_ = kpiValue_;
+        if (kpiMaxValueBuilder_ == null) {
+          result.kpiMaxValue_ = kpiMaxValue_;
         } else {
-          result.kpiValue_ = kpiValueBuilder_.build();
+          result.kpiMaxValue_ = kpiMaxValueBuilder_.build();
         }
+        result.inRange_ = inRange_;
+        result.includeMinValue_ = includeMinValue_;
+        result.includeMaxValue_ = includeMaxValue_;
         onBuilt();
         return result;
       }
@@ -8792,25 +6689,30 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.Kpi) {
-          return mergeFrom((monitoring.Monitoring.Kpi)other);
+        if (other instanceof monitoring.Monitoring.KpiValueRange) {
+          return mergeFrom((monitoring.Monitoring.KpiValueRange)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());
+      public Builder mergeFrom(monitoring.Monitoring.KpiValueRange other) {
+        if (other == monitoring.Monitoring.KpiValueRange.getDefaultInstance()) return this;
+        if (other.hasKpiMinValue()) {
+          mergeKpiMinValue(other.getKpiMinValue());
         }
-        if (!other.getTimestamp().isEmpty()) {
-          timestamp_ = other.timestamp_;
-          onChanged();
+        if (other.hasKpiMaxValue()) {
+          mergeKpiMaxValue(other.getKpiMaxValue());
         }
-        if (other.hasKpiValue()) {
-          mergeKpiValue(other.getKpiValue());
+        if (other.getInRange() != false) {
+          setInRange(other.getInRange());
+        }
+        if (other.getIncludeMinValue() != false) {
+          setIncludeMinValue(other.getIncludeMinValue());
+        }
+        if (other.getIncludeMaxValue() != false) {
+          setIncludeMaxValue(other.getIncludeMaxValue());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -8827,11 +6729,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.Kpi parsedMessage = null;
+        monitoring.Monitoring.KpiValueRange parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.Kpi) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiValueRange) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -8841,318 +6743,371 @@ public final class Monitoring {
         return this;
       }
 
-      private monitoring.Monitoring.KpiId kpiId_;
+      private monitoring.Monitoring.KpiValue kpiMinValue_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMinValueBuilder_;
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
-       * @return Whether the kpiId field is set.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * @return Whether the kpiMinValue field is set.
        */
-      public boolean hasKpiId() {
-        return kpiIdBuilder_ != null || kpiId_ != null;
+      public boolean hasKpiMinValue() {
+        return kpiMinValueBuilder_ != null || kpiMinValue_ != null;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
-       * @return The kpiId.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * @return The kpiMinValue.
        */
-      public monitoring.Monitoring.KpiId getKpiId() {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+      public monitoring.Monitoring.KpiValue getKpiMinValue() {
+        if (kpiMinValueBuilder_ == null) {
+          return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
         } else {
-          return kpiIdBuilder_.getMessage();
+          return kpiMinValueBuilder_.getMessage();
         }
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
+      public Builder setKpiMinValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMinValueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          kpiId_ = value;
+          kpiMinValue_ = value;
           onChanged();
         } else {
-          kpiIdBuilder_.setMessage(value);
+          kpiMinValueBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder setKpiId(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = builderForValue.build();
+      public Builder setKpiMinValue(
+          monitoring.Monitoring.KpiValue.Builder builderForValue) {
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValue_ = builderForValue.build();
           onChanged();
         } else {
-          kpiIdBuilder_.setMessage(builderForValue.build());
+          kpiMinValueBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (kpiId_ != null) {
-            kpiId_ =
-              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+      public Builder mergeKpiMinValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMinValueBuilder_ == null) {
+          if (kpiMinValue_ != null) {
+            kpiMinValue_ =
+              monitoring.Monitoring.KpiValue.newBuilder(kpiMinValue_).mergeFrom(value).buildPartial();
           } else {
-            kpiId_ = value;
+            kpiMinValue_ = value;
           }
           onChanged();
         } else {
-          kpiIdBuilder_.mergeFrom(value);
+          kpiMinValueBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder clearKpiId() {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+      public Builder clearKpiMinValue() {
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValue_ = null;
           onChanged();
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          kpiMinValue_ = null;
+          kpiMinValueBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+      public monitoring.Monitoring.KpiValue.Builder getKpiMinValueBuilder() {
         
         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;
-        }
+        return getKpiMinValueFieldBuilder().getBuilder();
       }
       /**
-       * <code>string timestamp = 2;</code>
-       * @return The bytes for timestamp.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      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;
+      public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
+        if (kpiMinValueBuilder_ != null) {
+          return kpiMinValueBuilder_.getMessageOrBuilder();
         } 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;
+          return kpiMinValue_ == null ?
+              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
+        }
       }
       /**
-       * <code>string timestamp = 2;</code>
-       * @param value The bytes for timestamp to set.
-       * @return This builder for chaining.
+       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
        */
-      public Builder setTimestampBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        timestamp_ = value;
-        onChanged();
-        return this;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
+          getKpiMinValueFieldBuilder() {
+        if (kpiMinValueBuilder_ == null) {
+          kpiMinValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
+                  getKpiMinValue(),
+                  getParentForChildren(),
+                  isClean());
+          kpiMinValue_ = null;
+        }
+        return kpiMinValueBuilder_;
       }
 
-      private monitoring.Monitoring.KpiValue kpiValue_;
+      private monitoring.Monitoring.KpiValue kpiMaxValue_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiValueBuilder_;
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMaxValueBuilder_;
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
-       * @return Whether the kpiValue field is set.
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * @return Whether the kpiMaxValue field is set.
        */
-      public boolean hasKpiValue() {
-        return kpiValueBuilder_ != null || kpiValue_ != null;
+      public boolean hasKpiMaxValue() {
+        return kpiMaxValueBuilder_ != null || kpiMaxValue_ != null;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
-       * @return The kpiValue.
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * @return The kpiMaxValue.
        */
-      public monitoring.Monitoring.KpiValue getKpiValue() {
-        if (kpiValueBuilder_ == null) {
-          return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+      public monitoring.Monitoring.KpiValue getKpiMaxValue() {
+        if (kpiMaxValueBuilder_ == null) {
+          return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
         } else {
-          return kpiValueBuilder_.getMessage();
+          return kpiMaxValueBuilder_.getMessage();
         }
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder setKpiValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiValueBuilder_ == null) {
+      public Builder setKpiMaxValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMaxValueBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          kpiValue_ = value;
+          kpiMaxValue_ = value;
           onChanged();
         } else {
-          kpiValueBuilder_.setMessage(value);
+          kpiMaxValueBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder setKpiValue(
+      public Builder setKpiMaxValue(
           monitoring.Monitoring.KpiValue.Builder builderForValue) {
-        if (kpiValueBuilder_ == null) {
-          kpiValue_ = builderForValue.build();
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValue_ = builderForValue.build();
           onChanged();
         } else {
-          kpiValueBuilder_.setMessage(builderForValue.build());
+          kpiMaxValueBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder mergeKpiValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiValueBuilder_ == null) {
-          if (kpiValue_ != null) {
-            kpiValue_ =
-              monitoring.Monitoring.KpiValue.newBuilder(kpiValue_).mergeFrom(value).buildPartial();
+      public Builder mergeKpiMaxValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiMaxValueBuilder_ == null) {
+          if (kpiMaxValue_ != null) {
+            kpiMaxValue_ =
+              monitoring.Monitoring.KpiValue.newBuilder(kpiMaxValue_).mergeFrom(value).buildPartial();
           } else {
-            kpiValue_ = value;
+            kpiMaxValue_ = value;
           }
           onChanged();
         } else {
-          kpiValueBuilder_.mergeFrom(value);
+          kpiMaxValueBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public Builder clearKpiValue() {
-        if (kpiValueBuilder_ == null) {
-          kpiValue_ = null;
+      public Builder clearKpiMaxValue() {
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValue_ = null;
           onChanged();
         } else {
-          kpiValue_ = null;
-          kpiValueBuilder_ = null;
+          kpiMaxValue_ = null;
+          kpiMaxValueBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public monitoring.Monitoring.KpiValue.Builder getKpiValueBuilder() {
+      public monitoring.Monitoring.KpiValue.Builder getKpiMaxValueBuilder() {
         
         onChanged();
-        return getKpiValueFieldBuilder().getBuilder();
+        return getKpiMaxValueFieldBuilder().getBuilder();
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
        */
-      public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
-        if (kpiValueBuilder_ != null) {
-          return kpiValueBuilder_.getMessageOrBuilder();
+      public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
+        if (kpiMaxValueBuilder_ != null) {
+          return kpiMaxValueBuilder_.getMessageOrBuilder();
         } else {
-          return kpiValue_ == null ?
-              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+          return kpiMaxValue_ == null ?
+              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
         }
       }
       /**
-       * <code>.monitoring.KpiValue kpi_value = 3;</code>
+       * <code>.monitoring.KpiValue kpiMaxValue = 2;</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<
+          getKpiMaxValueFieldBuilder() {
+        if (kpiMaxValueBuilder_ == null) {
+          kpiMaxValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
-                  getKpiValue(),
+                  getKpiMaxValue(),
                   getParentForChildren(),
                   isClean());
-          kpiValue_ = null;
+          kpiMaxValue_ = null;
         }
-        return kpiValueBuilder_;
+        return kpiMaxValueBuilder_;
+      }
+
+      private boolean inRange_ ;
+      /**
+       * <pre>
+       * by default True
+       * </pre>
+       *
+       * <code>bool inRange = 3;</code>
+       * @return The inRange.
+       */
+      @java.lang.Override
+      public boolean getInRange() {
+        return inRange_;
+      }
+      /**
+       * <pre>
+       * by default True
+       * </pre>
+       *
+       * <code>bool inRange = 3;</code>
+       * @param value The inRange to set.
+       * @return This builder for chaining.
+       */
+      public Builder setInRange(boolean value) {
+        
+        inRange_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * by default True
+       * </pre>
+       *
+       * <code>bool inRange = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearInRange() {
+        
+        inRange_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean includeMinValue_ ;
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMinValue = 4;</code>
+       * @return The includeMinValue.
+       */
+      @java.lang.Override
+      public boolean getIncludeMinValue() {
+        return includeMinValue_;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMinValue = 4;</code>
+       * @param value The includeMinValue to set.
+       * @return This builder for chaining.
+       */
+      public Builder setIncludeMinValue(boolean value) {
+        
+        includeMinValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMinValue = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearIncludeMinValue() {
+        
+        includeMinValue_ = false;
+        onChanged();
+        return this;
+      }
+
+      private boolean includeMaxValue_ ;
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMaxValue = 5;</code>
+       * @return The includeMaxValue.
+       */
+      @java.lang.Override
+      public boolean getIncludeMaxValue() {
+        return includeMaxValue_;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMaxValue = 5;</code>
+       * @param value The includeMaxValue to set.
+       * @return This builder for chaining.
+       */
+      public Builder setIncludeMaxValue(boolean value) {
+        
+        includeMaxValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * False is outside the interval
+       * </pre>
+       *
+       * <code>bool includeMaxValue = 5;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearIncludeMaxValue() {
+        
+        includeMaxValue_ = false;
+        onChanged();
+        return this;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -9167,100 +7122,155 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.Kpi)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiValueRange)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.Kpi)
-    private static final monitoring.Monitoring.Kpi DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiValueRange)
+    private static final monitoring.Monitoring.KpiValueRange DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.Kpi();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValueRange();
     }
 
-    public static monitoring.Monitoring.Kpi getDefaultInstance() {
+    public static monitoring.Monitoring.KpiValueRange getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<Kpi>
-        PARSER = new com.google.protobuf.AbstractParser<Kpi>() {
+    private static final com.google.protobuf.Parser<KpiValueRange>
+        PARSER = new com.google.protobuf.AbstractParser<KpiValueRange>() {
       @java.lang.Override
-      public Kpi parsePartialFrom(
+      public KpiValueRange parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Kpi(input, extensionRegistry);
+        return new KpiValueRange(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<Kpi> parser() {
+    public static com.google.protobuf.Parser<KpiValueRange> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<Kpi> getParserForType() {
+    public com.google.protobuf.Parser<KpiValueRange> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiValueRangeOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiValueRange)
+  public interface KpiValueOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiValue)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return Whether the kpiMinValue field is set.
+     * <code>int32 int32Val = 1;</code>
+     * @return Whether the int32Val field is set.
+     */
+    boolean hasInt32Val();
+    /**
+     * <code>int32 int32Val = 1;</code>
+     * @return The int32Val.
+     */
+    int getInt32Val();
+
+    /**
+     * <code>uint32 uint32Val = 2;</code>
+     * @return Whether the uint32Val field is set.
+     */
+    boolean hasUint32Val();
+    /**
+     * <code>uint32 uint32Val = 2;</code>
+     * @return The uint32Val.
+     */
+    int getUint32Val();
+
+    /**
+     * <code>int64 int64Val = 3;</code>
+     * @return Whether the int64Val field is set.
+     */
+    boolean hasInt64Val();
+    /**
+     * <code>int64 int64Val = 3;</code>
+     * @return The int64Val.
+     */
+    long getInt64Val();
+
+    /**
+     * <code>uint64 uint64Val = 4;</code>
+     * @return Whether the uint64Val field is set.
      */
-    boolean hasKpiMinValue();
+    boolean hasUint64Val();
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return The kpiMinValue.
+     * <code>uint64 uint64Val = 4;</code>
+     * @return The uint64Val.
      */
-    monitoring.Monitoring.KpiValue getKpiMinValue();
+    long getUint64Val();
+
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * <code>float floatVal = 5;</code>
+     * @return Whether the floatVal field is set.
      */
-    monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder();
+    boolean hasFloatVal();
+    /**
+     * <code>float floatVal = 5;</code>
+     * @return The floatVal.
+     */
+    float getFloatVal();
 
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return Whether the kpiMaxValue field is set.
+     * <code>string stringVal = 6;</code>
+     * @return Whether the stringVal field is set.
      */
-    boolean hasKpiMaxValue();
+    boolean hasStringVal();
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return The kpiMaxValue.
+     * <code>string stringVal = 6;</code>
+     * @return The stringVal.
      */
-    monitoring.Monitoring.KpiValue getKpiMaxValue();
+    java.lang.String getStringVal();
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * <code>string stringVal = 6;</code>
+     * @return The bytes for stringVal.
      */
-    monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder();
+    com.google.protobuf.ByteString
+        getStringValBytes();
+
+    /**
+     * <code>bool boolVal = 7;</code>
+     * @return Whether the boolVal field is set.
+     */
+    boolean hasBoolVal();
+    /**
+     * <code>bool boolVal = 7;</code>
+     * @return The boolVal.
+     */
+    boolean getBoolVal();
+
+    public monitoring.Monitoring.KpiValue.ValueCase getValueCase();
   }
   /**
-   * Protobuf type {@code monitoring.KpiValueRange}
+   * Protobuf type {@code monitoring.KpiValue}
    */
-  public static final class KpiValueRange extends
+  public static final class KpiValue extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiValueRange)
-      KpiValueRangeOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiValue)
+      KpiValueOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiValueRange.newBuilder() to construct.
-    private KpiValueRange(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiValue.newBuilder() to construct.
+    private KpiValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiValueRange() {
+    private KpiValue() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiValueRange();
+      return new KpiValue();
     }
 
     @java.lang.Override
@@ -9268,7 +7278,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiValueRange(
+    private KpiValue(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -9286,30 +7296,40 @@ public final class Monitoring {
             case 0:
               done = true;
               break;
-            case 10: {
-              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
-              if (kpiMinValue_ != null) {
-                subBuilder = kpiMinValue_.toBuilder();
-              }
-              kpiMinValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiMinValue_);
-                kpiMinValue_ = subBuilder.buildPartial();
-              }
-
+            case 8: {
+              valueCase_ = 1;
+              value_ = input.readInt32();
               break;
             }
-            case 18: {
-              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
-              if (kpiMaxValue_ != null) {
-                subBuilder = kpiMaxValue_.toBuilder();
-              }
-              kpiMaxValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiMaxValue_);
-                kpiMaxValue_ = subBuilder.buildPartial();
-              }
-
+            case 16: {
+              valueCase_ = 2;
+              value_ = input.readUInt32();
+              break;
+            }
+            case 24: {
+              valueCase_ = 3;
+              value_ = input.readInt64();
+              break;
+            }
+            case 32: {
+              valueCase_ = 4;
+              value_ = input.readUInt64();
+              break;
+            }
+            case 45: {
+              valueCase_ = 5;
+              value_ = input.readFloat();
+              break;
+            }
+            case 50: {
+              java.lang.String s = input.readStringRequireUtf8();
+              valueCase_ = 6;
+              value_ = s;
+              break;
+            }
+            case 56: {
+              valueCase_ = 7;
+              value_ = input.readBool();
               break;
             }
             default: {
@@ -9333,67 +7353,244 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
+              monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
     }
 
-    public static final int KPIMINVALUE_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.KpiValue kpiMinValue_;
+    private int valueCase_ = 0;
+    private java.lang.Object value_;
+    public enum ValueCase
+        implements com.google.protobuf.Internal.EnumLite,
+            com.google.protobuf.AbstractMessage.InternalOneOfEnum {
+      INT32VAL(1),
+      UINT32VAL(2),
+      INT64VAL(3),
+      UINT64VAL(4),
+      FLOATVAL(5),
+      STRINGVAL(6),
+      BOOLVAL(7),
+      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 INT32VAL;
+          case 2: return UINT32VAL;
+          case 3: return INT64VAL;
+          case 4: return UINT64VAL;
+          case 5: return FLOATVAL;
+          case 6: return STRINGVAL;
+          case 7: 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 INT32VAL_FIELD_NUMBER = 1;
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return Whether the kpiMinValue field is set.
+     * <code>int32 int32Val = 1;</code>
+     * @return Whether the int32Val field is set.
      */
     @java.lang.Override
-    public boolean hasKpiMinValue() {
-      return kpiMinValue_ != null;
+    public boolean hasInt32Val() {
+      return valueCase_ == 1;
     }
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-     * @return The kpiMinValue.
+     * <code>int32 int32Val = 1;</code>
+     * @return The int32Val.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getKpiMinValue() {
-      return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
+    public int getInt32Val() {
+      if (valueCase_ == 1) {
+        return (java.lang.Integer) value_;
+      }
+      return 0;
     }
+
+    public static final int UINT32VAL_FIELD_NUMBER = 2;
     /**
-     * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+     * <code>uint32 uint32Val = 2;</code>
+     * @return Whether the uint32Val field is set.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
-      return getKpiMinValue();
+    public boolean hasUint32Val() {
+      return valueCase_ == 2;
+    }
+    /**
+     * <code>uint32 uint32Val = 2;</code>
+     * @return The uint32Val.
+     */
+    @java.lang.Override
+    public int getUint32Val() {
+      if (valueCase_ == 2) {
+        return (java.lang.Integer) value_;
+      }
+      return 0;
     }
 
-    public static final int KPIMAXVALUE_FIELD_NUMBER = 2;
-    private monitoring.Monitoring.KpiValue kpiMaxValue_;
+    public static final int INT64VAL_FIELD_NUMBER = 3;
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return Whether the kpiMaxValue field is set.
+     * <code>int64 int64Val = 3;</code>
+     * @return Whether the int64Val field is set.
      */
     @java.lang.Override
-    public boolean hasKpiMaxValue() {
-      return kpiMaxValue_ != null;
+    public boolean hasInt64Val() {
+      return valueCase_ == 3;
+    }
+    /**
+     * <code>int64 int64Val = 3;</code>
+     * @return The int64Val.
+     */
+    @java.lang.Override
+    public long getInt64Val() {
+      if (valueCase_ == 3) {
+        return (java.lang.Long) value_;
+      }
+      return 0L;
+    }
+
+    public static final int UINT64VAL_FIELD_NUMBER = 4;
+    /**
+     * <code>uint64 uint64Val = 4;</code>
+     * @return Whether the uint64Val field is set.
+     */
+    @java.lang.Override
+    public boolean hasUint64Val() {
+      return valueCase_ == 4;
+    }
+    /**
+     * <code>uint64 uint64Val = 4;</code>
+     * @return The uint64Val.
+     */
+    @java.lang.Override
+    public long getUint64Val() {
+      if (valueCase_ == 4) {
+        return (java.lang.Long) value_;
+      }
+      return 0L;
+    }
+
+    public static final int FLOATVAL_FIELD_NUMBER = 5;
+    /**
+     * <code>float floatVal = 5;</code>
+     * @return Whether the floatVal field is set.
+     */
+    @java.lang.Override
+    public boolean hasFloatVal() {
+      return valueCase_ == 5;
+    }
+    /**
+     * <code>float floatVal = 5;</code>
+     * @return The floatVal.
+     */
+    @java.lang.Override
+    public float getFloatVal() {
+      if (valueCase_ == 5) {
+        return (java.lang.Float) value_;
+      }
+      return 0F;
+    }
+
+    public static final int STRINGVAL_FIELD_NUMBER = 6;
+    /**
+     * <code>string stringVal = 6;</code>
+     * @return Whether the stringVal field is set.
+     */
+    public boolean hasStringVal() {
+      return valueCase_ == 6;
+    }
+    /**
+     * <code>string stringVal = 6;</code>
+     * @return The stringVal.
+     */
+    public java.lang.String getStringVal() {
+      java.lang.Object ref = "";
+      if (valueCase_ == 6) {
+        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_ == 6) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>string stringVal = 6;</code>
+     * @return The bytes for stringVal.
+     */
+    public com.google.protobuf.ByteString
+        getStringValBytes() {
+      java.lang.Object ref = "";
+      if (valueCase_ == 6) {
+        ref = value_;
+      }
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        if (valueCase_ == 6) {
+          value_ = b;
+        }
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
     }
+
+    public static final int BOOLVAL_FIELD_NUMBER = 7;
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-     * @return The kpiMaxValue.
+     * <code>bool boolVal = 7;</code>
+     * @return Whether the boolVal field is set.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getKpiMaxValue() {
-      return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
+    public boolean hasBoolVal() {
+      return valueCase_ == 7;
     }
     /**
-     * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+     * <code>bool boolVal = 7;</code>
+     * @return The boolVal.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
-      return getKpiMaxValue();
+    public boolean getBoolVal() {
+      if (valueCase_ == 7) {
+        return (java.lang.Boolean) value_;
+      }
+      return false;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -9410,11 +7607,32 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (kpiMinValue_ != null) {
-        output.writeMessage(1, getKpiMinValue());
+      if (valueCase_ == 1) {
+        output.writeInt32(
+            1, (int)((java.lang.Integer) value_));
       }
-      if (kpiMaxValue_ != null) {
-        output.writeMessage(2, getKpiMaxValue());
+      if (valueCase_ == 2) {
+        output.writeUInt32(
+            2, (int)((java.lang.Integer) value_));
+      }
+      if (valueCase_ == 3) {
+        output.writeInt64(
+            3, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 4) {
+        output.writeUInt64(
+            4, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 5) {
+        output.writeFloat(
+            5, (float)((java.lang.Float) value_));
+      }
+      if (valueCase_ == 6) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, value_);
+      }
+      if (valueCase_ == 7) {
+        output.writeBool(
+            7, (boolean)((java.lang.Boolean) value_));
       }
       unknownFields.writeTo(output);
     }
@@ -9425,13 +7643,38 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (kpiMinValue_ != null) {
+      if (valueCase_ == 1) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getKpiMinValue());
+          .computeInt32Size(
+              1, (int)((java.lang.Integer) value_));
       }
-      if (kpiMaxValue_ != null) {
+      if (valueCase_ == 2) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, getKpiMaxValue());
+          .computeUInt32Size(
+              2, (int)((java.lang.Integer) value_));
+      }
+      if (valueCase_ == 3) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(
+              3, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 4) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt64Size(
+              4, (long)((java.lang.Long) value_));
+      }
+      if (valueCase_ == 5) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(
+              5, (float)((java.lang.Float) value_));
+      }
+      if (valueCase_ == 6) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, value_);
+      }
+      if (valueCase_ == 7) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(
+              7, (boolean)((java.lang.Boolean) value_));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -9443,20 +7686,44 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiValueRange)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiValue)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiValueRange other = (monitoring.Monitoring.KpiValueRange) obj;
+      monitoring.Monitoring.KpiValue other = (monitoring.Monitoring.KpiValue) obj;
 
-      if (hasKpiMinValue() != other.hasKpiMinValue()) return false;
-      if (hasKpiMinValue()) {
-        if (!getKpiMinValue()
-            .equals(other.getKpiMinValue())) return false;
-      }
-      if (hasKpiMaxValue() != other.hasKpiMaxValue()) return false;
-      if (hasKpiMaxValue()) {
-        if (!getKpiMaxValue()
-            .equals(other.getKpiMaxValue())) return false;
+      if (!getValueCase().equals(other.getValueCase())) return false;
+      switch (valueCase_) {
+        case 1:
+          if (getInt32Val()
+              != other.getInt32Val()) return false;
+          break;
+        case 2:
+          if (getUint32Val()
+              != other.getUint32Val()) return false;
+          break;
+        case 3:
+          if (getInt64Val()
+              != other.getInt64Val()) return false;
+          break;
+        case 4:
+          if (getUint64Val()
+              != other.getUint64Val()) return false;
+          break;
+        case 5:
+          if (java.lang.Float.floatToIntBits(getFloatVal())
+              != java.lang.Float.floatToIntBits(
+                  other.getFloatVal())) return false;
+          break;
+        case 6:
+          if (!getStringVal()
+              .equals(other.getStringVal())) return false;
+          break;
+        case 7:
+          if (getBoolVal()
+              != other.getBoolVal()) return false;
+          break;
+        case 0:
+        default:
       }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -9469,82 +7736,110 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasKpiMinValue()) {
-        hash = (37 * hash) + KPIMINVALUE_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiMinValue().hashCode();
-      }
-      if (hasKpiMaxValue()) {
-        hash = (37 * hash) + KPIMAXVALUE_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiMaxValue().hashCode();
+      switch (valueCase_) {
+        case 1:
+          hash = (37 * hash) + INT32VAL_FIELD_NUMBER;
+          hash = (53 * hash) + getInt32Val();
+          break;
+        case 2:
+          hash = (37 * hash) + UINT32VAL_FIELD_NUMBER;
+          hash = (53 * hash) + getUint32Val();
+          break;
+        case 3:
+          hash = (37 * hash) + INT64VAL_FIELD_NUMBER;
+          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+              getInt64Val());
+          break;
+        case 4:
+          hash = (37 * hash) + UINT64VAL_FIELD_NUMBER;
+          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+              getUint64Val());
+          break;
+        case 5:
+          hash = (37 * hash) + FLOATVAL_FIELD_NUMBER;
+          hash = (53 * hash) + java.lang.Float.floatToIntBits(
+              getFloatVal());
+          break;
+        case 6:
+          hash = (37 * hash) + STRINGVAL_FIELD_NUMBER;
+          hash = (53 * hash) + getStringVal().hashCode();
+          break;
+        case 7:
+          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.KpiValueRange parseFrom(
+    public static monitoring.Monitoring.KpiValue parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(
+    public static monitoring.Monitoring.KpiValue parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(byte[] data)
+    public static monitoring.Monitoring.KpiValue parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(java.io.InputStream input)
+    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.KpiValueRange parseFrom(
+    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.KpiValueRange parseDelimitedFrom(java.io.InputStream input)
+    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.KpiValueRange parseDelimitedFrom(
+    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.KpiValueRange parseFrom(
+    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.KpiValueRange parseFrom(
+    public static monitoring.Monitoring.KpiValue parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -9557,7 +7852,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiValueRange prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiValue prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -9573,26 +7868,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiValueRange}
+     * Protobuf type {@code monitoring.KpiValue}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiValueRange)
-        monitoring.Monitoring.KpiValueRangeOrBuilder {
+        // @@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_KpiValueRange_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiValueRange.class, monitoring.Monitoring.KpiValueRange.Builder.class);
+                monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiValueRange.newBuilder()
+      // Construct using monitoring.Monitoring.KpiValue.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -9610,35 +7905,25 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValue_ = null;
-        } else {
-          kpiMinValue_ = null;
-          kpiMinValueBuilder_ = null;
-        }
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValue_ = null;
-        } else {
-          kpiMaxValue_ = null;
-          kpiMaxValueBuilder_ = null;
-        }
+        valueCase_ = 0;
+        value_ = null;
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiValueRange_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiValueRange.getDefaultInstance();
+      public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiValue.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValueRange build() {
-        monitoring.Monitoring.KpiValueRange result = buildPartial();
+      public monitoring.Monitoring.KpiValue build() {
+        monitoring.Monitoring.KpiValue result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -9646,18 +7931,30 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValueRange buildPartial() {
-        monitoring.Monitoring.KpiValueRange result = new monitoring.Monitoring.KpiValueRange(this);
-        if (kpiMinValueBuilder_ == null) {
-          result.kpiMinValue_ = kpiMinValue_;
-        } else {
-          result.kpiMinValue_ = kpiMinValueBuilder_.build();
+      public monitoring.Monitoring.KpiValue buildPartial() {
+        monitoring.Monitoring.KpiValue result = new monitoring.Monitoring.KpiValue(this);
+        if (valueCase_ == 1) {
+          result.value_ = value_;
         }
-        if (kpiMaxValueBuilder_ == null) {
-          result.kpiMaxValue_ = kpiMaxValue_;
-        } else {
-          result.kpiMaxValue_ = kpiMaxValueBuilder_.build();
+        if (valueCase_ == 2) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 3) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 4) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 5) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 6) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 7) {
+          result.value_ = value_;
         }
+        result.valueCase_ = valueCase_;
         onBuilt();
         return result;
       }
@@ -9696,21 +7993,50 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiValueRange) {
-          return mergeFrom((monitoring.Monitoring.KpiValueRange)other);
+        if (other instanceof monitoring.Monitoring.KpiValue) {
+          return mergeFrom((monitoring.Monitoring.KpiValue)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.KpiValueRange other) {
-        if (other == monitoring.Monitoring.KpiValueRange.getDefaultInstance()) return this;
-        if (other.hasKpiMinValue()) {
-          mergeKpiMinValue(other.getKpiMinValue());
-        }
-        if (other.hasKpiMaxValue()) {
-          mergeKpiMaxValue(other.getKpiMaxValue());
+      public Builder mergeFrom(monitoring.Monitoring.KpiValue other) {
+        if (other == monitoring.Monitoring.KpiValue.getDefaultInstance()) return this;
+        switch (other.getValueCase()) {
+          case INT32VAL: {
+            setInt32Val(other.getInt32Val());
+            break;
+          }
+          case UINT32VAL: {
+            setUint32Val(other.getUint32Val());
+            break;
+          }
+          case INT64VAL: {
+            setInt64Val(other.getInt64Val());
+            break;
+          }
+          case UINT64VAL: {
+            setUint64Val(other.getUint64Val());
+            break;
+          }
+          case FLOATVAL: {
+            setFloatVal(other.getFloatVal());
+            break;
+          }
+          case STRINGVAL: {
+            valueCase_ = 6;
+            value_ = other.value_;
+            onChanged();
+            break;
+          }
+          case BOOLVAL: {
+            setBoolVal(other.getBoolVal());
+            break;
+          }
+          case VALUE_NOT_SET: {
+            break;
+          }
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -9727,11 +8053,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiValueRange parsedMessage = null;
+        monitoring.Monitoring.KpiValue parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiValueRange) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiValue) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -9740,243 +8066,363 @@ public final class Monitoring {
         }
         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;
+      }
+
 
-      private monitoring.Monitoring.KpiValue kpiMinValue_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMinValueBuilder_;
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-       * @return Whether the kpiMinValue field is set.
+       * <code>int32 int32Val = 1;</code>
+       * @return Whether the int32Val field is set.
        */
-      public boolean hasKpiMinValue() {
-        return kpiMinValueBuilder_ != null || kpiMinValue_ != null;
+      public boolean hasInt32Val() {
+        return valueCase_ == 1;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
-       * @return The kpiMinValue.
+       * <code>int32 int32Val = 1;</code>
+       * @return The int32Val.
        */
-      public monitoring.Monitoring.KpiValue getKpiMinValue() {
-        if (kpiMinValueBuilder_ == null) {
-          return kpiMinValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
-        } else {
-          return kpiMinValueBuilder_.getMessage();
+      public int getInt32Val() {
+        if (valueCase_ == 1) {
+          return (java.lang.Integer) value_;
         }
+        return 0;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>int32 int32Val = 1;</code>
+       * @param value The int32Val to set.
+       * @return This builder for chaining.
        */
-      public Builder setKpiMinValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMinValueBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          kpiMinValue_ = value;
-          onChanged();
-        } else {
-          kpiMinValueBuilder_.setMessage(value);
-        }
-
+      public Builder setInt32Val(int value) {
+        valueCase_ = 1;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>int32 int32Val = 1;</code>
+       * @return This builder for chaining.
        */
-      public Builder setKpiMinValue(
-          monitoring.Monitoring.KpiValue.Builder builderForValue) {
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValue_ = builderForValue.build();
+      public Builder clearInt32Val() {
+        if (valueCase_ == 1) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMinValueBuilder_.setMessage(builderForValue.build());
         }
+        return this;
+      }
 
+      /**
+       * <code>uint32 uint32Val = 2;</code>
+       * @return Whether the uint32Val field is set.
+       */
+      public boolean hasUint32Val() {
+        return valueCase_ == 2;
+      }
+      /**
+       * <code>uint32 uint32Val = 2;</code>
+       * @return The uint32Val.
+       */
+      public int getUint32Val() {
+        if (valueCase_ == 2) {
+          return (java.lang.Integer) value_;
+        }
+        return 0;
+      }
+      /**
+       * <code>uint32 uint32Val = 2;</code>
+       * @param value The uint32Val to set.
+       * @return This builder for chaining.
+       */
+      public Builder setUint32Val(int value) {
+        valueCase_ = 2;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint32 uint32Val = 2;</code>
+       * @return This builder for chaining.
        */
-      public Builder mergeKpiMinValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMinValueBuilder_ == null) {
-          if (kpiMinValue_ != null) {
-            kpiMinValue_ =
-              monitoring.Monitoring.KpiValue.newBuilder(kpiMinValue_).mergeFrom(value).buildPartial();
-          } else {
-            kpiMinValue_ = value;
-          }
+      public Builder clearUint32Val() {
+        if (valueCase_ == 2) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMinValueBuilder_.mergeFrom(value);
         }
+        return this;
+      }
 
+      /**
+       * <code>int64 int64Val = 3;</code>
+       * @return Whether the int64Val field is set.
+       */
+      public boolean hasInt64Val() {
+        return valueCase_ == 3;
+      }
+      /**
+       * <code>int64 int64Val = 3;</code>
+       * @return The int64Val.
+       */
+      public long getInt64Val() {
+        if (valueCase_ == 3) {
+          return (java.lang.Long) value_;
+        }
+        return 0L;
+      }
+      /**
+       * <code>int64 int64Val = 3;</code>
+       * @param value The int64Val to set.
+       * @return This builder for chaining.
+       */
+      public Builder setInt64Val(long value) {
+        valueCase_ = 3;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>int64 int64Val = 3;</code>
+       * @return This builder for chaining.
        */
-      public Builder clearKpiMinValue() {
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValue_ = null;
+      public Builder clearInt64Val() {
+        if (valueCase_ == 3) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMinValue_ = null;
-          kpiMinValueBuilder_ = null;
         }
-
         return this;
       }
+
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint64 uint64Val = 4;</code>
+       * @return Whether the uint64Val field is set.
        */
-      public monitoring.Monitoring.KpiValue.Builder getKpiMinValueBuilder() {
-        
-        onChanged();
-        return getKpiMinValueFieldBuilder().getBuilder();
+      public boolean hasUint64Val() {
+        return valueCase_ == 4;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint64 uint64Val = 4;</code>
+       * @return The uint64Val.
        */
-      public monitoring.Monitoring.KpiValueOrBuilder getKpiMinValueOrBuilder() {
-        if (kpiMinValueBuilder_ != null) {
-          return kpiMinValueBuilder_.getMessageOrBuilder();
-        } else {
-          return kpiMinValue_ == null ?
-              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMinValue_;
+      public long getUint64Val() {
+        if (valueCase_ == 4) {
+          return (java.lang.Long) value_;
         }
+        return 0L;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMinValue = 1;</code>
+       * <code>uint64 uint64Val = 4;</code>
+       * @param value The uint64Val to set.
+       * @return This builder for chaining.
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
-          getKpiMinValueFieldBuilder() {
-        if (kpiMinValueBuilder_ == null) {
-          kpiMinValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
-                  getKpiMinValue(),
-                  getParentForChildren(),
-                  isClean());
-          kpiMinValue_ = null;
+      public Builder setUint64Val(long value) {
+        valueCase_ = 4;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>uint64 uint64Val = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearUint64Val() {
+        if (valueCase_ == 4) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
         }
-        return kpiMinValueBuilder_;
+        return this;
       }
 
-      private monitoring.Monitoring.KpiValue kpiMaxValue_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiMaxValueBuilder_;
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-       * @return Whether the kpiMaxValue field is set.
+       * <code>float floatVal = 5;</code>
+       * @return Whether the floatVal field is set.
        */
-      public boolean hasKpiMaxValue() {
-        return kpiMaxValueBuilder_ != null || kpiMaxValue_ != null;
+      public boolean hasFloatVal() {
+        return valueCase_ == 5;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
-       * @return The kpiMaxValue.
+       * <code>float floatVal = 5;</code>
+       * @return The floatVal.
        */
-      public monitoring.Monitoring.KpiValue getKpiMaxValue() {
-        if (kpiMaxValueBuilder_ == null) {
-          return kpiMaxValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
-        } else {
-          return kpiMaxValueBuilder_.getMessage();
+      public float getFloatVal() {
+        if (valueCase_ == 5) {
+          return (java.lang.Float) value_;
         }
+        return 0F;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>float floatVal = 5;</code>
+       * @param value The floatVal to set.
+       * @return This builder for chaining.
        */
-      public Builder setKpiMaxValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMaxValueBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          kpiMaxValue_ = value;
+      public Builder setFloatVal(float value) {
+        valueCase_ = 5;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float floatVal = 5;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearFloatVal() {
+        if (valueCase_ == 5) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMaxValueBuilder_.setMessage(value);
         }
-
         return this;
       }
+
+      /**
+       * <code>string stringVal = 6;</code>
+       * @return Whether the stringVal field is set.
+       */
+      @java.lang.Override
+      public boolean hasStringVal() {
+        return valueCase_ == 6;
+      }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @return The stringVal.
        */
-      public Builder setKpiMaxValue(
-          monitoring.Monitoring.KpiValue.Builder builderForValue) {
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValue_ = builderForValue.build();
-          onChanged();
+      @java.lang.Override
+      public java.lang.String getStringVal() {
+        java.lang.Object ref = "";
+        if (valueCase_ == 6) {
+          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_ == 6) {
+            value_ = s;
+          }
+          return s;
         } else {
-          kpiMaxValueBuilder_.setMessage(builderForValue.build());
+          return (java.lang.String) ref;
         }
-
-        return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @return The bytes for stringVal.
        */
-      public Builder mergeKpiMaxValue(monitoring.Monitoring.KpiValue value) {
-        if (kpiMaxValueBuilder_ == null) {
-          if (kpiMaxValue_ != null) {
-            kpiMaxValue_ =
-              monitoring.Monitoring.KpiValue.newBuilder(kpiMaxValue_).mergeFrom(value).buildPartial();
-          } else {
-            kpiMaxValue_ = value;
+      @java.lang.Override
+      public com.google.protobuf.ByteString
+          getStringValBytes() {
+        java.lang.Object ref = "";
+        if (valueCase_ == 6) {
+          ref = value_;
+        }
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          if (valueCase_ == 6) {
+            value_ = b;
           }
-          onChanged();
+          return b;
         } else {
-          kpiMaxValueBuilder_.mergeFrom(value);
+          return (com.google.protobuf.ByteString) ref;
         }
-
+      }
+      /**
+       * <code>string stringVal = 6;</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_ = 6;
+        value_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @return This builder for chaining.
        */
-      public Builder clearKpiMaxValue() {
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValue_ = null;
+      public Builder clearStringVal() {
+        if (valueCase_ == 6) {
+          valueCase_ = 0;
+          value_ = null;
           onChanged();
-        } else {
-          kpiMaxValue_ = null;
-          kpiMaxValueBuilder_ = null;
         }
-
         return this;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>string stringVal = 6;</code>
+       * @param value The bytes for stringVal to set.
+       * @return This builder for chaining.
        */
-      public monitoring.Monitoring.KpiValue.Builder getKpiMaxValueBuilder() {
-        
+      public Builder setStringValBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        valueCase_ = 6;
+        value_ = value;
         onChanged();
-        return getKpiMaxValueFieldBuilder().getBuilder();
+        return this;
       }
+
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>bool boolVal = 7;</code>
+       * @return Whether the boolVal field is set.
        */
-      public monitoring.Monitoring.KpiValueOrBuilder getKpiMaxValueOrBuilder() {
-        if (kpiMaxValueBuilder_ != null) {
-          return kpiMaxValueBuilder_.getMessageOrBuilder();
-        } else {
-          return kpiMaxValue_ == null ?
-              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiMaxValue_;
+      public boolean hasBoolVal() {
+        return valueCase_ == 7;
+      }
+      /**
+       * <code>bool boolVal = 7;</code>
+       * @return The boolVal.
+       */
+      public boolean getBoolVal() {
+        if (valueCase_ == 7) {
+          return (java.lang.Boolean) value_;
         }
+        return false;
       }
       /**
-       * <code>.monitoring.KpiValue kpiMaxValue = 2;</code>
+       * <code>bool boolVal = 7;</code>
+       * @param value The boolVal to set.
+       * @return This builder for chaining.
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
-          getKpiMaxValueFieldBuilder() {
-        if (kpiMaxValueBuilder_ == null) {
-          kpiMaxValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
-                  getKpiMaxValue(),
-                  getParentForChildren(),
-                  isClean());
-          kpiMaxValue_ = null;
+      public Builder setBoolVal(boolean value) {
+        valueCase_ = 7;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>bool boolVal = 7;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearBoolVal() {
+        if (valueCase_ == 7) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
         }
-        return kpiMaxValueBuilder_;
+        return this;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -9991,122 +8437,95 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiValueRange)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiValue)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiValueRange)
-    private static final monitoring.Monitoring.KpiValueRange DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiValue)
+    private static final monitoring.Monitoring.KpiValue DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValueRange();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValue();
     }
 
-    public static monitoring.Monitoring.KpiValueRange getDefaultInstance() {
+    public static monitoring.Monitoring.KpiValue getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiValueRange>
-        PARSER = new com.google.protobuf.AbstractParser<KpiValueRange>() {
+    private static final com.google.protobuf.Parser<KpiValue>
+        PARSER = new com.google.protobuf.AbstractParser<KpiValue>() {
       @java.lang.Override
-      public KpiValueRange parsePartialFrom(
+      public KpiValue parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiValueRange(input, extensionRegistry);
+        return new KpiValue(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiValueRange> parser() {
+    public static com.google.protobuf.Parser<KpiValue> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiValueRange> getParserForType() {
+    public com.google.protobuf.Parser<KpiValue> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiValueRange getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiValueOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiValue)
+  public interface KpiListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiList)
       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.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    boolean hasStringVal();
+    java.util.List<monitoring.Monitoring.Kpi> 
+        getKpiListList();
     /**
-     * <code>string stringVal = 3;</code>
-     * @return The stringVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    java.lang.String getStringVal();
+    monitoring.Monitoring.Kpi getKpiList(int index);
     /**
-     * <code>string stringVal = 3;</code>
-     * @return The bytes for stringVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    com.google.protobuf.ByteString
-        getStringValBytes();
-
+    int getKpiListCount();
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return Whether the boolVal field is set.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    boolean hasBoolVal();
+    java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+        getKpiListOrBuilderList();
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return The boolVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    boolean getBoolVal();
-
-    public monitoring.Monitoring.KpiValue.ValueCase getValueCase();
+    monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+        int index);
   }
   /**
-   * Protobuf type {@code monitoring.KpiValue}
+   * Protobuf type {@code monitoring.KpiList}
    */
-  public static final class KpiValue extends
+  public static final class KpiList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiValue)
-      KpiValueOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiList)
+      KpiListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiValue.newBuilder() to construct.
-    private KpiValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiList.newBuilder() to construct.
+    private KpiList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiValue() {
+    private KpiList() {
+      kpiList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiValue();
+      return new KpiList();
     }
 
     @java.lang.Override
@@ -10114,7 +8533,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiValue(
+    private KpiList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -10122,6 +8541,7 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -10132,25 +8552,13 @@ public final class Monitoring {
             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();
+            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: {
@@ -10168,181 +8576,64 @@ public final class Monitoring {
         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_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;
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
     }
-    /**
-     * <code>uint32 intVal = 1;</code>
-     * @return The intVal.
-     */
+
     @java.lang.Override
-    public int getIntVal() {
-      if (valueCase_ == 1) {
-        return (java.lang.Integer) value_;
-      }
-      return 0;
+    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 FLOATVAL_FIELD_NUMBER = 2;
+    public static final int KPI_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.Kpi> kpiList_;
     /**
-     * <code>float floatVal = 2;</code>
-     * @return Whether the floatVal field is set.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @java.lang.Override
-    public boolean hasFloatVal() {
-      return valueCase_ == 2;
+    public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
+      return kpiList_;
     }
     /**
-     * <code>float floatVal = 2;</code>
-     * @return The floatVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @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;
-      }
+    public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+        getKpiListOrBuilderList() {
+      return kpiList_;
     }
     /**
-     * <code>string stringVal = 3;</code>
-     * @return The bytes for stringVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
-    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;
-      }
+    @java.lang.Override
+    public int getKpiListCount() {
+      return kpiList_.size();
     }
-
-    public static final int BOOLVAL_FIELD_NUMBER = 4;
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return Whether the boolVal field is set.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @java.lang.Override
-    public boolean hasBoolVal() {
-      return valueCase_ == 4;
+    public monitoring.Monitoring.Kpi getKpiList(int index) {
+      return kpiList_.get(index);
     }
     /**
-     * <code>bool boolVal = 4;</code>
-     * @return The boolVal.
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
      */
     @java.lang.Override
-    public boolean getBoolVal() {
-      if (valueCase_ == 4) {
-        return (java.lang.Boolean) value_;
-      }
-      return false;
+    public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+        int index) {
+      return kpiList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -10359,20 +8650,8 @@ public final class Monitoring {
     @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_));
+      for (int i = 0; i < kpiList_.size(); i++) {
+        output.writeMessage(1, kpiList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -10383,23 +8662,9 @@ public final class Monitoring {
       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) {
+      for (int i = 0; i < kpiList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeBoolSize(
-              4, (boolean)((java.lang.Boolean) value_));
+          .computeMessageSize(1, kpiList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -10411,33 +8676,13 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiValue)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiList)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiValue other = (monitoring.Monitoring.KpiValue) obj;
+      monitoring.Monitoring.KpiList other = (monitoring.Monitoring.KpiList) 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 (!getKpiListList()
+          .equals(other.getKpiListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -10449,96 +8694,78 @@ public final class Monitoring {
       }
       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:
+      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.KpiValue parseFrom(
+    public static monitoring.Monitoring.KpiList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValue parseFrom(
+    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.KpiValue parseFrom(
+    public static monitoring.Monitoring.KpiList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValue parseFrom(
+    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.KpiValue parseFrom(byte[] data)
+    public static monitoring.Monitoring.KpiList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiValue parseFrom(
+    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.KpiValue parseFrom(java.io.InputStream input)
+    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.KpiValue parseFrom(
+    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.KpiValue parseDelimitedFrom(java.io.InputStream input)
+    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.KpiValue parseDelimitedFrom(
+    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.KpiValue parseFrom(
+    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.KpiValue parseFrom(
+    public static monitoring.Monitoring.KpiList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -10551,7 +8778,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiValue prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -10567,26 +8794,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiValue}
+     * Protobuf type {@code monitoring.KpiList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiValue)
-        monitoring.Monitoring.KpiValueOrBuilder {
+        // @@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_KpiValue_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
+                monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiValue.newBuilder()
+      // Construct using monitoring.Monitoring.KpiList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -10599,52 +8826,54 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getKpiListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        valueCase_ = 0;
-        value_ = null;
+        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_KpiValue_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiValue.getDefaultInstance();
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiValue build() {
-        monitoring.Monitoring.KpiValue result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
+      public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiList.getDefaultInstance();
       }
 
       @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_;
+      public monitoring.Monitoring.KpiList build() {
+        monitoring.Monitoring.KpiList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
-        if (valueCase_ == 4) {
-          result.value_ = value_;
+        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();
         }
-        result.valueCase_ = valueCase_;
         onBuilt();
         return result;
       }
@@ -10683,37 +8912,40 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiValue) {
-          return mergeFrom((monitoring.Monitoring.KpiValue)other);
+        if (other instanceof monitoring.Monitoring.KpiList) {
+          return mergeFrom((monitoring.Monitoring.KpiList)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_;
+      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();
-            break;
           }
-          case BOOLVAL: {
-            setBoolVal(other.getBoolVal());
-            break;
-          }
-          case VALUE_NOT_SET: {
-            break;
+        } 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);
@@ -10731,11 +8963,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiValue parsedMessage = null;
+        monitoring.Monitoring.KpiList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiValue) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -10744,240 +8976,246 @@ public final class Monitoring {
         }
         return this;
       }
-      private int valueCase_ = 0;
-      private java.lang.Object value_;
-      public ValueCase
-          getValueCase() {
-        return ValueCase.forNumber(
-            valueCase_);
-      }
+      private int bitField0_;
 
-      public Builder clearValue() {
-        valueCase_ = 0;
-        value_ = null;
-        onChanged();
-        return this;
+      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>uint32 intVal = 1;</code>
-       * @return Whether the intVal field is set.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public boolean hasIntVal() {
-        return valueCase_ == 1;
+      public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
+        if (kpiListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        } else {
+          return kpiListBuilder_.getMessageList();
+        }
       }
       /**
-       * <code>uint32 intVal = 1;</code>
-       * @return The intVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public int getIntVal() {
-        if (valueCase_ == 1) {
-          return (java.lang.Integer) value_;
+      public int getKpiListCount() {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.size();
+        } else {
+          return kpiListBuilder_.getCount();
         }
-        return 0;
       }
       /**
-       * <code>uint32 intVal = 1;</code>
-       * @param value The intVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setIntVal(int value) {
-        valueCase_ = 1;
-        value_ = value;
-        onChanged();
-        return this;
+      public monitoring.Monitoring.Kpi getKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);
+        } else {
+          return kpiListBuilder_.getMessage(index);
+        }
       }
       /**
-       * <code>uint32 intVal = 1;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearIntVal() {
-        if (valueCase_ == 1) {
-          valueCase_ = 0;
-          value_ = null;
+      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>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.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public float getFloatVal() {
-        if (valueCase_ == 2) {
-          return (java.lang.Float) value_;
+      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 0F;
+        return this;
       }
       /**
-       * <code>float floatVal = 2;</code>
-       * @param value The floatVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setFloatVal(float value) {
-        valueCase_ = 2;
-        value_ = value;
-        onChanged();
+      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>float floatVal = 2;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearFloatVal() {
-        if (valueCase_ == 2) {
-          valueCase_ = 0;
-          value_ = null;
+      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>string stringVal = 3;</code>
-       * @return Whether the stringVal field is set.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      @java.lang.Override
-      public boolean hasStringVal() {
-        return valueCase_ == 3;
+      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>string stringVal = 3;</code>
-       * @return The stringVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      @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;
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(index, builderForValue.build());
+          onChanged();
         } else {
-          return (java.lang.String) ref;
+          kpiListBuilder_.addMessage(index, builderForValue.build());
         }
+        return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @return The bytes for stringVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      @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;
+      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 {
-          return (com.google.protobuf.ByteString) ref;
+          kpiListBuilder_.addAllMessages(values);
         }
+        return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @param value The stringVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setStringVal(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  valueCase_ = 3;
-        value_ = value;
-        onChanged();
+      public Builder clearKpiList() {
+        if (kpiListBuilder_ == null) {
+          kpiList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiListBuilder_.clear();
+        }
         return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearStringVal() {
-        if (valueCase_ == 3) {
-          valueCase_ = 0;
-          value_ = null;
+      public Builder removeKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.remove(index);
           onChanged();
+        } else {
+          kpiListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>string stringVal = 3;</code>
-       * @param value The bytes for stringVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setStringValBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        valueCase_ = 3;
-        value_ = value;
-        onChanged();
-        return this;
+      public monitoring.Monitoring.Kpi.Builder getKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().getBuilder(index);
       }
-
       /**
-       * <code>bool boolVal = 4;</code>
-       * @return Whether the boolVal field is set.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public boolean hasBoolVal() {
-        return valueCase_ == 4;
+      public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+          int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);  } else {
+          return kpiListBuilder_.getMessageOrBuilder(index);
+        }
       }
       /**
-       * <code>bool boolVal = 4;</code>
-       * @return The boolVal.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public boolean getBoolVal() {
-        if (valueCase_ == 4) {
-          return (java.lang.Boolean) value_;
+      public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+           getKpiListOrBuilderList() {
+        if (kpiListBuilder_ != null) {
+          return kpiListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiList_);
         }
-        return false;
       }
       /**
-       * <code>bool boolVal = 4;</code>
-       * @param value The boolVal to set.
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder setBoolVal(boolean value) {
-        valueCase_ = 4;
-        value_ = value;
-        onChanged();
-        return this;
+      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder() {
+        return getKpiListFieldBuilder().addBuilder(
+            monitoring.Monitoring.Kpi.getDefaultInstance());
       }
       /**
-       * <code>bool boolVal = 4;</code>
-       * @return This builder for chaining.
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
        */
-      public Builder clearBoolVal() {
-        if (valueCase_ == 4) {
-          valueCase_ = 0;
-          value_ = null;
-          onChanged();
+      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 this;
+        return kpiListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -10992,95 +9230,95 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiValue)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiList)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiValue)
-    private static final monitoring.Monitoring.KpiValue DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiList)
+    private static final monitoring.Monitoring.KpiList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValue();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiList();
     }
 
-    public static monitoring.Monitoring.KpiValue getDefaultInstance() {
+    public static monitoring.Monitoring.KpiList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiValue>
-        PARSER = new com.google.protobuf.AbstractParser<KpiValue>() {
+    private static final com.google.protobuf.Parser<KpiList>
+        PARSER = new com.google.protobuf.AbstractParser<KpiList>() {
       @java.lang.Override
-      public KpiValue parsePartialFrom(
+      public KpiList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiValue(input, extensionRegistry);
+        return new KpiList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiValue> parser() {
+    public static com.google.protobuf.Parser<KpiList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiValue> getParserForType() {
+    public com.google.protobuf.Parser<KpiList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiList)
+  public interface KpiDescriptorListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiDescriptorList)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    java.util.List<monitoring.Monitoring.Kpi> 
-        getKpiListList();
+    java.util.List<monitoring.Monitoring.KpiDescriptor> 
+        getKpiDescriptorListList();
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    monitoring.Monitoring.Kpi getKpiList(int index);
+    monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index);
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    int getKpiListCount();
+    int getKpiDescriptorListCount();
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
-        getKpiListOrBuilderList();
+    java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
+        getKpiDescriptorListOrBuilderList();
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
-    monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+    monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
         int index);
   }
   /**
-   * Protobuf type {@code monitoring.KpiList}
+   * Protobuf type {@code monitoring.KpiDescriptorList}
    */
-  public static final class KpiList extends
+  public static final class KpiDescriptorList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiList)
-      KpiListOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.KpiDescriptorList)
+      KpiDescriptorListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiList.newBuilder() to construct.
-    private KpiList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use KpiDescriptorList.newBuilder() to construct.
+    private KpiDescriptorList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiList() {
-      kpiList_ = java.util.Collections.emptyList();
+    private KpiDescriptorList() {
+      kpiDescriptorList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiList();
+      return new KpiDescriptorList();
     }
 
     @java.lang.Override
@@ -11088,7 +9326,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private KpiList(
+    private KpiDescriptorList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -11109,11 +9347,11 @@ public final class Monitoring {
               break;
             case 10: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.Kpi>();
+                kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              kpiList_.add(
-                  input.readMessage(monitoring.Monitoring.Kpi.parser(), extensionRegistry));
+              kpiDescriptorList_.add(
+                  input.readMessage(monitoring.Monitoring.KpiDescriptor.parser(), extensionRegistry));
               break;
             }
             default: {
@@ -11132,7 +9370,7 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+          kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -11140,55 +9378,55 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
+              monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
     }
 
-    public static final int KPI_LIST_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.Kpi> kpiList_;
+    public static final int KPI_DESCRIPTOR_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_;
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
-      return kpiList_;
+    public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
+      return kpiDescriptorList_;
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
-        getKpiListOrBuilderList() {
-      return kpiList_;
+    public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
+        getKpiDescriptorListOrBuilderList() {
+      return kpiDescriptorList_;
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public int getKpiListCount() {
-      return kpiList_.size();
+    public int getKpiDescriptorListCount() {
+      return kpiDescriptorList_.size();
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.Kpi getKpiList(int index) {
-      return kpiList_.get(index);
+    public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
+      return kpiDescriptorList_.get(index);
     }
     /**
-     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+    public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
         int index) {
-      return kpiList_.get(index);
+      return kpiDescriptorList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -11205,8 +9443,8 @@ public final class Monitoring {
     @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));
+      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
+        output.writeMessage(1, kpiDescriptorList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -11217,9 +9455,9 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      for (int i = 0; i < kpiList_.size(); i++) {
+      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, kpiList_.get(i));
+          .computeMessageSize(1, kpiDescriptorList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -11231,13 +9469,13 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiList)) {
+      if (!(obj instanceof monitoring.Monitoring.KpiDescriptorList)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiList other = (monitoring.Monitoring.KpiList) obj;
+      monitoring.Monitoring.KpiDescriptorList other = (monitoring.Monitoring.KpiDescriptorList) obj;
 
-      if (!getKpiListList()
-          .equals(other.getKpiListList())) return false;
+      if (!getKpiDescriptorListList()
+          .equals(other.getKpiDescriptorListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -11249,78 +9487,78 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getKpiListCount() > 0) {
-        hash = (37 * hash) + KPI_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiListList().hashCode();
+      if (getKpiDescriptorListCount() > 0) {
+        hash = (37 * hash) + KPI_DESCRIPTOR_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiDescriptorListList().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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)
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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)
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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)
+    public static monitoring.Monitoring.KpiDescriptorList parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiList parseDelimitedFrom(
+    public static monitoring.Monitoring.KpiDescriptorList 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(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiList parseFrom(
+    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -11333,7 +9571,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiList prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.KpiDescriptorList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -11349,26 +9587,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiList}
+     * Protobuf type {@code monitoring.KpiDescriptorList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiList)
-        monitoring.Monitoring.KpiListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiDescriptorList)
+        monitoring.Monitoring.KpiDescriptorListOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
+                monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiList.newBuilder()
+      // Construct using monitoring.Monitoring.KpiDescriptorList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -11381,17 +9619,17 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiListFieldBuilder();
+          getKpiDescriptorListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+        if (kpiDescriptorListBuilder_ == null) {
+          kpiDescriptorList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          kpiListBuilder_.clear();
+          kpiDescriptorListBuilder_.clear();
         }
         return this;
       }
@@ -11399,17 +9637,17 @@ public final class Monitoring {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiList.getDefaultInstance();
+      public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiDescriptorList.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiList build() {
-        monitoring.Monitoring.KpiList result = buildPartial();
+      public monitoring.Monitoring.KpiDescriptorList build() {
+        monitoring.Monitoring.KpiDescriptorList result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -11417,17 +9655,17 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiList buildPartial() {
-        monitoring.Monitoring.KpiList result = new monitoring.Monitoring.KpiList(this);
+      public monitoring.Monitoring.KpiDescriptorList buildPartial() {
+        monitoring.Monitoring.KpiDescriptorList result = new monitoring.Monitoring.KpiDescriptorList(this);
         int from_bitField0_ = bitField0_;
-        if (kpiListBuilder_ == null) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (((bitField0_ & 0x00000001) != 0)) {
-            kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+            kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
-          result.kpiList_ = kpiList_;
+          result.kpiDescriptorList_ = kpiDescriptorList_;
         } else {
-          result.kpiList_ = kpiListBuilder_.build();
+          result.kpiDescriptorList_ = kpiDescriptorListBuilder_.build();
         }
         onBuilt();
         return result;
@@ -11467,39 +9705,39 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.KpiList) {
-          return mergeFrom((monitoring.Monitoring.KpiList)other);
+        if (other instanceof monitoring.Monitoring.KpiDescriptorList) {
+          return mergeFrom((monitoring.Monitoring.KpiDescriptorList)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_;
+      public Builder mergeFrom(monitoring.Monitoring.KpiDescriptorList other) {
+        if (other == monitoring.Monitoring.KpiDescriptorList.getDefaultInstance()) return this;
+        if (kpiDescriptorListBuilder_ == null) {
+          if (!other.kpiDescriptorList_.isEmpty()) {
+            if (kpiDescriptorList_.isEmpty()) {
+              kpiDescriptorList_ = other.kpiDescriptorList_;
               bitField0_ = (bitField0_ & ~0x00000001);
             } else {
-              ensureKpiListIsMutable();
-              kpiList_.addAll(other.kpiList_);
+              ensureKpiDescriptorListIsMutable();
+              kpiDescriptorList_.addAll(other.kpiDescriptorList_);
             }
             onChanged();
           }
         } else {
-          if (!other.kpiList_.isEmpty()) {
-            if (kpiListBuilder_.isEmpty()) {
-              kpiListBuilder_.dispose();
-              kpiListBuilder_ = null;
-              kpiList_ = other.kpiList_;
+          if (!other.kpiDescriptorList_.isEmpty()) {
+            if (kpiDescriptorListBuilder_.isEmpty()) {
+              kpiDescriptorListBuilder_.dispose();
+              kpiDescriptorListBuilder_ = null;
+              kpiDescriptorList_ = other.kpiDescriptorList_;
               bitField0_ = (bitField0_ & ~0x00000001);
-              kpiListBuilder_ = 
+              kpiDescriptorListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiListFieldBuilder() : null;
+                   getKpiDescriptorListFieldBuilder() : null;
             } else {
-              kpiListBuilder_.addAllMessages(other.kpiList_);
+              kpiDescriptorListBuilder_.addAllMessages(other.kpiDescriptorList_);
             }
           }
         }
@@ -11518,11 +9756,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.KpiList parsedMessage = null;
+        monitoring.Monitoring.KpiDescriptorList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiList) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.KpiDescriptorList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -11533,244 +9771,244 @@ public final class Monitoring {
       }
       private int bitField0_;
 
-      private java.util.List<monitoring.Monitoring.Kpi> kpiList_ =
+      private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_ =
         java.util.Collections.emptyList();
-      private void ensureKpiListIsMutable() {
+      private void ensureKpiDescriptorListIsMutable() {
         if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.Kpi>(kpiList_);
+          kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>(kpiDescriptorList_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.Kpi, monitoring.Monitoring.Kpi.Builder, monitoring.Monitoring.KpiOrBuilder> kpiListBuilder_;
+          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> kpiDescriptorListBuilder_;
 
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
-        if (kpiListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiList_);
+      public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
+        if (kpiDescriptorListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
         } else {
-          return kpiListBuilder_.getMessageList();
+          return kpiDescriptorListBuilder_.getMessageList();
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public int getKpiListCount() {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.size();
+      public int getKpiDescriptorListCount() {
+        if (kpiDescriptorListBuilder_ == null) {
+          return kpiDescriptorList_.size();
         } else {
-          return kpiListBuilder_.getCount();
+          return kpiDescriptorListBuilder_.getCount();
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi getKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);
+      public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
+        if (kpiDescriptorListBuilder_ == null) {
+          return kpiDescriptorList_.get(index);
         } else {
-          return kpiListBuilder_.getMessage(index);
+          return kpiDescriptorListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.Kpi value) {
-        if (kpiListBuilder_ == null) {
+      public Builder setKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor value) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.set(index, value);
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.set(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, value);
+          kpiDescriptorListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.set(index, builderForValue.build());
+      public Builder setKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, builderForValue.build());
+          kpiDescriptorListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(monitoring.Monitoring.Kpi value) {
-        if (kpiListBuilder_ == null) {
+      public Builder addKpiDescriptorList(monitoring.Monitoring.KpiDescriptor value) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(value);
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(value);
+          kpiDescriptorListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.Kpi value) {
-        if (kpiListBuilder_ == null) {
+      public Builder addKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor value) {
+        if (kpiDescriptorListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(index, value);
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, value);
+          kpiDescriptorListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(
-          monitoring.Monitoring.Kpi.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(builderForValue.build());
+      public Builder addKpiDescriptorList(
+          monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(builderForValue.build());
+          kpiDescriptorListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(index, builderForValue.build());
+      public Builder addKpiDescriptorList(
+          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, builderForValue.build());
+          kpiDescriptorListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder addAllKpiList(
-          java.lang.Iterable<? extends monitoring.Monitoring.Kpi> values) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
+      public Builder addAllKpiDescriptorList(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiDescriptor> values) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiList_);
+              values, kpiDescriptorList_);
           onChanged();
         } else {
-          kpiListBuilder_.addAllMessages(values);
+          kpiDescriptorListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder clearKpiList() {
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+      public Builder clearKpiDescriptorList() {
+        if (kpiDescriptorListBuilder_ == null) {
+          kpiDescriptorList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          kpiListBuilder_.clear();
+          kpiDescriptorListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public Builder removeKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.remove(index);
+      public Builder removeKpiDescriptorList(int index) {
+        if (kpiDescriptorListBuilder_ == null) {
+          ensureKpiDescriptorListIsMutable();
+          kpiDescriptorList_.remove(index);
           onChanged();
         } else {
-          kpiListBuilder_.remove(index);
+          kpiDescriptorListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi.Builder getKpiListBuilder(
+      public monitoring.Monitoring.KpiDescriptor.Builder getKpiDescriptorListBuilder(
           int index) {
-        return getKpiListFieldBuilder().getBuilder(index);
+        return getKpiDescriptorListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+      public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
           int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);  } else {
-          return kpiListBuilder_.getMessageOrBuilder(index);
+        if (kpiDescriptorListBuilder_ == null) {
+          return kpiDescriptorList_.get(index);  } else {
+          return kpiDescriptorListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
-           getKpiListOrBuilderList() {
-        if (kpiListBuilder_ != null) {
-          return kpiListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
+           getKpiDescriptorListOrBuilderList() {
+        if (kpiDescriptorListBuilder_ != null) {
+          return kpiDescriptorListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(kpiList_);
+          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
         }
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder() {
-        return getKpiListFieldBuilder().addBuilder(
-            monitoring.Monitoring.Kpi.getDefaultInstance());
+      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder() {
+        return getKpiDescriptorListFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder(
+      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder(
           int index) {
-        return getKpiListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.Kpi.getDefaultInstance());
+        return getKpiDescriptorListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.Kpi.Builder> 
-           getKpiListBuilderList() {
-        return getKpiListFieldBuilder().getBuilderList();
+      public java.util.List<monitoring.Monitoring.KpiDescriptor.Builder> 
+           getKpiDescriptorListBuilderList() {
+        return getKpiDescriptorListFieldBuilder().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_,
+          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> 
+          getKpiDescriptorListFieldBuilder() {
+        if (kpiDescriptorListBuilder_ == null) {
+          kpiDescriptorListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder>(
+                  kpiDescriptorList_,
                   ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          kpiList_ = null;
+          kpiDescriptorList_ = null;
         }
-        return kpiListBuilder_;
+        return kpiDescriptorListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -11785,128 +10023,251 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiList)
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiDescriptorList)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiList)
-    private static final monitoring.Monitoring.KpiList DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.KpiDescriptorList)
+    private static final monitoring.Monitoring.KpiDescriptorList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiList();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiDescriptorList();
     }
 
-    public static monitoring.Monitoring.KpiList getDefaultInstance() {
+    public static monitoring.Monitoring.KpiDescriptorList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiList>
-        PARSER = new com.google.protobuf.AbstractParser<KpiList>() {
+    private static final com.google.protobuf.Parser<KpiDescriptorList>
+        PARSER = new com.google.protobuf.AbstractParser<KpiDescriptorList>() {
       @java.lang.Override
-      public KpiList parsePartialFrom(
+      public KpiDescriptorList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiList(input, extensionRegistry);
+        return new KpiDescriptorList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<KpiList> parser() {
+    public static com.google.protobuf.Parser<KpiDescriptorList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<KpiList> getParserForType() {
+    public com.google.protobuf.Parser<KpiDescriptorList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
+    public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface KpiDescriptorListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.KpiDescriptorList)
+  public interface SubsDescriptorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubsDescriptor)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
-    java.util.List<monitoring.Monitoring.KpiDescriptor> 
-        getKpiDescriptorListList();
+    boolean hasSubsId();
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return The subsId.
      */
-    monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index);
+    monitoring.Monitoring.SubscriptionID getSubsId();
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
-    int getKpiDescriptorListCount();
+    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder();
+
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return Whether the kpiId field is set.
      */
-    java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
-        getKpiDescriptorListOrBuilderList();
+    boolean hasKpiId();
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return The kpiId.
      */
-    monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
-        int index);
+    monitoring.Monitoring.KpiId getKpiId();
+    /**
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>float sampling_duration_s = 3;</code>
+     * @return The samplingDurationS.
+     */
+    float getSamplingDurationS();
+
+    /**
+     * <code>float sampling_interval_s = 4;</code>
+     * @return The samplingIntervalS.
+     */
+    float getSamplingIntervalS();
+
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
+     */
+    boolean hasStartTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
+     */
+    context.ContextOuterClass.Timestamp getStartTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder();
+
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
+     */
+    boolean hasEndTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
+     */
+    context.ContextOuterClass.Timestamp getEndTimestamp();
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.KpiDescriptorList}
+   * Protobuf type {@code monitoring.SubsDescriptor}
    */
-  public static final class KpiDescriptorList extends
+  public static final class SubsDescriptor extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.KpiDescriptorList)
-      KpiDescriptorListOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubsDescriptor)
+      SubsDescriptorOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use KpiDescriptorList.newBuilder() to construct.
-    private KpiDescriptorList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubsDescriptor.newBuilder() to construct.
+    private SubsDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private KpiDescriptorList() {
-      kpiDescriptorList_ = java.util.Collections.emptyList();
+    private SubsDescriptor() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new KpiDescriptorList();
+      return new SubsDescriptor();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
     }
+    private SubsDescriptor(
+        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.SubscriptionID.Builder subBuilder = null;
+              if (subsId_ != null) {
+                subBuilder = subsId_.toBuilder();
+              }
+              subsId_ = input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(subsId_);
+                subsId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              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 29: {
+
+              samplingDurationS_ = input.readFloat();
+              break;
+            }
+            case 37: {
 
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private KpiDescriptorList(
-        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;
+              samplingIntervalS_ = input.readFloat();
               break;
-            case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>();
-                mutable_bitField0_ |= 0x00000001;
+            }
+            case 42: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (startTimestamp_ != null) {
+                subBuilder = startTimestamp_.toBuilder();
               }
-              kpiDescriptorList_.add(
-                  input.readMessage(monitoring.Monitoring.KpiDescriptor.parser(), extensionRegistry));
+              startTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(startTimestamp_);
+                startTimestamp_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 50: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (endTimestamp_ != null) {
+                subBuilder = endTimestamp_.toBuilder();
+              }
+              endTimestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(endTimestamp_);
+                endTimestamp_ = subBuilder.buildPartial();
+              }
+
               break;
             }
             default: {
@@ -11924,64 +10285,171 @@ public final class Monitoring {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
-        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
+              monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.Builder.class);
     }
 
-    public static final int KPI_DESCRIPTOR_LIST_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_;
+    public static final int SUBS_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.SubscriptionID subsId_;
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
-      return kpiDescriptorList_;
+    public boolean hasSubsId() {
+      return subsId_ != null;
     }
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+     * @return The subsId.
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
-        getKpiDescriptorListOrBuilderList() {
-      return kpiDescriptorList_;
+    public monitoring.Monitoring.SubscriptionID getSubsId() {
+      return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
     }
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
     @java.lang.Override
-    public int getKpiDescriptorListCount() {
-      return kpiDescriptorList_.size();
+    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
+      return getSubsId();
     }
+
+    public static final int KPI_ID_FIELD_NUMBER = 2;
+    private monitoring.Monitoring.KpiId kpiId_;
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return Whether the kpiId field is set.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
-      return kpiDescriptorList_.get(index);
+    public boolean hasKpiId() {
+      return kpiId_ != null;
     }
     /**
-     * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     * @return The kpiId.
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
-        int index) {
-      return kpiDescriptorList_.get(index);
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    }
+    /**
+     * <code>.monitoring.KpiId kpi_id = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
+    }
+
+    public static final int SAMPLING_DURATION_S_FIELD_NUMBER = 3;
+    private float samplingDurationS_;
+    /**
+     * <code>float sampling_duration_s = 3;</code>
+     * @return The samplingDurationS.
+     */
+    @java.lang.Override
+    public float getSamplingDurationS() {
+      return samplingDurationS_;
+    }
+
+    public static final int SAMPLING_INTERVAL_S_FIELD_NUMBER = 4;
+    private float samplingIntervalS_;
+    /**
+     * <code>float sampling_interval_s = 4;</code>
+     * @return The samplingIntervalS.
+     */
+    @java.lang.Override
+    public float getSamplingIntervalS() {
+      return samplingIntervalS_;
+    }
+
+    public static final int START_TIMESTAMP_FIELD_NUMBER = 5;
+    private context.ContextOuterClass.Timestamp startTimestamp_;
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return Whether the startTimestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasStartTimestamp() {
+      return startTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     * @return The startTimestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getStartTimestamp() {
+      return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples since X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp start_timestamp = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+      return getStartTimestamp();
+    }
+
+    public static final int END_TIMESTAMP_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.Timestamp endTimestamp_;
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return Whether the endTimestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasEndTimestamp() {
+      return endTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     * @return The endTimestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getEndTimestamp() {
+      return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
+    }
+    /**
+     * <pre>
+     * used when you want something like "get the samples until X date/time"
+     * </pre>
+     *
+     * <code>.context.Timestamp end_timestamp = 6;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+      return getEndTimestamp();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -11998,8 +10466,23 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
-        output.writeMessage(1, kpiDescriptorList_.get(i));
+      if (subsId_ != null) {
+        output.writeMessage(1, getSubsId());
+      }
+      if (kpiId_ != null) {
+        output.writeMessage(2, getKpiId());
+      }
+      if (samplingDurationS_ != 0F) {
+        output.writeFloat(3, samplingDurationS_);
+      }
+      if (samplingIntervalS_ != 0F) {
+        output.writeFloat(4, samplingIntervalS_);
+      }
+      if (startTimestamp_ != null) {
+        output.writeMessage(5, getStartTimestamp());
+      }
+      if (endTimestamp_ != null) {
+        output.writeMessage(6, getEndTimestamp());
       }
       unknownFields.writeTo(output);
     }
@@ -12010,9 +10493,29 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      for (int i = 0; i < kpiDescriptorList_.size(); i++) {
+      if (subsId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, kpiDescriptorList_.get(i));
+          .computeMessageSize(1, getSubsId());
+      }
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getKpiId());
+      }
+      if (samplingDurationS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, samplingDurationS_);
+      }
+      if (samplingIntervalS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(4, samplingIntervalS_);
+      }
+      if (startTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, getStartTimestamp());
+      }
+      if (endTimestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getEndTimestamp());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -12024,13 +10527,37 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.KpiDescriptorList)) {
+      if (!(obj instanceof monitoring.Monitoring.SubsDescriptor)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.KpiDescriptorList other = (monitoring.Monitoring.KpiDescriptorList) obj;
+      monitoring.Monitoring.SubsDescriptor other = (monitoring.Monitoring.SubsDescriptor) obj;
 
-      if (!getKpiDescriptorListList()
-          .equals(other.getKpiDescriptorListList())) return false;
+      if (hasSubsId() != other.hasSubsId()) return false;
+      if (hasSubsId()) {
+        if (!getSubsId()
+            .equals(other.getSubsId())) return false;
+      }
+      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 (hasStartTimestamp() != other.hasStartTimestamp()) return false;
+      if (hasStartTimestamp()) {
+        if (!getStartTimestamp()
+            .equals(other.getStartTimestamp())) return false;
+      }
+      if (hasEndTimestamp() != other.hasEndTimestamp()) return false;
+      if (hasEndTimestamp()) {
+        if (!getEndTimestamp()
+            .equals(other.getEndTimestamp())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -12042,78 +10569,96 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getKpiDescriptorListCount() > 0) {
-        hash = (37 * hash) + KPI_DESCRIPTOR_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiDescriptorListList().hashCode();
+      if (hasSubsId()) {
+        hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSubsId().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());
+      if (hasStartTimestamp()) {
+        hash = (37 * hash) + START_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getStartTimestamp().hashCode();
+      }
+      if (hasEndTimestamp()) {
+        hash = (37 * hash) + END_TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getEndTimestamp().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor 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.KpiDescriptorList parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor 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.KpiDescriptorList parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsDescriptor parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseDelimitedFrom(
+    public static monitoring.Monitoring.SubsDescriptor 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.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.KpiDescriptorList parseFrom(
+    public static monitoring.Monitoring.SubsDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -12126,7 +10671,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.KpiDescriptorList prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubsDescriptor prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -12142,26 +10687,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.KpiDescriptorList}
+     * Protobuf type {@code monitoring.SubsDescriptor}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.KpiDescriptorList)
-        monitoring.Monitoring.KpiDescriptorListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubsDescriptor)
+        monitoring.Monitoring.SubsDescriptorOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.KpiDescriptorList.class, monitoring.Monitoring.KpiDescriptorList.Builder.class);
+                monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.KpiDescriptorList.newBuilder()
+      // Construct using monitoring.Monitoring.SubsDescriptor.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -12174,17 +10719,38 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiDescriptorListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiDescriptorListBuilder_ == null) {
-          kpiDescriptorList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
         } else {
-          kpiDescriptorListBuilder_.clear();
+          subsId_ = null;
+          subsIdBuilder_ = null;
+        }
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+        samplingDurationS_ = 0F;
+
+        samplingIntervalS_ = 0F;
+
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
+        } else {
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
+        }
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
+        } else {
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
         }
         return this;
       }
@@ -12192,17 +10758,17 @@ public final class Monitoring {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptorList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
-        return monitoring.Monitoring.KpiDescriptorList.getDefaultInstance();
+      public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubsDescriptor.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiDescriptorList build() {
-        monitoring.Monitoring.KpiDescriptorList result = buildPartial();
+      public monitoring.Monitoring.SubsDescriptor build() {
+        monitoring.Monitoring.SubsDescriptor result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -12210,17 +10776,29 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.KpiDescriptorList buildPartial() {
-        monitoring.Monitoring.KpiDescriptorList result = new monitoring.Monitoring.KpiDescriptorList(this);
-        int from_bitField0_ = bitField0_;
-        if (kpiDescriptorListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            kpiDescriptorList_ = java.util.Collections.unmodifiableList(kpiDescriptorList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.kpiDescriptorList_ = kpiDescriptorList_;
+      public monitoring.Monitoring.SubsDescriptor buildPartial() {
+        monitoring.Monitoring.SubsDescriptor result = new monitoring.Monitoring.SubsDescriptor(this);
+        if (subsIdBuilder_ == null) {
+          result.subsId_ = subsId_;
         } else {
-          result.kpiDescriptorList_ = kpiDescriptorListBuilder_.build();
+          result.subsId_ = subsIdBuilder_.build();
+        }
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.samplingDurationS_ = samplingDurationS_;
+        result.samplingIntervalS_ = samplingIntervalS_;
+        if (startTimestampBuilder_ == null) {
+          result.startTimestamp_ = startTimestamp_;
+        } else {
+          result.startTimestamp_ = startTimestampBuilder_.build();
+        }
+        if (endTimestampBuilder_ == null) {
+          result.endTimestamp_ = endTimestamp_;
+        } else {
+          result.endTimestamp_ = endTimestampBuilder_.build();
         }
         onBuilt();
         return result;
@@ -12258,312 +10836,673 @@ public final class Monitoring {
           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.KpiDescriptorList) {
-          return mergeFrom((monitoring.Monitoring.KpiDescriptorList)other);
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.SubsDescriptor) {
+          return mergeFrom((monitoring.Monitoring.SubsDescriptor)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.SubsDescriptor other) {
+        if (other == monitoring.Monitoring.SubsDescriptor.getDefaultInstance()) return this;
+        if (other.hasSubsId()) {
+          mergeSubsId(other.getSubsId());
+        }
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
+        if (other.getSamplingDurationS() != 0F) {
+          setSamplingDurationS(other.getSamplingDurationS());
+        }
+        if (other.getSamplingIntervalS() != 0F) {
+          setSamplingIntervalS(other.getSamplingIntervalS());
+        }
+        if (other.hasStartTimestamp()) {
+          mergeStartTimestamp(other.getStartTimestamp());
+        }
+        if (other.hasEndTimestamp()) {
+          mergeEndTimestamp(other.getEndTimestamp());
+        }
+        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.SubsDescriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.SubsDescriptor) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private monitoring.Monitoring.SubscriptionID subsId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsIdBuilder_;
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return Whether the subsId field is set.
+       */
+      public boolean hasSubsId() {
+        return subsIdBuilder_ != null || subsId_ != null;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return The subsId.
+       */
+      public monitoring.Monitoring.SubscriptionID getSubsId() {
+        if (subsIdBuilder_ == null) {
+          return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        } else {
+          return subsIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          subsId_ = value;
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(
+          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsIdBuilder_ == null) {
+          subsId_ = builderForValue.build();
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder mergeSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (subsId_ != null) {
+            subsId_ =
+              monitoring.Monitoring.SubscriptionID.newBuilder(subsId_).mergeFrom(value).buildPartial();
+          } else {
+            subsId_ = value;
+          }
+          onChanged();
+        } else {
+          subsIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder clearSubsId() {
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
+          onChanged();
+        } else {
+          subsId_ = null;
+          subsIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionID.Builder getSubsIdBuilder() {
+        
+        onChanged();
+        return getSubsIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
+        if (subsIdBuilder_ != null) {
+          return subsIdBuilder_.getMessageOrBuilder();
+        } else {
+          return subsId_ == null ?
+              monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
+          getSubsIdFieldBuilder() {
+        if (subsIdBuilder_ == null) {
+          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
+                  getSubsId(),
+                  getParentForChildren(),
+                  isClean());
+          subsId_ = null;
+        }
+        return subsIdBuilder_;
+      }
+
+      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 = 2;</code>
+       * @return Whether the kpiId field is set.
+       */
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       * @return The kpiId.
+       */
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         } else {
-          super.mergeFrom(other);
-          return this;
+          return kpiIdBuilder_.getMessage();
         }
       }
-
-      public Builder mergeFrom(monitoring.Monitoring.KpiDescriptorList other) {
-        if (other == monitoring.Monitoring.KpiDescriptorList.getDefaultInstance()) return this;
-        if (kpiDescriptorListBuilder_ == null) {
-          if (!other.kpiDescriptorList_.isEmpty()) {
-            if (kpiDescriptorList_.isEmpty()) {
-              kpiDescriptorList_ = other.kpiDescriptorList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureKpiDescriptorListIsMutable();
-              kpiDescriptorList_.addAll(other.kpiDescriptorList_);
-            }
-            onChanged();
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       */
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          kpiId_ = value;
+          onChanged();
         } else {
-          if (!other.kpiDescriptorList_.isEmpty()) {
-            if (kpiDescriptorListBuilder_.isEmpty()) {
-              kpiDescriptorListBuilder_.dispose();
-              kpiDescriptorListBuilder_ = null;
-              kpiDescriptorList_ = other.kpiDescriptorList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              kpiDescriptorListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiDescriptorListFieldBuilder() : null;
-            } else {
-              kpiDescriptorListBuilder_.addAllMessages(other.kpiDescriptorList_);
-            }
-          }
+          kpiIdBuilder_.setMessage(value);
         }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
+
         return this;
       }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       */
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
 
-      @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
+        return this;
       }
-
-      @java.lang.Override
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        monitoring.Monitoring.KpiDescriptorList parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.KpiDescriptorList) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</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;
-      }
-      private int bitField0_;
 
-      private java.util.List<monitoring.Monitoring.KpiDescriptor> kpiDescriptorList_ =
-        java.util.Collections.emptyList();
-      private void ensureKpiDescriptorListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiDescriptorList_ = new java.util.ArrayList<monitoring.Monitoring.KpiDescriptor>(kpiDescriptorList_);
-          bitField0_ |= 0x00000001;
-         }
+        return this;
       }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> kpiDescriptorListBuilder_;
-
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiDescriptor> getKpiDescriptorListList() {
-        if (kpiDescriptorListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
         } else {
-          return kpiDescriptorListBuilder_.getMessageList();
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
        */
-      public int getKpiDescriptorListCount() {
-        if (kpiDescriptorListBuilder_ == null) {
-          return kpiDescriptorList_.size();
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
         } else {
-          return kpiDescriptorListBuilder_.getCount();
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
         }
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>.monitoring.KpiId kpi_id = 2;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor getKpiDescriptorList(int index) {
-        if (kpiDescriptorListBuilder_ == null) {
-          return kpiDescriptorList_.get(index);
-        } else {
-          return kpiDescriptorListBuilder_.getMessage(index);
+      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>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <code>float sampling_duration_s = 3;</code>
+       * @return The samplingDurationS.
        */
-      public Builder setKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor value) {
-        if (kpiDescriptorListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.set(index, value);
-          onChanged();
+      @java.lang.Override
+      public float getSamplingDurationS() {
+        return samplingDurationS_;
+      }
+      /**
+       * <code>float sampling_duration_s = 3;</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 = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingDurationS() {
+        
+        samplingDurationS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float samplingIntervalS_ ;
+      /**
+       * <code>float sampling_interval_s = 4;</code>
+       * @return The samplingIntervalS.
+       */
+      @java.lang.Override
+      public float getSamplingIntervalS() {
+        return samplingIntervalS_;
+      }
+      /**
+       * <code>float sampling_interval_s = 4;</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 = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingIntervalS() {
+        
+        samplingIntervalS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private context.ContextOuterClass.Timestamp startTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> startTimestampBuilder_;
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return Whether the startTimestamp field is set.
+       */
+      public boolean hasStartTimestamp() {
+        return startTimestampBuilder_ != null || startTimestamp_ != null;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       * @return The startTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          return startTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
         } else {
-          kpiDescriptorListBuilder_.setMessage(index, value);
+          return startTimestampBuilder_.getMessage();
         }
-        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder setKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.set(index, builderForValue.build());
+      public Builder setStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          startTimestamp_ = value;
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.setMessage(index, builderForValue.build());
+          startTimestampBuilder_.setMessage(value);
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(monitoring.Monitoring.KpiDescriptor value) {
-        if (kpiDescriptorListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(value);
+      public Builder setStartTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = builderForValue.build();
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.addMessage(value);
+          startTimestampBuilder_.setMessage(builderForValue.build());
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor value) {
-        if (kpiDescriptorListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
+      public Builder mergeStartTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (startTimestampBuilder_ == null) {
+          if (startTimestamp_ != null) {
+            startTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(startTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            startTimestamp_ = value;
           }
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(index, value);
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.addMessage(index, value);
+          startTimestampBuilder_.mergeFrom(value);
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(
-          monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(builderForValue.build());
+      public Builder clearStartTimestamp() {
+        if (startTimestampBuilder_ == null) {
+          startTimestamp_ = null;
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.addMessage(builderForValue.build());
+          startTimestamp_ = null;
+          startTimestampBuilder_ = null;
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addKpiDescriptorList(
-          int index, monitoring.Monitoring.KpiDescriptor.Builder builderForValue) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.add(index, builderForValue.build());
-          onChanged();
+      public context.ContextOuterClass.Timestamp.Builder getStartTimestampBuilder() {
+        
+        onChanged();
+        return getStartTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getStartTimestampOrBuilder() {
+        if (startTimestampBuilder_ != null) {
+          return startTimestampBuilder_.getMessageOrBuilder();
         } else {
-          kpiDescriptorListBuilder_.addMessage(index, builderForValue.build());
+          return startTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : startTimestamp_;
         }
-        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples since X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp start_timestamp = 5;</code>
        */
-      public Builder addAllKpiDescriptorList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiDescriptor> values) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiDescriptorList_);
-          onChanged();
-        } else {
-          kpiDescriptorListBuilder_.addAllMessages(values);
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getStartTimestampFieldBuilder() {
+        if (startTimestampBuilder_ == null) {
+          startTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getStartTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          startTimestamp_ = null;
         }
-        return this;
+        return startTimestampBuilder_;
       }
+
+      private context.ContextOuterClass.Timestamp endTimestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> endTimestampBuilder_;
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return Whether the endTimestamp field is set.
        */
-      public Builder clearKpiDescriptorList() {
-        if (kpiDescriptorListBuilder_ == null) {
-          kpiDescriptorList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
+      public boolean hasEndTimestamp() {
+        return endTimestampBuilder_ != null || endTimestamp_ != null;
+      }
+      /**
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
+       * @return The endTimestamp.
+       */
+      public context.ContextOuterClass.Timestamp getEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          return endTimestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
         } else {
-          kpiDescriptorListBuilder_.clear();
+          return endTimestampBuilder_.getMessage();
         }
-        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public Builder removeKpiDescriptorList(int index) {
-        if (kpiDescriptorListBuilder_ == null) {
-          ensureKpiDescriptorListIsMutable();
-          kpiDescriptorList_.remove(index);
+      public Builder setEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          endTimestamp_ = value;
           onChanged();
         } else {
-          kpiDescriptorListBuilder_.remove(index);
+          endTimestampBuilder_.setMessage(value);
         }
+
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor.Builder getKpiDescriptorListBuilder(
-          int index) {
-        return getKpiDescriptorListFieldBuilder().getBuilder(index);
+      public Builder setEndTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          endTimestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptorOrBuilder getKpiDescriptorListOrBuilder(
-          int index) {
-        if (kpiDescriptorListBuilder_ == null) {
-          return kpiDescriptorList_.get(index);  } else {
-          return kpiDescriptorListBuilder_.getMessageOrBuilder(index);
+      public Builder mergeEndTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (endTimestampBuilder_ == null) {
+          if (endTimestamp_ != null) {
+            endTimestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(endTimestamp_).mergeFrom(value).buildPartial();
+          } else {
+            endTimestamp_ = value;
+          }
+          onChanged();
+        } else {
+          endTimestampBuilder_.mergeFrom(value);
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public java.util.List<? extends monitoring.Monitoring.KpiDescriptorOrBuilder> 
-           getKpiDescriptorListOrBuilderList() {
-        if (kpiDescriptorListBuilder_ != null) {
-          return kpiDescriptorListBuilder_.getMessageOrBuilderList();
+      public Builder clearEndTimestamp() {
+        if (endTimestampBuilder_ == null) {
+          endTimestamp_ = null;
+          onChanged();
         } else {
-          return java.util.Collections.unmodifiableList(kpiDescriptorList_);
+          endTimestamp_ = null;
+          endTimestampBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder() {
-        return getKpiDescriptorListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
+      public context.ContextOuterClass.Timestamp.Builder getEndTimestampBuilder() {
+        
+        onChanged();
+        return getEndTimestampFieldBuilder().getBuilder();
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public monitoring.Monitoring.KpiDescriptor.Builder addKpiDescriptorListBuilder(
-          int index) {
-        return getKpiDescriptorListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiDescriptor.getDefaultInstance());
+      public context.ContextOuterClass.TimestampOrBuilder getEndTimestampOrBuilder() {
+        if (endTimestampBuilder_ != null) {
+          return endTimestampBuilder_.getMessageOrBuilder();
+        } else {
+          return endTimestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : endTimestamp_;
+        }
       }
       /**
-       * <code>repeated .monitoring.KpiDescriptor kpi_descriptor_list = 1;</code>
+       * <pre>
+       * used when you want something like "get the samples until X date/time"
+       * </pre>
+       *
+       * <code>.context.Timestamp end_timestamp = 6;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiDescriptor.Builder> 
-           getKpiDescriptorListBuilderList() {
-        return getKpiDescriptorListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder> 
-          getKpiDescriptorListFieldBuilder() {
-        if (kpiDescriptorListBuilder_ == null) {
-          kpiDescriptorListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiDescriptor.Builder, monitoring.Monitoring.KpiDescriptorOrBuilder>(
-                  kpiDescriptorList_,
-                  ((bitField0_ & 0x00000001) != 0),
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getEndTimestampFieldBuilder() {
+        if (endTimestampBuilder_ == null) {
+          endTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getEndTimestamp(),
                   getParentForChildren(),
                   isClean());
-          kpiDescriptorList_ = null;
+          endTimestamp_ = null;
         }
-        return kpiDescriptorListBuilder_;
+        return endTimestampBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -12578,139 +11517,85 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.KpiDescriptorList)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubsDescriptor)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.KpiDescriptorList)
-    private static final monitoring.Monitoring.KpiDescriptorList DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubsDescriptor)
+    private static final monitoring.Monitoring.SubsDescriptor DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiDescriptorList();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsDescriptor();
     }
 
-    public static monitoring.Monitoring.KpiDescriptorList getDefaultInstance() {
+    public static monitoring.Monitoring.SubsDescriptor getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<KpiDescriptorList>
-        PARSER = new com.google.protobuf.AbstractParser<KpiDescriptorList>() {
+    private static final com.google.protobuf.Parser<SubsDescriptor>
+        PARSER = new com.google.protobuf.AbstractParser<SubsDescriptor>() {
       @java.lang.Override
-      public KpiDescriptorList parsePartialFrom(
+      public SubsDescriptor parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new KpiDescriptorList(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<KpiDescriptorList> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<KpiDescriptorList> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.KpiDescriptorList getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface SubsDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubsDescriptor)
-      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();
+        return new SubsDescriptor(input, extensionRegistry);
+      }
+    };
 
-    /**
-     * <code>float sampling_duration_s = 2;</code>
-     * @return The samplingDurationS.
-     */
-    float getSamplingDurationS();
+    public static com.google.protobuf.Parser<SubsDescriptor> parser() {
+      return PARSER;
+    }
 
-    /**
-     * <code>float sampling_interval_s = 3;</code>
-     * @return The samplingIntervalS.
-     */
-    float getSamplingIntervalS();
+    @java.lang.Override
+    public com.google.protobuf.Parser<SubsDescriptor> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SubscriptionIDOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubscriptionID)
+      com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The startDate.
-     */
-    java.lang.String getStartDate();
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The bytes for startDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
-    com.google.protobuf.ByteString
-        getStartDateBytes();
-
+    boolean hasSubsId();
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return The subsId.
      */
-    java.lang.String getEndDate();
+    context.ContextOuterClass.Uuid getSubsId();
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The bytes for endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
      */
-    com.google.protobuf.ByteString
-        getEndDateBytes();
+    context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.SubsDescriptor}
+   * Protobuf type {@code monitoring.SubscriptionID}
    */
-  public static final class SubsDescriptor extends
+  public static final class SubscriptionID extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubsDescriptor)
-      SubsDescriptorOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubscriptionID)
+      SubscriptionIDOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubsDescriptor.newBuilder() to construct.
-    private SubsDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubscriptionID.newBuilder() to construct.
+    private SubscriptionID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubsDescriptor() {
-      startDate_ = "";
-      endDate_ = "";
+    private SubscriptionID() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubsDescriptor();
+      return new SubscriptionID();
     }
 
     @java.lang.Override
@@ -12718,7 +11603,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubsDescriptor(
+    private SubscriptionID(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -12737,40 +11622,18 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              monitoring.Monitoring.KpiId.Builder subBuilder = null;
-              if (kpiId_ != null) {
-                subBuilder = kpiId_.toBuilder();
+              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              if (subsId_ != null) {
+                subBuilder = subsId_.toBuilder();
               }
-              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              subsId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiId_);
-                kpiId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(subsId_);
+                subsId_ = subBuilder.buildPartial();
               }
 
               break;
             }
-            case 21: {
-
-              samplingDurationS_ = input.readFloat();
-              break;
-            }
-            case 29: {
-
-              samplingIntervalS_ = input.readFloat();
-              break;
-            }
-            case 34: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              startDate_ = s;
-              break;
-            }
-            case 42: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              endDate_ = s;
-              break;
-            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -12792,155 +11655,41 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.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_;
+              monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
     }
 
-    public static final int START_DATE_FIELD_NUMBER = 4;
-    private volatile java.lang.Object startDate_;
-    /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The startDate.
-     */
-    @java.lang.Override
-    public java.lang.String getStartDate() {
-      java.lang.Object ref = startDate_;
-      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();
-        startDate_ = s;
-        return s;
-      }
-    }
+    public static final int SUBS_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid subsId_;
     /**
-     * <pre>
-     * used when you want something like "get the samples since X date/time"
-     * </pre>
-     *
-     * <code>string start_date = 4;</code>
-     * @return The bytes for startDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return Whether the subsId field is set.
      */
     @java.lang.Override
-    public com.google.protobuf.ByteString
-        getStartDateBytes() {
-      java.lang.Object ref = startDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        startDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
+    public boolean hasSubsId() {
+      return subsId_ != null;
     }
-
-    public static final int END_DATE_FIELD_NUMBER = 5;
-    private volatile java.lang.Object endDate_;
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
+     * @return The subsId.
      */
     @java.lang.Override
-    public java.lang.String getEndDate() {
-      java.lang.Object ref = endDate_;
-      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();
-        endDate_ = s;
-        return s;
-      }
+    public context.ContextOuterClass.Uuid getSubsId() {
+      return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
     }
     /**
-     * <pre>
-     * used when you want something like "get the samples until X date/time"
-     * </pre>
-     *
-     * <code>string end_date = 5;</code>
-     * @return The bytes for endDate.
+     * <code>.context.Uuid subs_id = 1;</code>
      */
     @java.lang.Override
-    public com.google.protobuf.ByteString
-        getEndDateBytes() {
-      java.lang.Object ref = endDate_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        endDate_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
+    public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
+      return getSubsId();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -12957,20 +11706,8 @@ public final class Monitoring {
     @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_);
-      }
-      if (!getStartDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, startDate_);
-      }
-      if (!getEndDateBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, endDate_);
+      if (subsId_ != null) {
+        output.writeMessage(1, getSubsId());
       }
       unknownFields.writeTo(output);
     }
@@ -12981,23 +11718,9 @@ public final class Monitoring {
       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) {
+      if (subsId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeFloatSize(3, samplingIntervalS_);
-      }
-      if (!getStartDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, startDate_);
-      }
-      if (!getEndDateBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, endDate_);
+          .computeMessageSize(1, getSubsId());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -13009,26 +11732,16 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubsDescriptor)) {
+      if (!(obj instanceof monitoring.Monitoring.SubscriptionID)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubsDescriptor other = (monitoring.Monitoring.SubsDescriptor) obj;
+      monitoring.Monitoring.SubscriptionID other = (monitoring.Monitoring.SubscriptionID) obj;
 
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
+      if (hasSubsId() != other.hasSubsId()) return false;
+      if (hasSubsId()) {
+        if (!getSubsId()
+            .equals(other.getSubsId())) 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 (!getStartDate()
-          .equals(other.getStartDate())) return false;
-      if (!getEndDate()
-          .equals(other.getEndDate())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -13040,88 +11753,78 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
+      if (hasSubsId()) {
+        hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSubsId().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 = (37 * hash) + START_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getStartDate().hashCode();
-      hash = (37 * hash) + END_DATE_FIELD_NUMBER;
-      hash = (53 * hash) + getEndDate().hashCode();
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID 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.SubsDescriptor parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubscriptionID parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubscriptionID parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID 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.SubsDescriptor parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubscriptionID parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseDelimitedFrom(
+    public static monitoring.Monitoring.SubscriptionID 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.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsDescriptor parseFrom(
+    public static monitoring.Monitoring.SubscriptionID parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -13134,7 +11837,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubsDescriptor prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubscriptionID prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -13150,26 +11853,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubsDescriptor}
+     * Protobuf type {@code monitoring.SubscriptionID}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubsDescriptor)
-        monitoring.Monitoring.SubsDescriptorOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubscriptionID)
+        monitoring.Monitoring.SubscriptionIDOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubsDescriptor.class, monitoring.Monitoring.SubsDescriptor.Builder.class);
+                monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubsDescriptor.newBuilder()
+      // Construct using monitoring.Monitoring.SubscriptionID.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -13187,37 +11890,29 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          subsId_ = null;
+          subsIdBuilder_ = null;
         }
-        samplingDurationS_ = 0F;
-
-        samplingIntervalS_ = 0F;
-
-        startDate_ = "";
-
-        endDate_ = "";
-
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsDescriptor_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubsDescriptor.getDefaultInstance();
+      public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubscriptionID.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsDescriptor build() {
-        monitoring.Monitoring.SubsDescriptor result = buildPartial();
+      public monitoring.Monitoring.SubscriptionID build() {
+        monitoring.Monitoring.SubscriptionID result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -13225,17 +11920,13 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsDescriptor buildPartial() {
-        monitoring.Monitoring.SubsDescriptor result = new monitoring.Monitoring.SubsDescriptor(this);
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
+      public monitoring.Monitoring.SubscriptionID buildPartial() {
+        monitoring.Monitoring.SubscriptionID result = new monitoring.Monitoring.SubscriptionID(this);
+        if (subsIdBuilder_ == null) {
+          result.subsId_ = subsId_;
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          result.subsId_ = subsIdBuilder_.build();
         }
-        result.samplingDurationS_ = samplingDurationS_;
-        result.samplingIntervalS_ = samplingIntervalS_;
-        result.startDate_ = startDate_;
-        result.endDate_ = endDate_;
         onBuilt();
         return result;
       }
@@ -13250,457 +11941,189 @@ public final class Monitoring {
           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.SubsDescriptor) {
-          return mergeFrom((monitoring.Monitoring.SubsDescriptor)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(monitoring.Monitoring.SubsDescriptor other) {
-        if (other == monitoring.Monitoring.SubsDescriptor.getDefaultInstance()) return this;
-        if (other.hasKpiId()) {
-          mergeKpiId(other.getKpiId());
-        }
-        if (other.getSamplingDurationS() != 0F) {
-          setSamplingDurationS(other.getSamplingDurationS());
-        }
-        if (other.getSamplingIntervalS() != 0F) {
-          setSamplingIntervalS(other.getSamplingIntervalS());
-        }
-        if (!other.getStartDate().isEmpty()) {
-          startDate_ = other.startDate_;
-          onChanged();
-        }
-        if (!other.getEndDate().isEmpty()) {
-          endDate_ = other.endDate_;
-          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 {
-        monitoring.Monitoring.SubsDescriptor parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubsDescriptor) 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();
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
       }
-      /**
-       * <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_;
-        }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
       }
-      /**
-       * <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_;
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
       }
-
-      private float samplingDurationS_ ;
-      /**
-       * <code>float sampling_duration_s = 2;</code>
-       * @return The samplingDurationS.
-       */
       @java.lang.Override
-      public float getSamplingDurationS() {
-        return samplingDurationS_;
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
       }
-      /**
-       * <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;
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.SubscriptionID) {
+          return mergeFrom((monitoring.Monitoring.SubscriptionID)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
       }
-      /**
-       * <code>float sampling_duration_s = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearSamplingDurationS() {
-        
-        samplingDurationS_ = 0F;
+
+      public Builder mergeFrom(monitoring.Monitoring.SubscriptionID other) {
+        if (other == monitoring.Monitoring.SubscriptionID.getDefaultInstance()) return this;
+        if (other.hasSubsId()) {
+          mergeSubsId(other.getSubsId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
       }
 
-      private float samplingIntervalS_ ;
-      /**
-       * <code>float sampling_interval_s = 3;</code>
-       * @return The samplingIntervalS.
-       */
       @java.lang.Override
-      public float getSamplingIntervalS() {
-        return samplingIntervalS_;
+      public final boolean isInitialized() {
+        return true;
       }
-      /**
-       * <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();
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.SubscriptionID parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.SubscriptionID) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
         return this;
       }
+
+      private context.ContextOuterClass.Uuid subsId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> subsIdBuilder_;
       /**
-       * <code>float sampling_interval_s = 3;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
+       * @return Whether the subsId field is set.
        */
-      public Builder clearSamplingIntervalS() {
-        
-        samplingIntervalS_ = 0F;
-        onChanged();
-        return this;
+      public boolean hasSubsId() {
+        return subsIdBuilder_ != null || subsId_ != null;
       }
-
-      private java.lang.Object startDate_ = "";
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @return The startDate.
+       * <code>.context.Uuid subs_id = 1;</code>
+       * @return The subsId.
        */
-      public java.lang.String getStartDate() {
-        java.lang.Object ref = startDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          startDate_ = s;
-          return s;
+      public context.ContextOuterClass.Uuid getSubsId() {
+        if (subsIdBuilder_ == null) {
+          return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
         } else {
-          return (java.lang.String) ref;
+          return subsIdBuilder_.getMessage();
         }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @return The bytes for startDate.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public com.google.protobuf.ByteString
-          getStartDateBytes() {
-        java.lang.Object ref = startDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          startDate_ = b;
-          return b;
+      public Builder setSubsId(context.ContextOuterClass.Uuid value) {
+        if (subsIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          subsId_ = value;
+          onChanged();
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          subsIdBuilder_.setMessage(value);
         }
-      }
-      /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @param value The startDate to set.
-       * @return This builder for chaining.
-       */
-      public Builder setStartDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        startDate_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearStartDate() {
-        
-        startDate_ = getDefaultInstance().getStartDate();
-        onChanged();
+
         return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples since X date/time"
-       * </pre>
-       *
-       * <code>string start_date = 4;</code>
-       * @param value The bytes for startDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder setStartDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        startDate_ = value;
-        onChanged();
+      public Builder setSubsId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (subsIdBuilder_ == null) {
+          subsId_ = builderForValue.build();
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(builderForValue.build());
+        }
+
         return this;
       }
-
-      private java.lang.Object endDate_ = "";
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @return The endDate.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public java.lang.String getEndDate() {
-        java.lang.Object ref = endDate_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          endDate_ = s;
-          return s;
+      public Builder mergeSubsId(context.ContextOuterClass.Uuid value) {
+        if (subsIdBuilder_ == null) {
+          if (subsId_ != null) {
+            subsId_ =
+              context.ContextOuterClass.Uuid.newBuilder(subsId_).mergeFrom(value).buildPartial();
+          } else {
+            subsId_ = value;
+          }
+          onChanged();
         } else {
-          return (java.lang.String) ref;
+          subsIdBuilder_.mergeFrom(value);
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @return The bytes for endDate.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public com.google.protobuf.ByteString
-          getEndDateBytes() {
-        java.lang.Object ref = endDate_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          endDate_ = b;
-          return b;
+      public Builder clearSubsId() {
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
+          onChanged();
         } else {
-          return (com.google.protobuf.ByteString) ref;
+          subsId_ = null;
+          subsIdBuilder_ = null;
         }
+
+        return this;
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @param value The endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder setEndDate(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        endDate_ = value;
+      public context.ContextOuterClass.Uuid.Builder getSubsIdBuilder() {
+        
         onChanged();
-        return this;
+        return getSubsIdFieldBuilder().getBuilder();
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder clearEndDate() {
-        
-        endDate_ = getDefaultInstance().getEndDate();
-        onChanged();
-        return this;
+      public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
+        if (subsIdBuilder_ != null) {
+          return subsIdBuilder_.getMessageOrBuilder();
+        } else {
+          return subsId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+        }
       }
       /**
-       * <pre>
-       * used when you want something like "get the samples until X date/time"
-       * </pre>
-       *
-       * <code>string end_date = 5;</code>
-       * @param value The bytes for endDate to set.
-       * @return This builder for chaining.
+       * <code>.context.Uuid subs_id = 1;</code>
        */
-      public Builder setEndDateBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        endDate_ = value;
-        onChanged();
-        return this;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getSubsIdFieldBuilder() {
+        if (subsIdBuilder_ == null) {
+          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getSubsId(),
+                  getParentForChildren(),
+                  isClean());
+          subsId_ = null;
+        }
+        return subsIdBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -13715,85 +12138,110 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.SubsDescriptor)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubscriptionID)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.SubsDescriptor)
-    private static final monitoring.Monitoring.SubsDescriptor DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubscriptionID)
+    private static final monitoring.Monitoring.SubscriptionID DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsDescriptor();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubscriptionID();
     }
 
-    public static monitoring.Monitoring.SubsDescriptor getDefaultInstance() {
+    public static monitoring.Monitoring.SubscriptionID getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<SubsDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<SubsDescriptor>() {
+    private static final com.google.protobuf.Parser<SubscriptionID>
+        PARSER = new com.google.protobuf.AbstractParser<SubscriptionID>() {
       @java.lang.Override
-      public SubsDescriptor parsePartialFrom(
+      public SubscriptionID parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubsDescriptor(input, extensionRegistry);
+        return new SubscriptionID(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<SubsDescriptor> parser() {
+    public static com.google.protobuf.Parser<SubscriptionID> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<SubsDescriptor> getParserForType() {
+    public com.google.protobuf.Parser<SubscriptionID> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.SubsDescriptor getDefaultInstanceForType() {
+    public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface SubscriptionIDOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubscriptionID)
+  public interface SubsResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubsResponse)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return Whether the subsId field is set.
      */
     boolean hasSubsId();
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return The subsId.
      */
-    context.ContextOuterClass.Uuid getSubsId();
+    monitoring.Monitoring.SubscriptionID getSubsId();
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder();
+    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder();
+
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiList> 
+        getKpiListList();
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    monitoring.Monitoring.KpiList getKpiList(int index);
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    int getKpiListCount();
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
+        getKpiListOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+        int index);
   }
   /**
-   * Protobuf type {@code monitoring.SubscriptionID}
+   * Protobuf type {@code monitoring.SubsResponse}
    */
-  public static final class SubscriptionID extends
+  public static final class SubsResponse extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubscriptionID)
-      SubscriptionIDOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubsResponse)
+      SubsResponseOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubscriptionID.newBuilder() to construct.
-    private SubscriptionID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubsResponse.newBuilder() to construct.
+    private SubsResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubscriptionID() {
+    private SubsResponse() {
+      kpiList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubscriptionID();
+      return new SubsResponse();
     }
 
     @java.lang.Override
@@ -13801,7 +12249,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubscriptionID(
+    private SubsResponse(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -13809,6 +12257,7 @@ public final class Monitoring {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -13820,11 +12269,11 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              monitoring.Monitoring.SubscriptionID.Builder subBuilder = null;
               if (subsId_ != null) {
                 subBuilder = subsId_.toBuilder();
               }
-              subsId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              subsId_ = input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(subsId_);
                 subsId_ = subBuilder.buildPartial();
@@ -13832,6 +12281,15 @@ public final class Monitoring {
 
               break;
             }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              kpiList_.add(
+                  input.readMessage(monitoring.Monitoring.KpiList.parser(), extensionRegistry));
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -13847,27 +12305,30 @@ public final class Monitoring {
         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_SubscriptionID_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
+              monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
     }
 
     public static final int SUBS_ID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid subsId_;
+    private monitoring.Monitoring.SubscriptionID subsId_;
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return Whether the subsId field is set.
      */
     @java.lang.Override
@@ -13875,21 +12336,61 @@ public final class Monitoring {
       return subsId_ != null;
     }
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      * @return The subsId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getSubsId() {
-      return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+    public monitoring.Monitoring.SubscriptionID getSubsId() {
+      return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
     }
     /**
-     * <code>.context.Uuid subs_id = 1;</code>
+     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
+    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
       return getSubsId();
     }
 
+    public static final int KPI_LIST_FIELD_NUMBER = 2;
+    private java.util.List<monitoring.Monitoring.KpiList> kpiList_;
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
+      return kpiList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
+        getKpiListOrBuilderList() {
+      return kpiList_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public int getKpiListCount() {
+      return kpiList_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiList getKpiList(int index) {
+      return kpiList_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+        int index) {
+      return kpiList_.get(index);
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -13907,6 +12408,9 @@ public final class Monitoring {
       if (subsId_ != null) {
         output.writeMessage(1, getSubsId());
       }
+      for (int i = 0; i < kpiList_.size(); i++) {
+        output.writeMessage(2, kpiList_.get(i));
+      }
       unknownFields.writeTo(output);
     }
 
@@ -13920,6 +12424,10 @@ public final class Monitoring {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getSubsId());
       }
+      for (int i = 0; i < kpiList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, kpiList_.get(i));
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -13930,16 +12438,18 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubscriptionID)) {
+      if (!(obj instanceof monitoring.Monitoring.SubsResponse)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubscriptionID other = (monitoring.Monitoring.SubscriptionID) obj;
+      monitoring.Monitoring.SubsResponse other = (monitoring.Monitoring.SubsResponse) obj;
 
       if (hasSubsId() != other.hasSubsId()) return false;
       if (hasSubsId()) {
         if (!getSubsId()
             .equals(other.getSubsId())) return false;
       }
+      if (!getKpiListList()
+          .equals(other.getKpiListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -13955,74 +12465,78 @@ public final class Monitoring {
         hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
         hash = (53 * hash) + getSubsId().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.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse 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.SubscriptionID parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubsResponse parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsResponse parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse 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.SubscriptionID parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsResponse parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubscriptionID parseDelimitedFrom(
+    public static monitoring.Monitoring.SubsResponse 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.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubscriptionID parseFrom(
+    public static monitoring.Monitoring.SubsResponse parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -14035,7 +12549,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubscriptionID prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubsResponse prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -14051,26 +12565,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubscriptionID}
+     * Protobuf type {@code monitoring.SubsResponse}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubscriptionID)
-        monitoring.Monitoring.SubscriptionIDOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubsResponse)
+        monitoring.Monitoring.SubsResponseOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubscriptionID_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubscriptionID.class, monitoring.Monitoring.SubscriptionID.Builder.class);
+                monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubscriptionID.newBuilder()
+      // Construct using monitoring.Monitoring.SubsResponse.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -14083,6 +12597,7 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getKpiListFieldBuilder();
         }
       }
       @java.lang.Override
@@ -14094,23 +12609,29 @@ public final class Monitoring {
           subsId_ = null;
           subsIdBuilder_ = null;
         }
+        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_SubscriptionID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubscriptionID.getDefaultInstance();
+      public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubsResponse.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubscriptionID build() {
-        monitoring.Monitoring.SubscriptionID result = buildPartial();
+      public monitoring.Monitoring.SubsResponse build() {
+        monitoring.Monitoring.SubsResponse result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -14118,13 +12639,23 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubscriptionID buildPartial() {
-        monitoring.Monitoring.SubscriptionID result = new monitoring.Monitoring.SubscriptionID(this);
+      public monitoring.Monitoring.SubsResponse buildPartial() {
+        monitoring.Monitoring.SubsResponse result = new monitoring.Monitoring.SubsResponse(this);
+        int from_bitField0_ = bitField0_;
         if (subsIdBuilder_ == null) {
           result.subsId_ = subsId_;
         } else {
           result.subsId_ = subsIdBuilder_.build();
         }
+        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;
       }
@@ -14163,19 +12694,45 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.SubscriptionID) {
-          return mergeFrom((monitoring.Monitoring.SubscriptionID)other);
+        if (other instanceof monitoring.Monitoring.SubsResponse) {
+          return mergeFrom((monitoring.Monitoring.SubsResponse)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.SubscriptionID other) {
-        if (other == monitoring.Monitoring.SubscriptionID.getDefaultInstance()) return this;
+      public Builder mergeFrom(monitoring.Monitoring.SubsResponse other) {
+        if (other == monitoring.Monitoring.SubsResponse.getDefaultInstance()) return this;
         if (other.hasSubsId()) {
           mergeSubsId(other.getSubsId());
         }
+        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;
@@ -14191,11 +12748,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.SubscriptionID parsedMessage = null;
+        monitoring.Monitoring.SubsResponse parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubscriptionID) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.SubsResponse) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -14204,124 +12761,365 @@ public final class Monitoring {
         }
         return this;
       }
-
-      private context.ContextOuterClass.Uuid subsId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> subsIdBuilder_;
+      private int bitField0_;
+
+      private monitoring.Monitoring.SubscriptionID subsId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsIdBuilder_;
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return Whether the subsId field is set.
+       */
+      public boolean hasSubsId() {
+        return subsIdBuilder_ != null || subsId_ != null;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       * @return The subsId.
+       */
+      public monitoring.Monitoring.SubscriptionID getSubsId() {
+        if (subsIdBuilder_ == null) {
+          return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        } else {
+          return subsIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          subsId_ = value;
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder setSubsId(
+          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsIdBuilder_ == null) {
+          subsId_ = builderForValue.build();
+          onChanged();
+        } else {
+          subsIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder mergeSubsId(monitoring.Monitoring.SubscriptionID value) {
+        if (subsIdBuilder_ == null) {
+          if (subsId_ != null) {
+            subsId_ =
+              monitoring.Monitoring.SubscriptionID.newBuilder(subsId_).mergeFrom(value).buildPartial();
+          } else {
+            subsId_ = value;
+          }
+          onChanged();
+        } else {
+          subsIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public Builder clearSubsId() {
+        if (subsIdBuilder_ == null) {
+          subsId_ = null;
+          onChanged();
+        } else {
+          subsId_ = null;
+          subsIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionID.Builder getSubsIdBuilder() {
+        
+        onChanged();
+        return getSubsIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
+        if (subsIdBuilder_ != null) {
+          return subsIdBuilder_.getMessageOrBuilder();
+        } else {
+          return subsId_ == null ?
+              monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
+        }
+      }
+      /**
+       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
+          getSubsIdFieldBuilder() {
+        if (subsIdBuilder_ == null) {
+          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
+                  getSubsId(),
+                  getParentForChildren(),
+                  isClean());
+          subsId_ = null;
+        }
+        return subsIdBuilder_;
+      }
+
+      private java.util.List<monitoring.Monitoring.KpiList> kpiList_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>(kpiList_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> kpiListBuilder_;
+
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
+        if (kpiListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        } else {
+          return kpiListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public int getKpiListCount() {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.size();
+        } else {
+          return kpiListBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiList getKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);
+        } else {
+          return kpiListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public Builder setKpiList(
+          int index, monitoring.Monitoring.KpiList value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.set(index, value);
+          onChanged();
+        } else {
+          kpiListBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
-       * @return Whether the subsId field is set.
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public boolean hasSubsId() {
-        return subsIdBuilder_ != null || subsId_ != null;
+      public Builder setKpiList(
+          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiListBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
-       * @return The subsId.
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public context.ContextOuterClass.Uuid getSubsId() {
-        if (subsIdBuilder_ == null) {
-          return subsId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+      public Builder addKpiList(monitoring.Monitoring.KpiList value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.add(value);
+          onChanged();
         } else {
-          return subsIdBuilder_.getMessage();
+          kpiListBuilder_.addMessage(value);
         }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder setSubsId(context.ContextOuterClass.Uuid value) {
-        if (subsIdBuilder_ == null) {
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.KpiList value) {
+        if (kpiListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          subsId_ = value;
+          ensureKpiListIsMutable();
+          kpiList_.add(index, value);
           onChanged();
         } else {
-          subsIdBuilder_.setMessage(value);
+          kpiListBuilder_.addMessage(index, value);
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder setSubsId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
-        if (subsIdBuilder_ == null) {
-          subsId_ = builderForValue.build();
+      public Builder addKpiList(
+          monitoring.Monitoring.KpiList.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(builderForValue.build());
           onChanged();
         } else {
-          subsIdBuilder_.setMessage(builderForValue.build());
+          kpiListBuilder_.addMessage(builderForValue.build());
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder mergeSubsId(context.ContextOuterClass.Uuid value) {
-        if (subsIdBuilder_ == null) {
-          if (subsId_ != null) {
-            subsId_ =
-              context.ContextOuterClass.Uuid.newBuilder(subsId_).mergeFrom(value).buildPartial();
-          } else {
-            subsId_ = value;
-          }
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          subsIdBuilder_.mergeFrom(value);
+          kpiListBuilder_.addMessage(index, builderForValue.build());
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public Builder clearSubsId() {
-        if (subsIdBuilder_ == null) {
-          subsId_ = null;
+      public Builder addAllKpiList(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiList> values) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiList_);
           onChanged();
         } else {
-          subsId_ = null;
-          subsIdBuilder_ = null;
+          kpiListBuilder_.addAllMessages(values);
         }
-
         return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public context.ContextOuterClass.Uuid.Builder getSubsIdBuilder() {
-        
-        onChanged();
-        return getSubsIdFieldBuilder().getBuilder();
+      public Builder clearKpiList() {
+        if (kpiListBuilder_ == null) {
+          kpiList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiListBuilder_.clear();
+        }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      public context.ContextOuterClass.UuidOrBuilder getSubsIdOrBuilder() {
-        if (subsIdBuilder_ != null) {
-          return subsIdBuilder_.getMessageOrBuilder();
+      public Builder removeKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.remove(index);
+          onChanged();
         } else {
-          return subsId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : subsId_;
+          kpiListBuilder_.remove(index);
         }
+        return this;
       }
       /**
-       * <code>.context.Uuid subs_id = 1;</code>
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
-          getSubsIdFieldBuilder() {
-        if (subsIdBuilder_ == null) {
-          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
-                  getSubsId(),
+      public monitoring.Monitoring.KpiList.Builder getKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+          int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);  } else {
+          return kpiListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
+           getKpiListOrBuilderList() {
+        if (kpiListBuilder_ != null) {
+          return kpiListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder() {
+        return getKpiListFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiList.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiList.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiList.Builder> 
+           getKpiListBuilderList() {
+        return getKpiListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> 
+          getKpiListFieldBuilder() {
+        if (kpiListBuilder_ == null) {
+          kpiListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder>(
+                  kpiList_,
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          subsId_ = null;
+          kpiList_ = null;
         }
-        return subsIdBuilder_;
+        return kpiListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -14336,110 +13134,95 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.SubscriptionID)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubsResponse)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.SubscriptionID)
-    private static final monitoring.Monitoring.SubscriptionID DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubsResponse)
+    private static final monitoring.Monitoring.SubsResponse DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubscriptionID();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsResponse();
     }
 
-    public static monitoring.Monitoring.SubscriptionID getDefaultInstance() {
+    public static monitoring.Monitoring.SubsResponse getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<SubscriptionID>
-        PARSER = new com.google.protobuf.AbstractParser<SubscriptionID>() {
+    private static final com.google.protobuf.Parser<SubsResponse>
+        PARSER = new com.google.protobuf.AbstractParser<SubsResponse>() {
       @java.lang.Override
-      public SubscriptionID parsePartialFrom(
+      public SubsResponse parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubscriptionID(input, extensionRegistry);
+        return new SubsResponse(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<SubscriptionID> parser() {
+    public static com.google.protobuf.Parser<SubsResponse> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<SubscriptionID> getParserForType() {
+    public com.google.protobuf.Parser<SubsResponse> getParserForType() {
       return PARSER;
     }
 
-    @java.lang.Override
-    public monitoring.Monitoring.SubscriptionID getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface SubsResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubsResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return Whether the subsId field is set.
-     */
-    boolean hasSubsId();
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return The subsId.
-     */
-    monitoring.Monitoring.SubscriptionID getSubsId();
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     */
-    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder();
-
+    @java.lang.Override
+    public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SubsIDListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.SubsIDList)
+      com.google.protobuf.MessageOrBuilder {
+
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    java.util.List<monitoring.Monitoring.KpiList> 
-        getKpiListList();
+    java.util.List<monitoring.Monitoring.SubscriptionID> 
+        getSubsListList();
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    monitoring.Monitoring.KpiList getKpiList(int index);
+    monitoring.Monitoring.SubscriptionID getSubsList(int index);
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    int getKpiListCount();
+    int getSubsListCount();
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
-        getKpiListOrBuilderList();
+    java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
+        getSubsListOrBuilderList();
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
-    monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
         int index);
   }
   /**
-   * Protobuf type {@code monitoring.SubsResponse}
+   * Protobuf type {@code monitoring.SubsIDList}
    */
-  public static final class SubsResponse extends
+  public static final class SubsIDList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubsResponse)
-      SubsResponseOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.SubsIDList)
+      SubsIDListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubsResponse.newBuilder() to construct.
-    private SubsResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SubsIDList.newBuilder() to construct.
+    private SubsIDList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubsResponse() {
-      kpiList_ = java.util.Collections.emptyList();
+    private SubsIDList() {
+      subsList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubsResponse();
+      return new SubsIDList();
     }
 
     @java.lang.Override
@@ -14447,7 +13230,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubsResponse(
+    private SubsIDList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -14467,25 +13250,12 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              monitoring.Monitoring.SubscriptionID.Builder subBuilder = null;
-              if (subsId_ != null) {
-                subBuilder = subsId_.toBuilder();
-              }
-              subsId_ = input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(subsId_);
-                subsId_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 18: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>();
+                subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              kpiList_.add(
-                  input.readMessage(monitoring.Monitoring.KpiList.parser(), extensionRegistry));
+              subsList_.add(
+                  input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry));
               break;
             }
             default: {
@@ -14504,7 +13274,7 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+          subsList_ = java.util.Collections.unmodifiableList(subsList_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -14512,81 +13282,55 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
-    }
-
-    public static final int SUBS_ID_FIELD_NUMBER = 1;
-    private monitoring.Monitoring.SubscriptionID subsId_;
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return Whether the subsId field is set.
-     */
-    @java.lang.Override
-    public boolean hasSubsId() {
-      return subsId_ != null;
-    }
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     * @return The subsId.
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.SubscriptionID getSubsId() {
-      return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
-    }
-    /**
-     * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
-      return getSubsId();
+              monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
     }
 
-    public static final int KPI_LIST_FIELD_NUMBER = 2;
-    private java.util.List<monitoring.Monitoring.KpiList> kpiList_;
+    public static final int SUBS_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_;
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
-      return kpiList_;
+    public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
+      return subsList_;
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
-        getKpiListOrBuilderList() {
-      return kpiList_;
+    public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
+        getSubsListOrBuilderList() {
+      return subsList_;
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public int getKpiListCount() {
-      return kpiList_.size();
+    public int getSubsListCount() {
+      return subsList_.size();
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiList getKpiList(int index) {
-      return kpiList_.get(index);
+    public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
+      return subsList_.get(index);
     }
     /**
-     * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
      */
     @java.lang.Override
-    public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
         int index) {
-      return kpiList_.get(index);
+      return subsList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -14603,11 +13347,8 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (subsId_ != null) {
-        output.writeMessage(1, getSubsId());
-      }
-      for (int i = 0; i < kpiList_.size(); i++) {
-        output.writeMessage(2, kpiList_.get(i));
+      for (int i = 0; i < subsList_.size(); i++) {
+        output.writeMessage(1, subsList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -14618,13 +13359,9 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (subsId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getSubsId());
-      }
-      for (int i = 0; i < kpiList_.size(); i++) {
+      for (int i = 0; i < subsList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, kpiList_.get(i));
+          .computeMessageSize(1, subsList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -14636,18 +13373,13 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubsResponse)) {
+      if (!(obj instanceof monitoring.Monitoring.SubsIDList)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubsResponse other = (monitoring.Monitoring.SubsResponse) obj;
+      monitoring.Monitoring.SubsIDList other = (monitoring.Monitoring.SubsIDList) obj;
 
-      if (hasSubsId() != other.hasSubsId()) return false;
-      if (hasSubsId()) {
-        if (!getSubsId()
-            .equals(other.getSubsId())) return false;
-      }
-      if (!getKpiListList()
-          .equals(other.getKpiListList())) return false;
+      if (!getSubsListList()
+          .equals(other.getSubsListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -14659,82 +13391,78 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasSubsId()) {
-        hash = (37 * hash) + SUBS_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getSubsId().hashCode();
-      }
-      if (getKpiListCount() > 0) {
-        hash = (37 * hash) + KPI_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiListList().hashCode();
+      if (getSubsListCount() > 0) {
+        hash = (37 * hash) + SUBS_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getSubsListList().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList 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.SubsResponse parseFrom(byte[] data)
+    public static monitoring.Monitoring.SubsIDList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsIDList parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList 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.SubsResponse parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.SubsIDList parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsResponse parseDelimitedFrom(
+    public static monitoring.Monitoring.SubsIDList 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.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsResponse parseFrom(
+    public static monitoring.Monitoring.SubsIDList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -14747,7 +13475,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubsResponse prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.SubsIDList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -14763,26 +13491,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubsResponse}
+     * Protobuf type {@code monitoring.SubsIDList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubsResponse)
-        monitoring.Monitoring.SubsResponseOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.SubsIDList)
+        monitoring.Monitoring.SubsIDListOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubsResponse.class, monitoring.Monitoring.SubsResponse.Builder.class);
+                monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubsResponse.newBuilder()
+      // Construct using monitoring.Monitoring.SubsIDList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -14795,23 +13523,17 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getKpiListFieldBuilder();
+          getSubsListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (subsIdBuilder_ == null) {
-          subsId_ = null;
-        } else {
-          subsId_ = null;
-          subsIdBuilder_ = null;
-        }
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+        if (subsListBuilder_ == null) {
+          subsList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          kpiListBuilder_.clear();
+          subsListBuilder_.clear();
         }
         return this;
       }
@@ -14819,40 +13541,35 @@ public final class Monitoring {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsResponse_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubsResponse.getDefaultInstance();
+      public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
+        return monitoring.Monitoring.SubsIDList.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.SubsResponse build() {
-        monitoring.Monitoring.SubsResponse result = buildPartial();
+      public monitoring.Monitoring.SubsIDList build() {
+        monitoring.Monitoring.SubsIDList result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
         return result;
       }
 
-      @java.lang.Override
-      public monitoring.Monitoring.SubsResponse buildPartial() {
-        monitoring.Monitoring.SubsResponse result = new monitoring.Monitoring.SubsResponse(this);
-        int from_bitField0_ = bitField0_;
-        if (subsIdBuilder_ == null) {
-          result.subsId_ = subsId_;
-        } else {
-          result.subsId_ = subsIdBuilder_.build();
-        }
-        if (kpiListBuilder_ == null) {
+      @java.lang.Override
+      public monitoring.Monitoring.SubsIDList buildPartial() {
+        monitoring.Monitoring.SubsIDList result = new monitoring.Monitoring.SubsIDList(this);
+        int from_bitField0_ = bitField0_;
+        if (subsListBuilder_ == null) {
           if (((bitField0_ & 0x00000001) != 0)) {
-            kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+            subsList_ = java.util.Collections.unmodifiableList(subsList_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
-          result.kpiList_ = kpiList_;
+          result.subsList_ = subsList_;
         } else {
-          result.kpiList_ = kpiListBuilder_.build();
+          result.subsList_ = subsListBuilder_.build();
         }
         onBuilt();
         return result;
@@ -14892,42 +13609,39 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.SubsResponse) {
-          return mergeFrom((monitoring.Monitoring.SubsResponse)other);
+        if (other instanceof monitoring.Monitoring.SubsIDList) {
+          return mergeFrom((monitoring.Monitoring.SubsIDList)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.SubsResponse other) {
-        if (other == monitoring.Monitoring.SubsResponse.getDefaultInstance()) return this;
-        if (other.hasSubsId()) {
-          mergeSubsId(other.getSubsId());
-        }
-        if (kpiListBuilder_ == null) {
-          if (!other.kpiList_.isEmpty()) {
-            if (kpiList_.isEmpty()) {
-              kpiList_ = other.kpiList_;
+      public Builder mergeFrom(monitoring.Monitoring.SubsIDList other) {
+        if (other == monitoring.Monitoring.SubsIDList.getDefaultInstance()) return this;
+        if (subsListBuilder_ == null) {
+          if (!other.subsList_.isEmpty()) {
+            if (subsList_.isEmpty()) {
+              subsList_ = other.subsList_;
               bitField0_ = (bitField0_ & ~0x00000001);
             } else {
-              ensureKpiListIsMutable();
-              kpiList_.addAll(other.kpiList_);
+              ensureSubsListIsMutable();
+              subsList_.addAll(other.subsList_);
             }
             onChanged();
           }
         } else {
-          if (!other.kpiList_.isEmpty()) {
-            if (kpiListBuilder_.isEmpty()) {
-              kpiListBuilder_.dispose();
-              kpiListBuilder_ = null;
-              kpiList_ = other.kpiList_;
+          if (!other.subsList_.isEmpty()) {
+            if (subsListBuilder_.isEmpty()) {
+              subsListBuilder_.dispose();
+              subsListBuilder_ = null;
+              subsList_ = other.subsList_;
               bitField0_ = (bitField0_ & ~0x00000001);
-              kpiListBuilder_ = 
+              subsListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getKpiListFieldBuilder() : null;
+                   getSubsListFieldBuilder() : null;
             } else {
-              kpiListBuilder_.addAllMessages(other.kpiList_);
+              subsListBuilder_.addAllMessages(other.subsList_);
             }
           }
         }
@@ -14946,11 +13660,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.SubsResponse parsedMessage = null;
+        monitoring.Monitoring.SubsIDList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubsResponse) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.SubsIDList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -14961,363 +13675,244 @@ public final class Monitoring {
       }
       private int bitField0_;
 
-      private monitoring.Monitoring.SubscriptionID subsId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsIdBuilder_;
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       * @return Whether the subsId field is set.
-       */
-      public boolean hasSubsId() {
-        return subsIdBuilder_ != null || subsId_ != null;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       * @return The subsId.
-       */
-      public monitoring.Monitoring.SubscriptionID getSubsId() {
-        if (subsIdBuilder_ == null) {
-          return subsId_ == null ? monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
-        } else {
-          return subsIdBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder setSubsId(monitoring.Monitoring.SubscriptionID value) {
-        if (subsIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          subsId_ = value;
-          onChanged();
-        } else {
-          subsIdBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder setSubsId(
-          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsIdBuilder_ == null) {
-          subsId_ = builderForValue.build();
-          onChanged();
-        } else {
-          subsIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder mergeSubsId(monitoring.Monitoring.SubscriptionID value) {
-        if (subsIdBuilder_ == null) {
-          if (subsId_ != null) {
-            subsId_ =
-              monitoring.Monitoring.SubscriptionID.newBuilder(subsId_).mergeFrom(value).buildPartial();
-          } else {
-            subsId_ = value;
-          }
-          onChanged();
-        } else {
-          subsIdBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public Builder clearSubsId() {
-        if (subsIdBuilder_ == null) {
-          subsId_ = null;
-          onChanged();
-        } else {
-          subsId_ = null;
-          subsIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder getSubsIdBuilder() {
-        
-        onChanged();
-        return getSubsIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsIdOrBuilder() {
-        if (subsIdBuilder_ != null) {
-          return subsIdBuilder_.getMessageOrBuilder();
-        } else {
-          return subsId_ == null ?
-              monitoring.Monitoring.SubscriptionID.getDefaultInstance() : subsId_;
-        }
-      }
-      /**
-       * <code>.monitoring.SubscriptionID subs_id = 1;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
-          getSubsIdFieldBuilder() {
-        if (subsIdBuilder_ == null) {
-          subsIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
-                  getSubsId(),
-                  getParentForChildren(),
-                  isClean());
-          subsId_ = null;
-        }
-        return subsIdBuilder_;
-      }
-
-      private java.util.List<monitoring.Monitoring.KpiList> kpiList_ =
+      private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_ =
         java.util.Collections.emptyList();
-      private void ensureKpiListIsMutable() {
+      private void ensureSubsListIsMutable() {
         if (!((bitField0_ & 0x00000001) != 0)) {
-          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.KpiList>(kpiList_);
+          subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>(subsList_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> kpiListBuilder_;
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsListBuilder_;
 
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiList> getKpiListList() {
-        if (kpiListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(kpiList_);
+      public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
+        if (subsListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(subsList_);
         } else {
-          return kpiListBuilder_.getMessageList();
+          return subsListBuilder_.getMessageList();
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public int getKpiListCount() {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.size();
+      public int getSubsListCount() {
+        if (subsListBuilder_ == null) {
+          return subsList_.size();
         } else {
-          return kpiListBuilder_.getCount();
+          return subsListBuilder_.getCount();
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList getKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);
+      public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
+        if (subsListBuilder_ == null) {
+          return subsList_.get(index);
         } else {
-          return kpiListBuilder_.getMessage(index);
+          return subsListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.KpiList value) {
-        if (kpiListBuilder_ == null) {
+      public Builder setSubsList(
+          int index, monitoring.Monitoring.SubscriptionID value) {
+        if (subsListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.set(index, value);
+          ensureSubsListIsMutable();
+          subsList_.set(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, value);
+          subsListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder setKpiList(
-          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.set(index, builderForValue.build());
+      public Builder setSubsList(
+          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.setMessage(index, builderForValue.build());
+          subsListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addKpiList(monitoring.Monitoring.KpiList value) {
-        if (kpiListBuilder_ == null) {
+      public Builder addSubsList(monitoring.Monitoring.SubscriptionID value) {
+        if (subsListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(value);
+          ensureSubsListIsMutable();
+          subsList_.add(value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(value);
+          subsListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
-       */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.KpiList value) {
-        if (kpiListBuilder_ == null) {
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+       */
+      public Builder addSubsList(
+          int index, monitoring.Monitoring.SubscriptionID value) {
+        if (subsListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureKpiListIsMutable();
-          kpiList_.add(index, value);
+          ensureSubsListIsMutable();
+          subsList_.add(index, value);
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, value);
+          subsListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addKpiList(
-          monitoring.Monitoring.KpiList.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(builderForValue.build());
+      public Builder addSubsList(
+          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.add(builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(builderForValue.build());
+          subsListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addKpiList(
-          int index, monitoring.Monitoring.KpiList.Builder builderForValue) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.add(index, builderForValue.build());
+      public Builder addSubsList(
+          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          kpiListBuilder_.addMessage(index, builderForValue.build());
+          subsListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder addAllKpiList(
-          java.lang.Iterable<? extends monitoring.Monitoring.KpiList> values) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
+      public Builder addAllSubsList(
+          java.lang.Iterable<? extends monitoring.Monitoring.SubscriptionID> values) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, kpiList_);
+              values, subsList_);
           onChanged();
         } else {
-          kpiListBuilder_.addAllMessages(values);
+          subsListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder clearKpiList() {
-        if (kpiListBuilder_ == null) {
-          kpiList_ = java.util.Collections.emptyList();
+      public Builder clearSubsList() {
+        if (subsListBuilder_ == null) {
+          subsList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          kpiListBuilder_.clear();
+          subsListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public Builder removeKpiList(int index) {
-        if (kpiListBuilder_ == null) {
-          ensureKpiListIsMutable();
-          kpiList_.remove(index);
+      public Builder removeSubsList(int index) {
+        if (subsListBuilder_ == null) {
+          ensureSubsListIsMutable();
+          subsList_.remove(index);
           onChanged();
         } else {
-          kpiListBuilder_.remove(index);
+          subsListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList.Builder getKpiListBuilder(
+      public monitoring.Monitoring.SubscriptionID.Builder getSubsListBuilder(
           int index) {
-        return getKpiListFieldBuilder().getBuilder(index);
+        return getSubsListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiListOrBuilder getKpiListOrBuilder(
+      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
           int index) {
-        if (kpiListBuilder_ == null) {
-          return kpiList_.get(index);  } else {
-          return kpiListBuilder_.getMessageOrBuilder(index);
+        if (subsListBuilder_ == null) {
+          return subsList_.get(index);  } else {
+          return subsListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public java.util.List<? extends monitoring.Monitoring.KpiListOrBuilder> 
-           getKpiListOrBuilderList() {
-        if (kpiListBuilder_ != null) {
-          return kpiListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
+           getSubsListOrBuilderList() {
+        if (subsListBuilder_ != null) {
+          return subsListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(kpiList_);
+          return java.util.Collections.unmodifiableList(subsList_);
         }
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder() {
-        return getKpiListFieldBuilder().addBuilder(
-            monitoring.Monitoring.KpiList.getDefaultInstance());
+      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder() {
+        return getSubsListFieldBuilder().addBuilder(
+            monitoring.Monitoring.SubscriptionID.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public monitoring.Monitoring.KpiList.Builder addKpiListBuilder(
+      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder(
           int index) {
-        return getKpiListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.KpiList.getDefaultInstance());
+        return getSubsListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.SubscriptionID.getDefaultInstance());
       }
       /**
-       * <code>repeated .monitoring.KpiList kpi_list = 2;</code>
+       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
        */
-      public java.util.List<monitoring.Monitoring.KpiList.Builder> 
-           getKpiListBuilderList() {
-        return getKpiListFieldBuilder().getBuilderList();
+      public java.util.List<monitoring.Monitoring.SubscriptionID.Builder> 
+           getSubsListBuilderList() {
+        return getSubsListFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder> 
-          getKpiListFieldBuilder() {
-        if (kpiListBuilder_ == null) {
-          kpiListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.KpiList, monitoring.Monitoring.KpiList.Builder, monitoring.Monitoring.KpiListOrBuilder>(
-                  kpiList_,
+          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
+          getSubsListFieldBuilder() {
+        if (subsListBuilder_ == null) {
+          subsListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
+                  subsList_,
                   ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          kpiList_ = null;
+          subsList_ = null;
         }
-        return kpiListBuilder_;
+        return subsListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -15332,95 +13927,176 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.SubsResponse)
+      // @@protoc_insertion_point(builder_scope:monitoring.SubsIDList)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.SubsResponse)
-    private static final monitoring.Monitoring.SubsResponse DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.SubsIDList)
+    private static final monitoring.Monitoring.SubsIDList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsResponse();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsIDList();
     }
 
-    public static monitoring.Monitoring.SubsResponse getDefaultInstance() {
+    public static monitoring.Monitoring.SubsIDList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<SubsResponse>
-        PARSER = new com.google.protobuf.AbstractParser<SubsResponse>() {
+    private static final com.google.protobuf.Parser<SubsIDList>
+        PARSER = new com.google.protobuf.AbstractParser<SubsIDList>() {
       @java.lang.Override
-      public SubsResponse parsePartialFrom(
+      public SubsIDList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubsResponse(input, extensionRegistry);
+        return new SubsIDList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<SubsResponse> parser() {
+    public static com.google.protobuf.Parser<SubsIDList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<SubsResponse> getParserForType() {
+    public com.google.protobuf.Parser<SubsIDList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.SubsResponse getDefaultInstanceForType() {
+    public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface SubsIDListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.SubsIDList)
+  public interface AlarmDescriptorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.AlarmDescriptor)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
      */
-    java.util.List<monitoring.Monitoring.SubscriptionID> 
-        getSubsListList();
+    boolean hasAlarmId();
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return The alarmId.
      */
-    monitoring.Monitoring.SubscriptionID getSubsList(int index);
+    monitoring.Monitoring.AlarmID getAlarmId();
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
      */
-    int getSubsListCount();
+    monitoring.Monitoring.AlarmIDOrBuilder getAlarmIdOrBuilder();
+
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The alarmDescription.
      */
-    java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
-        getSubsListOrBuilderList();
+    java.lang.String getAlarmDescription();
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The bytes for alarmDescription.
      */
-    monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
+    com.google.protobuf.ByteString
+        getAlarmDescriptionBytes();
+
+    /**
+     * <code>string name = 3;</code>
+     * @return The name.
+     */
+    java.lang.String getName();
+    /**
+     * <code>string name = 3;</code>
+     * @return The bytes for name.
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiId> 
+        getKpiIdList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    monitoring.Monitoring.KpiId getKpiId(int index);
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    int getKpiIdCount();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    java.util.List<monitoring.Monitoring.KpiValueRange> 
+        getKpiValueRangeList();
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    monitoring.Monitoring.KpiValueRange getKpiValueRange(int index);
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    int getKpiValueRangeCount();
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiValueRangeOrBuilder> 
+        getKpiValueRangeOrBuilderList();
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder(
         int index);
+
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return Whether the timestamp field is set.
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return The timestamp.
+     */
+    context.ContextOuterClass.Timestamp getTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder();
   }
   /**
-   * Protobuf type {@code monitoring.SubsIDList}
+   * Protobuf type {@code monitoring.AlarmDescriptor}
    */
-  public static final class SubsIDList extends
+  public static final class AlarmDescriptor extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.SubsIDList)
-      SubsIDListOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.AlarmDescriptor)
+      AlarmDescriptorOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use SubsIDList.newBuilder() to construct.
-    private SubsIDList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use AlarmDescriptor.newBuilder() to construct.
+    private AlarmDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private SubsIDList() {
-      subsList_ = java.util.Collections.emptyList();
+    private AlarmDescriptor() {
+      alarmDescription_ = "";
+      name_ = "";
+      kpiId_ = java.util.Collections.emptyList();
+      kpiValueRange_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new SubsIDList();
+      return new AlarmDescriptor();
     }
 
     @java.lang.Override
@@ -15428,7 +14104,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private SubsIDList(
+    private AlarmDescriptor(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -15448,12 +14124,59 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
+              monitoring.Monitoring.AlarmID.Builder subBuilder = null;
+              if (alarmId_ != null) {
+                subBuilder = alarmId_.toBuilder();
+              }
+              alarmId_ = input.readMessage(monitoring.Monitoring.AlarmID.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(alarmId_);
+                alarmId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              alarmDescription_ = s;
+              break;
+            }
+            case 26: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              name_ = s;
+              break;
+            }
+            case 34: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>();
+                kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              subsList_.add(
-                  input.readMessage(monitoring.Monitoring.SubscriptionID.parser(), extensionRegistry));
+              kpiId_.add(
+                  input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry));
+              break;
+            }
+            case 42: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                kpiValueRange_ = new java.util.ArrayList<monitoring.Monitoring.KpiValueRange>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              kpiValueRange_.add(
+                  input.readMessage(monitoring.Monitoring.KpiValueRange.parser(), extensionRegistry));
+              break;
+            }
+            case 50: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (timestamp_ != null) {
+                subBuilder = timestamp_.toBuilder();
+              }
+              timestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(timestamp_);
+                timestamp_ = subBuilder.buildPartial();
+              }
+
               break;
             }
             default: {
@@ -15472,7 +14195,10 @@ public final class Monitoring {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          subsList_ = java.util.Collections.unmodifiableList(subsList_);
+          kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+        }
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
+          kpiValueRange_ = java.util.Collections.unmodifiableList(kpiValueRange_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -15480,55 +14206,223 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
+              monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
     }
 
-    public static final int SUBS_LIST_FIELD_NUMBER = 1;
-    private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_;
+    public static final int ALARM_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.AlarmID alarmId_;
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
      */
     @java.lang.Override
-    public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
-      return subsList_;
+    public boolean hasAlarmId() {
+      return alarmId_ != null;
     }
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
+     * @return The alarmId.
      */
     @java.lang.Override
-    public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
-        getSubsListOrBuilderList() {
-      return subsList_;
+    public monitoring.Monitoring.AlarmID getAlarmId() {
+      return alarmId_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmId_;
     }
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>.monitoring.AlarmID alarm_id = 1;</code>
      */
     @java.lang.Override
-    public int getSubsListCount() {
-      return subsList_.size();
+    public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIdOrBuilder() {
+      return getAlarmId();
     }
+
+    public static final int ALARM_DESCRIPTION_FIELD_NUMBER = 2;
+    private volatile java.lang.Object alarmDescription_;
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The alarmDescription.
      */
     @java.lang.Override
-    public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
-      return subsList_.get(index);
+    public java.lang.String getAlarmDescription() {
+      java.lang.Object ref = alarmDescription_;
+      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();
+        alarmDescription_ = s;
+        return s;
+      }
     }
     /**
-     * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
+     * <code>string alarm_description = 2;</code>
+     * @return The bytes for alarmDescription.
      */
     @java.lang.Override
-    public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
+    public com.google.protobuf.ByteString
+        getAlarmDescriptionBytes() {
+      java.lang.Object ref = alarmDescription_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        alarmDescription_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int NAME_FIELD_NUMBER = 3;
+    private volatile java.lang.Object name_;
+    /**
+     * <code>string name = 3;</code>
+     * @return The name.
+     */
+    @java.lang.Override
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      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();
+        name_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string name = 3;</code>
+     * @return The bytes for name.
+     */
+    @java.lang.Override
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int KPI_ID_FIELD_NUMBER = 4;
+    private java.util.List<monitoring.Monitoring.KpiId> kpiId_;
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+      return kpiId_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+        getKpiIdOrBuilderList() {
+      return kpiId_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public int getKpiIdCount() {
+      return kpiId_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiId(int index) {
+      return kpiId_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
         int index) {
-      return subsList_.get(index);
+      return kpiId_.get(index);
+    }
+
+    public static final int KPI_VALUE_RANGE_FIELD_NUMBER = 5;
+    private java.util.List<monitoring.Monitoring.KpiValueRange> kpiValueRange_;
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.KpiValueRange> getKpiValueRangeList() {
+      return kpiValueRange_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiValueRangeOrBuilder> 
+        getKpiValueRangeOrBuilderList() {
+      return kpiValueRange_;
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public int getKpiValueRangeCount() {
+      return kpiValueRange_.size();
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueRange getKpiValueRange(int index) {
+      return kpiValueRange_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder(
+        int index) {
+      return kpiValueRange_.get(index);
+    }
+
+    public static final int TIMESTAMP_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.Timestamp timestamp_;
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return Whether the timestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasTimestamp() {
+      return timestamp_ != null;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getTimestamp() {
+      return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 6;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+      return getTimestamp();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -15545,21 +14439,54 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      for (int i = 0; i < subsList_.size(); i++) {
-        output.writeMessage(1, subsList_.get(i));
+      if (alarmId_ != null) {
+        output.writeMessage(1, getAlarmId());
+      }
+      if (!getAlarmDescriptionBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, alarmDescription_);
+      }
+      if (!getNameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, name_);
+      }
+      for (int i = 0; i < kpiId_.size(); i++) {
+        output.writeMessage(4, kpiId_.get(i));
+      }
+      for (int i = 0; i < kpiValueRange_.size(); i++) {
+        output.writeMessage(5, kpiValueRange_.get(i));
+      }
+      if (timestamp_ != null) {
+        output.writeMessage(6, getTimestamp());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (alarmId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getAlarmId());
+      }
+      if (!getAlarmDescriptionBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, alarmDescription_);
+      }
+      if (!getNameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, name_);
+      }
+      for (int i = 0; i < kpiId_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, kpiId_.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 < subsList_.size(); i++) {
+      for (int i = 0; i < kpiValueRange_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, subsList_.get(i));
+          .computeMessageSize(5, kpiValueRange_.get(i));
+      }
+      if (timestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getTimestamp());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -15571,13 +14498,29 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.SubsIDList)) {
+      if (!(obj instanceof monitoring.Monitoring.AlarmDescriptor)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.SubsIDList other = (monitoring.Monitoring.SubsIDList) obj;
+      monitoring.Monitoring.AlarmDescriptor other = (monitoring.Monitoring.AlarmDescriptor) obj;
 
-      if (!getSubsListList()
-          .equals(other.getSubsListList())) return false;
+      if (hasAlarmId() != other.hasAlarmId()) return false;
+      if (hasAlarmId()) {
+        if (!getAlarmId()
+            .equals(other.getAlarmId())) return false;
+      }
+      if (!getAlarmDescription()
+          .equals(other.getAlarmDescription())) return false;
+      if (!getName()
+          .equals(other.getName())) return false;
+      if (!getKpiIdList()
+          .equals(other.getKpiIdList())) return false;
+      if (!getKpiValueRangeList()
+          .equals(other.getKpiValueRangeList())) return false;
+      if (hasTimestamp() != other.hasTimestamp()) return false;
+      if (hasTimestamp()) {
+        if (!getTimestamp()
+            .equals(other.getTimestamp())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -15589,78 +14532,94 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getSubsListCount() > 0) {
-        hash = (37 * hash) + SUBS_LIST_FIELD_NUMBER;
-        hash = (53 * hash) + getSubsListList().hashCode();
+      if (hasAlarmId()) {
+        hash = (37 * hash) + ALARM_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getAlarmId().hashCode();
+      }
+      hash = (37 * hash) + ALARM_DESCRIPTION_FIELD_NUMBER;
+      hash = (53 * hash) + getAlarmDescription().hashCode();
+      hash = (37 * hash) + NAME_FIELD_NUMBER;
+      hash = (53 * hash) + getName().hashCode();
+      if (getKpiIdCount() > 0) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiIdList().hashCode();
+      }
+      if (getKpiValueRangeCount() > 0) {
+        hash = (37 * hash) + KPI_VALUE_RANGE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiValueRangeList().hashCode();
+      }
+      if (hasTimestamp()) {
+        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getTimestamp().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor 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.SubsIDList parseFrom(byte[] data)
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor 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.SubsIDList parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmDescriptor parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsIDList parseDelimitedFrom(
+    public static monitoring.Monitoring.AlarmDescriptor 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.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.SubsIDList parseFrom(
+    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -15673,7 +14632,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.SubsIDList prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.AlarmDescriptor prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -15689,26 +14648,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.SubsIDList}
+     * Protobuf type {@code monitoring.AlarmDescriptor}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.SubsIDList)
-        monitoring.Monitoring.SubsIDListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.AlarmDescriptor)
+        monitoring.Monitoring.AlarmDescriptorOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.SubsIDList.class, monitoring.Monitoring.SubsIDList.Builder.class);
+                monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.SubsIDList.newBuilder()
+      // Construct using monitoring.Monitoring.AlarmDescriptor.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -15721,1670 +14680,1731 @@ public final class Monitoring {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getSubsListFieldBuilder();
+          getKpiIdFieldBuilder();
+          getKpiValueRangeFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (subsListBuilder_ == null) {
-          subsList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-        } else {
-          subsListBuilder_.clear();
-        }
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_SubsIDList_descriptor;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
-        return monitoring.Monitoring.SubsIDList.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.SubsIDList build() {
-        monitoring.Monitoring.SubsIDList result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public monitoring.Monitoring.SubsIDList buildPartial() {
-        monitoring.Monitoring.SubsIDList result = new monitoring.Monitoring.SubsIDList(this);
-        int from_bitField0_ = bitField0_;
-        if (subsListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            subsList_ = java.util.Collections.unmodifiableList(subsList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.subsList_ = subsList_;
-        } else {
-          result.subsList_ = subsListBuilder_.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.SubsIDList) {
-          return mergeFrom((monitoring.Monitoring.SubsIDList)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(monitoring.Monitoring.SubsIDList other) {
-        if (other == monitoring.Monitoring.SubsIDList.getDefaultInstance()) return this;
-        if (subsListBuilder_ == null) {
-          if (!other.subsList_.isEmpty()) {
-            if (subsList_.isEmpty()) {
-              subsList_ = other.subsList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureSubsListIsMutable();
-              subsList_.addAll(other.subsList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.subsList_.isEmpty()) {
-            if (subsListBuilder_.isEmpty()) {
-              subsListBuilder_.dispose();
-              subsListBuilder_ = null;
-              subsList_ = other.subsList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              subsListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getSubsListFieldBuilder() : null;
-            } else {
-              subsListBuilder_.addAllMessages(other.subsList_);
-            }
-          }
-        }
-        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.SubsIDList parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.SubsIDList) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      private java.util.List<monitoring.Monitoring.SubscriptionID> subsList_ =
-        java.util.Collections.emptyList();
-      private void ensureSubsListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          subsList_ = new java.util.ArrayList<monitoring.Monitoring.SubscriptionID>(subsList_);
-          bitField0_ |= 0x00000001;
-         }
-      }
-
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> subsListBuilder_;
-
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.SubscriptionID> getSubsListList() {
-        if (subsListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(subsList_);
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
         } else {
-          return subsListBuilder_.getMessageList();
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public int getSubsListCount() {
-        if (subsListBuilder_ == null) {
-          return subsList_.size();
+        alarmDescription_ = "";
+
+        name_ = "";
+
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          return subsListBuilder_.getCount();
+          kpiIdBuilder_.clear();
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID getSubsList(int index) {
-        if (subsListBuilder_ == null) {
-          return subsList_.get(index);
+        if (kpiValueRangeBuilder_ == null) {
+          kpiValueRange_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
         } else {
-          return subsListBuilder_.getMessage(index);
+          kpiValueRangeBuilder_.clear();
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder setSubsList(
-          int index, monitoring.Monitoring.SubscriptionID value) {
-        if (subsListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureSubsListIsMutable();
-          subsList_.set(index, value);
-          onChanged();
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
         } else {
-          subsListBuilder_.setMessage(index, value);
+          timestamp_ = null;
+          timestampBuilder_ = null;
         }
         return this;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder setSubsList(
-          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          subsListBuilder_.setMessage(index, builderForValue.build());
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
+        return monitoring.Monitoring.AlarmDescriptor.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmDescriptor build() {
+        monitoring.Monitoring.AlarmDescriptor result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
-        return this;
+        return result;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(monitoring.Monitoring.SubscriptionID value) {
-        if (subsListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureSubsListIsMutable();
-          subsList_.add(value);
-          onChanged();
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmDescriptor buildPartial() {
+        monitoring.Monitoring.AlarmDescriptor result = new monitoring.Monitoring.AlarmDescriptor(this);
+        int from_bitField0_ = bitField0_;
+        if (alarmIdBuilder_ == null) {
+          result.alarmId_ = alarmId_;
         } else {
-          subsListBuilder_.addMessage(value);
+          result.alarmId_ = alarmIdBuilder_.build();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(
-          int index, monitoring.Monitoring.SubscriptionID value) {
-        if (subsListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
+        result.alarmDescription_ = alarmDescription_;
+        result.name_ = name_;
+        if (kpiIdBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiId_ = java.util.Collections.unmodifiableList(kpiId_);
+            bitField0_ = (bitField0_ & ~0x00000001);
           }
-          ensureSubsListIsMutable();
-          subsList_.add(index, value);
-          onChanged();
+          result.kpiId_ = kpiId_;
         } else {
-          subsListBuilder_.addMessage(index, value);
+          result.kpiId_ = kpiIdBuilder_.build();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(
-          monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.add(builderForValue.build());
-          onChanged();
+        if (kpiValueRangeBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) != 0)) {
+            kpiValueRange_ = java.util.Collections.unmodifiableList(kpiValueRange_);
+            bitField0_ = (bitField0_ & ~0x00000002);
+          }
+          result.kpiValueRange_ = kpiValueRange_;
         } else {
-          subsListBuilder_.addMessage(builderForValue.build());
+          result.kpiValueRange_ = kpiValueRangeBuilder_.build();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addSubsList(
-          int index, monitoring.Monitoring.SubscriptionID.Builder builderForValue) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.add(index, builderForValue.build());
-          onChanged();
+        if (timestampBuilder_ == null) {
+          result.timestamp_ = timestamp_;
         } else {
-          subsListBuilder_.addMessage(index, builderForValue.build());
+          result.timestamp_ = timestampBuilder_.build();
         }
-        return this;
+        onBuilt();
+        return result;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder addAllSubsList(
-          java.lang.Iterable<? extends monitoring.Monitoring.SubscriptionID> values) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, subsList_);
-          onChanged();
+
+      @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.AlarmDescriptor) {
+          return mergeFrom((monitoring.Monitoring.AlarmDescriptor)other);
         } else {
-          subsListBuilder_.addAllMessages(values);
+          super.mergeFrom(other);
+          return this;
         }
-        return this;
       }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder clearSubsList() {
-        if (subsListBuilder_ == null) {
-          subsList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
+
+      public Builder mergeFrom(monitoring.Monitoring.AlarmDescriptor other) {
+        if (other == monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()) return this;
+        if (other.hasAlarmId()) {
+          mergeAlarmId(other.getAlarmId());
+        }
+        if (!other.getAlarmDescription().isEmpty()) {
+          alarmDescription_ = other.alarmDescription_;
           onChanged();
-        } else {
-          subsListBuilder_.clear();
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public Builder removeSubsList(int index) {
-        if (subsListBuilder_ == null) {
-          ensureSubsListIsMutable();
-          subsList_.remove(index);
+        if (!other.getName().isEmpty()) {
+          name_ = other.name_;
           onChanged();
-        } else {
-          subsListBuilder_.remove(index);
         }
-        return this;
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder getSubsListBuilder(
-          int index) {
-        return getSubsListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionIDOrBuilder getSubsListOrBuilder(
-          int index) {
-        if (subsListBuilder_ == null) {
-          return subsList_.get(index);  } else {
-          return subsListBuilder_.getMessageOrBuilder(index);
+        if (kpiIdBuilder_ == null) {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiId_.isEmpty()) {
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiIdIsMutable();
+              kpiId_.addAll(other.kpiId_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.kpiId_.isEmpty()) {
+            if (kpiIdBuilder_.isEmpty()) {
+              kpiIdBuilder_.dispose();
+              kpiIdBuilder_ = null;
+              kpiId_ = other.kpiId_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiIdBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiIdFieldBuilder() : null;
+            } else {
+              kpiIdBuilder_.addAllMessages(other.kpiId_);
+            }
+          }
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public java.util.List<? extends monitoring.Monitoring.SubscriptionIDOrBuilder> 
-           getSubsListOrBuilderList() {
-        if (subsListBuilder_ != null) {
-          return subsListBuilder_.getMessageOrBuilderList();
+        if (kpiValueRangeBuilder_ == null) {
+          if (!other.kpiValueRange_.isEmpty()) {
+            if (kpiValueRange_.isEmpty()) {
+              kpiValueRange_ = other.kpiValueRange_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+            } else {
+              ensureKpiValueRangeIsMutable();
+              kpiValueRange_.addAll(other.kpiValueRange_);
+            }
+            onChanged();
+          }
         } else {
-          return java.util.Collections.unmodifiableList(subsList_);
+          if (!other.kpiValueRange_.isEmpty()) {
+            if (kpiValueRangeBuilder_.isEmpty()) {
+              kpiValueRangeBuilder_.dispose();
+              kpiValueRangeBuilder_ = null;
+              kpiValueRange_ = other.kpiValueRange_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+              kpiValueRangeBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiValueRangeFieldBuilder() : null;
+            } else {
+              kpiValueRangeBuilder_.addAllMessages(other.kpiValueRange_);
+            }
+          }
         }
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder() {
-        return getSubsListFieldBuilder().addBuilder(
-            monitoring.Monitoring.SubscriptionID.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public monitoring.Monitoring.SubscriptionID.Builder addSubsListBuilder(
-          int index) {
-        return getSubsListFieldBuilder().addBuilder(
-            index, monitoring.Monitoring.SubscriptionID.getDefaultInstance());
-      }
-      /**
-       * <code>repeated .monitoring.SubscriptionID subs_list = 1;</code>
-       */
-      public java.util.List<monitoring.Monitoring.SubscriptionID.Builder> 
-           getSubsListBuilderList() {
-        return getSubsListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder> 
-          getSubsListFieldBuilder() {
-        if (subsListBuilder_ == null) {
-          subsListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              monitoring.Monitoring.SubscriptionID, monitoring.Monitoring.SubscriptionID.Builder, monitoring.Monitoring.SubscriptionIDOrBuilder>(
-                  subsList_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          subsList_ = null;
+        if (other.hasTimestamp()) {
+          mergeTimestamp(other.getTimestamp());
         }
-        return subsListBuilder_;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
       }
 
       @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      public final boolean isInitialized() {
+        return true;
       }
 
-
-      // @@protoc_insertion_point(builder_scope:monitoring.SubsIDList)
-    }
-
-    // @@protoc_insertion_point(class_scope:monitoring.SubsIDList)
-    private static final monitoring.Monitoring.SubsIDList DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.SubsIDList();
-    }
-
-    public static monitoring.Monitoring.SubsIDList getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<SubsIDList>
-        PARSER = new com.google.protobuf.AbstractParser<SubsIDList>() {
       @java.lang.Override
-      public SubsIDList parsePartialFrom(
+      public Builder mergeFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new SubsIDList(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<SubsIDList> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<SubsIDList> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public monitoring.Monitoring.SubsIDList getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface AlarmDescriptorOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.AlarmDescriptor)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The alarmDescription.
-     */
-    java.lang.String getAlarmDescription();
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The bytes for alarmDescription.
-     */
-    com.google.protobuf.ByteString
-        getAlarmDescriptionBytes();
-
-    /**
-     * <code>string name = 2;</code>
-     * @return The name.
-     */
-    java.lang.String getName();
-    /**
-     * <code>string name = 2;</code>
-     * @return The bytes for name.
-     */
-    com.google.protobuf.ByteString
-        getNameBytes();
-
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     * @return Whether the kpiId field is set.
-     */
-    boolean hasKpiId();
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     * @return The kpiId.
-     */
-    monitoring.Monitoring.KpiId getKpiId();
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     */
-    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
-
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return Whether the kpiValueRange field is set.
-     */
-    boolean hasKpiValueRange();
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return The kpiValueRange.
-     */
-    monitoring.Monitoring.KpiValueRange getKpiValueRange();
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     */
-    monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder();
-
-    /**
-     * <code>string timestamp = 5;</code>
-     * @return The timestamp.
-     */
-    java.lang.String getTimestamp();
-    /**
-     * <code>string timestamp = 5;</code>
-     * @return The bytes for timestamp.
-     */
-    com.google.protobuf.ByteString
-        getTimestampBytes();
-  }
-  /**
-   * Protobuf type {@code monitoring.AlarmDescriptor}
-   */
-  public static final class AlarmDescriptor extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.AlarmDescriptor)
-      AlarmDescriptorOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use AlarmDescriptor.newBuilder() to construct.
-    private AlarmDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private AlarmDescriptor() {
-      alarmDescription_ = "";
-      name_ = "";
-      timestamp_ = "";
-    }
-
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new AlarmDescriptor();
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private AlarmDescriptor(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
+          throws java.io.IOException {
+        monitoring.Monitoring.AlarmDescriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.AlarmDescriptor) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
       }
-      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();
-
-              alarmDescription_ = s;
-              break;
-            }
-            case 18: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              name_ = s;
-              break;
-            }
-            case 26: {
-              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();
-              }
+      private int bitField0_;
 
-              break;
-            }
-            case 34: {
-              monitoring.Monitoring.KpiValueRange.Builder subBuilder = null;
-              if (kpiValueRange_ != null) {
-                subBuilder = kpiValueRange_.toBuilder();
-              }
-              kpiValueRange_ = input.readMessage(monitoring.Monitoring.KpiValueRange.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(kpiValueRange_);
-                kpiValueRange_ = subBuilder.buildPartial();
-              }
+      private monitoring.Monitoring.AlarmID alarmId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> alarmIdBuilder_;
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       * @return Whether the alarmId field is set.
+       */
+      public boolean hasAlarmId() {
+        return alarmIdBuilder_ != null || alarmId_ != null;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       * @return The alarmId.
+       */
+      public monitoring.Monitoring.AlarmID getAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          return alarmId_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmId_;
+        } else {
+          return alarmIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder setAlarmId(monitoring.Monitoring.AlarmID value) {
+        if (alarmIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          alarmId_ = value;
+          onChanged();
+        } else {
+          alarmIdBuilder_.setMessage(value);
+        }
 
-              break;
-            }
-            case 42: {
-              java.lang.String s = input.readStringRequireUtf8();
+        return this;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder setAlarmId(
+          monitoring.Monitoring.AlarmID.Builder builderForValue) {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = builderForValue.build();
+          onChanged();
+        } else {
+          alarmIdBuilder_.setMessage(builderForValue.build());
+        }
 
-              timestamp_ = s;
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
+        return this;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder mergeAlarmId(monitoring.Monitoring.AlarmID value) {
+        if (alarmIdBuilder_ == null) {
+          if (alarmId_ != null) {
+            alarmId_ =
+              monitoring.Monitoring.AlarmID.newBuilder(alarmId_).mergeFrom(value).buildPartial();
+          } else {
+            alarmId_ = value;
           }
+          onChanged();
+        } else {
+          alarmIdBuilder_.mergeFrom(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 {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
+
+        return this;
       }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
-    }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public Builder clearAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
+          onChanged();
+        } else {
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
+        }
 
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
-    }
+        return this;
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public monitoring.Monitoring.AlarmID.Builder getAlarmIdBuilder() {
+        
+        onChanged();
+        return getAlarmIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIdOrBuilder() {
+        if (alarmIdBuilder_ != null) {
+          return alarmIdBuilder_.getMessageOrBuilder();
+        } else {
+          return alarmId_ == null ?
+              monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmId_;
+        }
+      }
+      /**
+       * <code>.monitoring.AlarmID alarm_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> 
+          getAlarmIdFieldBuilder() {
+        if (alarmIdBuilder_ == null) {
+          alarmIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder>(
+                  getAlarmId(),
+                  getParentForChildren(),
+                  isClean());
+          alarmId_ = null;
+        }
+        return alarmIdBuilder_;
+      }
 
-    public static final int ALARM_DESCRIPTION_FIELD_NUMBER = 1;
-    private volatile java.lang.Object alarmDescription_;
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The alarmDescription.
-     */
-    @java.lang.Override
-    public java.lang.String getAlarmDescription() {
-      java.lang.Object ref = alarmDescription_;
-      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();
-        alarmDescription_ = s;
-        return s;
+      private java.lang.Object alarmDescription_ = "";
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @return The alarmDescription.
+       */
+      public java.lang.String getAlarmDescription() {
+        java.lang.Object ref = alarmDescription_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          alarmDescription_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
       }
-    }
-    /**
-     * <code>string alarm_description = 1;</code>
-     * @return The bytes for alarmDescription.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getAlarmDescriptionBytes() {
-      java.lang.Object ref = alarmDescription_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        alarmDescription_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @return The bytes for alarmDescription.
+       */
+      public com.google.protobuf.ByteString
+          getAlarmDescriptionBytes() {
+        java.lang.Object ref = alarmDescription_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          alarmDescription_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @param value The alarmDescription to set.
+       * @return This builder for chaining.
+       */
+      public Builder setAlarmDescription(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        alarmDescription_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearAlarmDescription() {
+        
+        alarmDescription_ = getDefaultInstance().getAlarmDescription();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string alarm_description = 2;</code>
+       * @param value The bytes for alarmDescription to set.
+       * @return This builder for chaining.
+       */
+      public Builder setAlarmDescriptionBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        alarmDescription_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object name_ = "";
+      /**
+       * <code>string name = 3;</code>
+       * @return The name.
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
       }
-    }
-
-    public static final int NAME_FIELD_NUMBER = 2;
-    private volatile java.lang.Object name_;
-    /**
-     * <code>string name = 2;</code>
-     * @return The name.
-     */
-    @java.lang.Override
-    public java.lang.String getName() {
-      java.lang.Object ref = name_;
-      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();
-        name_ = s;
-        return s;
+      /**
+       * <code>string name = 3;</code>
+       * @return The bytes for name.
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
       }
-    }
-    /**
-     * <code>string name = 2;</code>
-     * @return The bytes for name.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getNameBytes() {
-      java.lang.Object ref = name_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        name_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
+      /**
+       * <code>string name = 3;</code>
+       * @param value The name to set.
+       * @return This builder for chaining.
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        name_ = value;
+        onChanged();
+        return this;
       }
-    }
-
-    public static final int KPI_ID_FIELD_NUMBER = 3;
-    private monitoring.Monitoring.KpiId kpiId_;
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</code>
-     * @return Whether the kpiId field is set.
-     */
-    @java.lang.Override
-    public boolean hasKpiId() {
-      return kpiId_ != null;
-    }
-    /**
-     * <code>.monitoring.KpiId kpi_id = 3;</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 = 3;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-      return getKpiId();
-    }
-
-    public static final int KPI_VALUE_RANGE_FIELD_NUMBER = 4;
-    private monitoring.Monitoring.KpiValueRange kpiValueRange_;
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return Whether the kpiValueRange field is set.
-     */
-    @java.lang.Override
-    public boolean hasKpiValueRange() {
-      return kpiValueRange_ != null;
-    }
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     * @return The kpiValueRange.
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiValueRange getKpiValueRange() {
-      return kpiValueRange_ == null ? monitoring.Monitoring.KpiValueRange.getDefaultInstance() : kpiValueRange_;
-    }
-    /**
-     * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-     */
-    @java.lang.Override
-    public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder() {
-      return getKpiValueRange();
-    }
-
-    public static final int TIMESTAMP_FIELD_NUMBER = 5;
-    private volatile java.lang.Object timestamp_;
-    /**
-     * <code>string timestamp = 5;</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 name = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearName() {
+        
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
       }
-    }
-    /**
-     * <code>string timestamp = 5;</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;
+      /**
+       * <code>string name = 3;</code>
+       * @param value The bytes for name to set.
+       * @return This builder for chaining.
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        name_ = value;
+        onChanged();
+        return this;
       }
-    }
 
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
+      private java.util.List<monitoring.Monitoring.KpiId> kpiId_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiIdIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiId_ = new java.util.ArrayList<monitoring.Monitoring.KpiId>(kpiId_);
+          bitField0_ |= 0x00000001;
+         }
+      }
 
-      memoizedIsInitialized = 1;
-      return true;
-    }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
 
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (!getAlarmDescriptionBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, alarmDescription_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId> getKpiIdList() {
+        if (kpiIdBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        } else {
+          return kpiIdBuilder_.getMessageList();
+        }
       }
-      if (!getNameBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public int getKpiIdCount() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.size();
+        } else {
+          return kpiIdBuilder_.getCount();
+        }
       }
-      if (kpiId_ != null) {
-        output.writeMessage(3, getKpiId());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId getKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);
+        } else {
+          return kpiIdBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, value);
+        }
+        return this;
       }
-      if (kpiValueRange_ != null) {
-        output.writeMessage(4, getKpiValueRange());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder setKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (!getTimestampBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, timestamp_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(value);
+        }
+        return this;
       }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getAlarmDescriptionBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, alarmDescription_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, value);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, value);
+        }
+        return this;
       }
-      if (!getNameBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
       }
-      if (kpiId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, getKpiId());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addKpiId(
+          int index, monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiIdBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
       }
-      if (kpiValueRange_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getKpiValueRange());
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder addAllKpiId(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiId> values) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiId_);
+          onChanged();
+        } else {
+          kpiIdBuilder_.addAllMessages(values);
+        }
+        return this;
       }
-      if (!getTimestampBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, timestamp_);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiIdBuilder_.clear();
+        }
+        return this;
       }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public Builder removeKpiId(int index) {
+        if (kpiIdBuilder_ == null) {
+          ensureKpiIdIsMutable();
+          kpiId_.remove(index);
+          onChanged();
+        } else {
+          kpiIdBuilder_.remove(index);
+        }
+        return this;
       }
-      if (!(obj instanceof monitoring.Monitoring.AlarmDescriptor)) {
-        return super.equals(obj);
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().getBuilder(index);
       }
-      monitoring.Monitoring.AlarmDescriptor other = (monitoring.Monitoring.AlarmDescriptor) obj;
-
-      if (!getAlarmDescription()
-          .equals(other.getAlarmDescription())) return false;
-      if (!getName()
-          .equals(other.getName())) return false;
-      if (hasKpiId() != other.hasKpiId()) return false;
-      if (hasKpiId()) {
-        if (!getKpiId()
-            .equals(other.getKpiId())) return false;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder(
+          int index) {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_.get(index);  } else {
+          return kpiIdBuilder_.getMessageOrBuilder(index);
+        }
       }
-      if (hasKpiValueRange() != other.hasKpiValueRange()) return false;
-      if (hasKpiValueRange()) {
-        if (!getKpiValueRange()
-            .equals(other.getKpiValueRange())) return false;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiIdOrBuilder> 
+           getKpiIdOrBuilderList() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiId_);
+        }
       }
-      if (!getTimestamp()
-          .equals(other.getTimestamp())) return false;
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder() {
+        return getKpiIdFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiId.getDefaultInstance());
       }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + ALARM_DESCRIPTION_FIELD_NUMBER;
-      hash = (53 * hash) + getAlarmDescription().hashCode();
-      hash = (37 * hash) + NAME_FIELD_NUMBER;
-      hash = (53 * hash) + getName().hashCode();
-      if (hasKpiId()) {
-        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiId().hashCode();
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder addKpiIdBuilder(
+          int index) {
+        return getKpiIdFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiId.getDefaultInstance());
       }
-      if (hasKpiValueRange()) {
-        hash = (37 * hash) + KPI_VALUE_RANGE_FIELD_NUMBER;
-        hash = (53 * hash) + getKpiValueRange().hashCode();
+      /**
+       * <code>repeated .monitoring.KpiId kpi_id = 4;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiId.Builder> 
+           getKpiIdBuilderList() {
+        return getKpiIdFieldBuilder().getBuilderList();
       }
-      hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
-      hash = (53 * hash) + getTimestamp().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static monitoring.Monitoring.AlarmDescriptor 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.AlarmDescriptor 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.AlarmDescriptor}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.AlarmDescriptor)
-        monitoring.Monitoring.AlarmDescriptorOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  kpiId_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
       }
 
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.AlarmDescriptor.class, monitoring.Monitoring.AlarmDescriptor.Builder.class);
+      private java.util.List<monitoring.Monitoring.KpiValueRange> kpiValueRange_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiValueRangeIsMutable() {
+        if (!((bitField0_ & 0x00000002) != 0)) {
+          kpiValueRange_ = new java.util.ArrayList<monitoring.Monitoring.KpiValueRange>(kpiValueRange_);
+          bitField0_ |= 0x00000002;
+         }
       }
 
-      // Construct using monitoring.Monitoring.AlarmDescriptor.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> kpiValueRangeBuilder_;
 
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiValueRange> getKpiValueRangeList() {
+        if (kpiValueRangeBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiValueRange_);
+        } else {
+          return kpiValueRangeBuilder_.getMessageList();
+        }
       }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public int getKpiValueRangeCount() {
+        if (kpiValueRangeBuilder_ == null) {
+          return kpiValueRange_.size();
+        } else {
+          return kpiValueRangeBuilder_.getCount();
         }
       }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        alarmDescription_ = "";
-
-        name_ = "";
-
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange getKpiValueRange(int index) {
+        if (kpiValueRangeBuilder_ == null) {
+          return kpiValueRange_.get(index);
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          return kpiValueRangeBuilder_.getMessage(index);
         }
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder setKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange value) {
         if (kpiValueRangeBuilder_ == null) {
-          kpiValueRange_ = null;
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.set(index, value);
+          onChanged();
         } else {
-          kpiValueRange_ = null;
-          kpiValueRangeBuilder_ = null;
+          kpiValueRangeBuilder_.setMessage(index, value);
         }
-        timestamp_ = "";
-
         return this;
       }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmDescriptor_descriptor;
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder setKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
       }
-
-      @java.lang.Override
-      public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
-        return monitoring.Monitoring.AlarmDescriptor.getDefaultInstance();
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(monitoring.Monitoring.KpiValueRange value) {
+        if (kpiValueRangeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(value);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.addMessage(value);
+        }
+        return this;
       }
-
-      @java.lang.Override
-      public monitoring.Monitoring.AlarmDescriptor build() {
-        monitoring.Monitoring.AlarmDescriptor result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange value) {
+        if (kpiValueRangeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(index, value);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.addMessage(index, value);
         }
-        return result;
+        return this;
       }
-
-      @java.lang.Override
-      public monitoring.Monitoring.AlarmDescriptor buildPartial() {
-        monitoring.Monitoring.AlarmDescriptor result = new monitoring.Monitoring.AlarmDescriptor(this);
-        result.alarmDescription_ = alarmDescription_;
-        result.name_ = name_;
-        if (kpiIdBuilder_ == null) {
-          result.kpiId_ = kpiId_;
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(
+          monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(builderForValue.build());
+          onChanged();
         } else {
-          result.kpiId_ = kpiIdBuilder_.build();
+          kpiValueRangeBuilder_.addMessage(builderForValue.build());
         }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addKpiValueRange(
+          int index, monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
         if (kpiValueRangeBuilder_ == null) {
-          result.kpiValueRange_ = kpiValueRange_;
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.add(index, builderForValue.build());
+          onChanged();
         } else {
-          result.kpiValueRange_ = kpiValueRangeBuilder_.build();
+          kpiValueRangeBuilder_.addMessage(index, builderForValue.build());
         }
-        result.timestamp_ = timestamp_;
-        onBuilt();
-        return result;
+        return this;
       }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder addAllKpiValueRange(
+          java.lang.Iterable<? extends monitoring.Monitoring.KpiValueRange> values) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiValueRange_);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.addAllMessages(values);
+        }
+        return this;
       }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder clearKpiValueRange() {
+        if (kpiValueRangeBuilder_ == null) {
+          kpiValueRange_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.clear();
+        }
+        return this;
       }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public Builder removeKpiValueRange(int index) {
+        if (kpiValueRangeBuilder_ == null) {
+          ensureKpiValueRangeIsMutable();
+          kpiValueRange_.remove(index);
+          onChanged();
+        } else {
+          kpiValueRangeBuilder_.remove(index);
+        }
+        return this;
       }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange.Builder getKpiValueRangeBuilder(
+          int index) {
+        return getKpiValueRangeFieldBuilder().getBuilder(index);
       }
-      @java.lang.Override
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return super.setRepeatedField(field, index, value);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder(
+          int index) {
+        if (kpiValueRangeBuilder_ == null) {
+          return kpiValueRange_.get(index);  } else {
+          return kpiValueRangeBuilder_.getMessageOrBuilder(index);
+        }
       }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiValueRangeOrBuilder> 
+           getKpiValueRangeOrBuilderList() {
+        if (kpiValueRangeBuilder_ != null) {
+          return kpiValueRangeBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiValueRange_);
+        }
       }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.AlarmDescriptor) {
-          return mergeFrom((monitoring.Monitoring.AlarmDescriptor)other);
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange.Builder addKpiValueRangeBuilder() {
+        return getKpiValueRangeFieldBuilder().addBuilder(
+            monitoring.Monitoring.KpiValueRange.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public monitoring.Monitoring.KpiValueRange.Builder addKpiValueRangeBuilder(
+          int index) {
+        return getKpiValueRangeFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.KpiValueRange.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.KpiValueRange kpi_value_range = 5;</code>
+       */
+      public java.util.List<monitoring.Monitoring.KpiValueRange.Builder> 
+           getKpiValueRangeBuilderList() {
+        return getKpiValueRangeFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> 
+          getKpiValueRangeFieldBuilder() {
+        if (kpiValueRangeBuilder_ == null) {
+          kpiValueRangeBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder>(
+                  kpiValueRange_,
+                  ((bitField0_ & 0x00000002) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiValueRange_ = null;
+        }
+        return kpiValueRangeBuilder_;
+      }
+
+      private context.ContextOuterClass.Timestamp timestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> timestampBuilder_;
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       * @return Whether the timestamp field is set.
+       */
+      public boolean hasTimestamp() {
+        return timestampBuilder_ != null || timestamp_ != null;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       * @return The timestamp.
+       */
+      public context.ContextOuterClass.Timestamp getTimestamp() {
+        if (timestampBuilder_ == null) {
+          return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        } else {
+          return timestampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder setTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          timestamp_ = value;
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder setTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (timestampBuilder_ == null) {
+          timestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder mergeTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (timestamp_ != null) {
+            timestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(timestamp_).mergeFrom(value).buildPartial();
+          } else {
+            timestamp_ = value;
+          }
+          onChanged();
         } else {
-          super.mergeFrom(other);
-          return this;
+          timestampBuilder_.mergeFrom(value);
         }
-      }
 
-      public Builder mergeFrom(monitoring.Monitoring.AlarmDescriptor other) {
-        if (other == monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()) return this;
-        if (!other.getAlarmDescription().isEmpty()) {
-          alarmDescription_ = other.alarmDescription_;
-          onChanged();
-        }
-        if (!other.getName().isEmpty()) {
-          name_ = other.name_;
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public Builder clearTimestamp() {
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
           onChanged();
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
         }
-        if (other.hasKpiId()) {
-          mergeKpiId(other.getKpiId());
-        }
-        if (other.hasKpiValueRange()) {
-          mergeKpiValueRange(other.getKpiValueRange());
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getTimestampBuilder() {
+        
+        onChanged();
+        return getTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+        if (timestampBuilder_ != null) {
+          return timestampBuilder_.getMessageOrBuilder();
+        } else {
+          return timestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
         }
-        if (!other.getTimestamp().isEmpty()) {
-          timestamp_ = other.timestamp_;
-          onChanged();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getTimestampFieldBuilder() {
+        if (timestampBuilder_ == null) {
+          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          timestamp_ = null;
         }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
+        return timestampBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
       }
 
       @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
 
+
+      // @@protoc_insertion_point(builder_scope:monitoring.AlarmDescriptor)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.AlarmDescriptor)
+    private static final monitoring.Monitoring.AlarmDescriptor DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmDescriptor();
+    }
+
+    public static monitoring.Monitoring.AlarmDescriptor getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<AlarmDescriptor>
+        PARSER = new com.google.protobuf.AbstractParser<AlarmDescriptor>() {
       @java.lang.Override
-      public Builder mergeFrom(
+      public AlarmDescriptor parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        monitoring.Monitoring.AlarmDescriptor parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.AlarmDescriptor) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AlarmDescriptor(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<AlarmDescriptor> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AlarmDescriptor> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface AlarmIDOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.AlarmID)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
+     */
+    boolean hasAlarmId();
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return The alarmId.
+     */
+    context.ContextOuterClass.Uuid getAlarmId();
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder();
+  }
+  /**
+   * Protobuf type {@code monitoring.AlarmID}
+   */
+  public static final class AlarmID extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.AlarmID)
+      AlarmIDOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use AlarmID.newBuilder() to construct.
+    private AlarmID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private AlarmID() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new AlarmID();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AlarmID(
+        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 (alarmId_ != null) {
+                subBuilder = alarmId_.toBuilder();
+              }
+              alarmId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(alarmId_);
+                alarmId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
           }
         }
-        return this;
+      } 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_AlarmID_descriptor;
+    }
 
-      private java.lang.Object alarmDescription_ = "";
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @return The alarmDescription.
-       */
-      public java.lang.String getAlarmDescription() {
-        java.lang.Object ref = alarmDescription_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          alarmDescription_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
+    }
+
+    public static final int ALARM_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid alarmId_;
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return Whether the alarmId field is set.
+     */
+    @java.lang.Override
+    public boolean hasAlarmId() {
+      return alarmId_ != null;
+    }
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     * @return The alarmId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getAlarmId() {
+      return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+    }
+    /**
+     * <code>.context.Uuid alarm_id = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
+      return getAlarmId();
+    }
+
+    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 (alarmId_ != null) {
+        output.writeMessage(1, getAlarmId());
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @return The bytes for alarmDescription.
-       */
-      public com.google.protobuf.ByteString
-          getAlarmDescriptionBytes() {
-        java.lang.Object ref = alarmDescription_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          alarmDescription_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (alarmId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getAlarmId());
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @param value The alarmDescription to set.
-       * @return This builder for chaining.
-       */
-      public Builder setAlarmDescription(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        alarmDescription_ = value;
-        onChanged();
-        return this;
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearAlarmDescription() {
-        
-        alarmDescription_ = getDefaultInstance().getAlarmDescription();
-        onChanged();
-        return this;
+      if (!(obj instanceof monitoring.Monitoring.AlarmID)) {
+        return super.equals(obj);
       }
-      /**
-       * <code>string alarm_description = 1;</code>
-       * @param value The bytes for alarmDescription to set.
-       * @return This builder for chaining.
-       */
-      public Builder setAlarmDescriptionBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        alarmDescription_ = value;
-        onChanged();
-        return this;
+      monitoring.Monitoring.AlarmID other = (monitoring.Monitoring.AlarmID) obj;
+
+      if (hasAlarmId() != other.hasAlarmId()) return false;
+      if (hasAlarmId()) {
+        if (!getAlarmId()
+            .equals(other.getAlarmId())) return false;
       }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
 
-      private java.lang.Object name_ = "";
-      /**
-       * <code>string name = 2;</code>
-       * @return The name.
-       */
-      public java.lang.String getName() {
-        java.lang.Object ref = name_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          name_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
       }
-      /**
-       * <code>string name = 2;</code>
-       * @return The bytes for name.
-       */
-      public com.google.protobuf.ByteString
-          getNameBytes() {
-        java.lang.Object ref = name_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          name_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasAlarmId()) {
+        hash = (37 * hash) + ALARM_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getAlarmId().hashCode();
       }
-      /**
-       * <code>string name = 2;</code>
-       * @param value The name to set.
-       * @return This builder for chaining.
-       */
-      public Builder setName(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        name_ = value;
-        onChanged();
-        return this;
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.AlarmID parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.AlarmID 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.AlarmID 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.AlarmID}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.AlarmID)
+        monitoring.Monitoring.AlarmIDOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
       }
-      /**
-       * <code>string name = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearName() {
-        
-        name_ = getDefaultInstance().getName();
-        onChanged();
-        return this;
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
       }
-      /**
-       * <code>string name = 2;</code>
-       * @param value The bytes for name to set.
-       * @return This builder for chaining.
-       */
-      public Builder setNameBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        name_ = value;
-        onChanged();
-        return this;
+
+      // Construct using monitoring.Monitoring.AlarmID.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
       }
 
-      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 = 3;</code>
-       * @return Whether the kpiId field is set.
-       */
-      public boolean hasKpiId() {
-        return kpiIdBuilder_ != null || kpiId_ != null;
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       * @return The kpiId.
-       */
-      public monitoring.Monitoring.KpiId getKpiId() {
-        if (kpiIdBuilder_ == null) {
-          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
-        } else {
-          return kpiIdBuilder_.getMessage();
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
-        if (kpiIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          kpiId_ = value;
-          onChanged();
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
         } else {
-          kpiIdBuilder_.setMessage(value);
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
         }
-
         return this;
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public Builder setKpiId(
-          monitoring.Monitoring.KpiId.Builder builderForValue) {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = builderForValue.build();
-          onChanged();
-        } else {
-          kpiIdBuilder_.setMessage(builderForValue.build());
-        }
 
-        return this;
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</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;
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
+        return monitoring.Monitoring.AlarmID.getDefaultInstance();
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public Builder clearKpiId() {
-        if (kpiIdBuilder_ == null) {
-          kpiId_ = null;
-          onChanged();
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmID build() {
+        monitoring.Monitoring.AlarmID result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.AlarmID buildPartial() {
+        monitoring.Monitoring.AlarmID result = new monitoring.Monitoring.AlarmID(this);
+        if (alarmIdBuilder_ == null) {
+          result.alarmId_ = alarmId_;
         } else {
-          kpiId_ = null;
-          kpiIdBuilder_ = null;
+          result.alarmId_ = alarmIdBuilder_.build();
         }
+        onBuilt();
+        return result;
+      }
 
-        return this;
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
-        
-        onChanged();
-        return getKpiIdFieldBuilder().getBuilder();
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</code>
-       */
-      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
-        if (kpiIdBuilder_ != null) {
-          return kpiIdBuilder_.getMessageOrBuilder();
+      @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.AlarmID) {
+          return mergeFrom((monitoring.Monitoring.AlarmID)other);
         } else {
-          return kpiId_ == null ?
-              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+          super.mergeFrom(other);
+          return this;
         }
       }
-      /**
-       * <code>.monitoring.KpiId kpi_id = 3;</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;
+
+      public Builder mergeFrom(monitoring.Monitoring.AlarmID other) {
+        if (other == monitoring.Monitoring.AlarmID.getDefaultInstance()) return this;
+        if (other.hasAlarmId()) {
+          mergeAlarmId(other.getAlarmId());
         }
-        return kpiIdBuilder_;
+        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.AlarmID parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.AlarmID) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
       }
 
-      private monitoring.Monitoring.KpiValueRange kpiValueRange_;
+      private context.ContextOuterClass.Uuid alarmId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> kpiValueRangeBuilder_;
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> alarmIdBuilder_;
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-       * @return Whether the kpiValueRange field is set.
+       * <code>.context.Uuid alarm_id = 1;</code>
+       * @return Whether the alarmId field is set.
        */
-      public boolean hasKpiValueRange() {
-        return kpiValueRangeBuilder_ != null || kpiValueRange_ != null;
+      public boolean hasAlarmId() {
+        return alarmIdBuilder_ != null || alarmId_ != null;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
-       * @return The kpiValueRange.
+       * <code>.context.Uuid alarm_id = 1;</code>
+       * @return The alarmId.
        */
-      public monitoring.Monitoring.KpiValueRange getKpiValueRange() {
-        if (kpiValueRangeBuilder_ == null) {
-          return kpiValueRange_ == null ? monitoring.Monitoring.KpiValueRange.getDefaultInstance() : kpiValueRange_;
+      public context.ContextOuterClass.Uuid getAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
         } else {
-          return kpiValueRangeBuilder_.getMessage();
+          return alarmIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder setKpiValueRange(monitoring.Monitoring.KpiValueRange value) {
-        if (kpiValueRangeBuilder_ == null) {
+      public Builder setAlarmId(context.ContextOuterClass.Uuid value) {
+        if (alarmIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          kpiValueRange_ = value;
+          alarmId_ = value;
           onChanged();
         } else {
-          kpiValueRangeBuilder_.setMessage(value);
+          alarmIdBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder setKpiValueRange(
-          monitoring.Monitoring.KpiValueRange.Builder builderForValue) {
-        if (kpiValueRangeBuilder_ == null) {
-          kpiValueRange_ = builderForValue.build();
+      public Builder setAlarmId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = builderForValue.build();
           onChanged();
         } else {
-          kpiValueRangeBuilder_.setMessage(builderForValue.build());
+          alarmIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder mergeKpiValueRange(monitoring.Monitoring.KpiValueRange value) {
-        if (kpiValueRangeBuilder_ == null) {
-          if (kpiValueRange_ != null) {
-            kpiValueRange_ =
-              monitoring.Monitoring.KpiValueRange.newBuilder(kpiValueRange_).mergeFrom(value).buildPartial();
+      public Builder mergeAlarmId(context.ContextOuterClass.Uuid value) {
+        if (alarmIdBuilder_ == null) {
+          if (alarmId_ != null) {
+            alarmId_ =
+              context.ContextOuterClass.Uuid.newBuilder(alarmId_).mergeFrom(value).buildPartial();
           } else {
-            kpiValueRange_ = value;
+            alarmId_ = value;
           }
           onChanged();
         } else {
-          kpiValueRangeBuilder_.mergeFrom(value);
+          alarmIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public Builder clearKpiValueRange() {
-        if (kpiValueRangeBuilder_ == null) {
-          kpiValueRange_ = null;
+      public Builder clearAlarmId() {
+        if (alarmIdBuilder_ == null) {
+          alarmId_ = null;
           onChanged();
         } else {
-          kpiValueRange_ = null;
-          kpiValueRangeBuilder_ = null;
+          alarmId_ = null;
+          alarmIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public monitoring.Monitoring.KpiValueRange.Builder getKpiValueRangeBuilder() {
+      public context.ContextOuterClass.Uuid.Builder getAlarmIdBuilder() {
         
         onChanged();
-        return getKpiValueRangeFieldBuilder().getBuilder();
+        return getAlarmIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
-      public monitoring.Monitoring.KpiValueRangeOrBuilder getKpiValueRangeOrBuilder() {
-        if (kpiValueRangeBuilder_ != null) {
-          return kpiValueRangeBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
+        if (alarmIdBuilder_ != null) {
+          return alarmIdBuilder_.getMessageOrBuilder();
         } else {
-          return kpiValueRange_ == null ?
-              monitoring.Monitoring.KpiValueRange.getDefaultInstance() : kpiValueRange_;
+          return alarmId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
         }
       }
       /**
-       * <code>.monitoring.KpiValueRange kpi_value_range = 4;</code>
+       * <code>.context.Uuid alarm_id = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder> 
-          getKpiValueRangeFieldBuilder() {
-        if (kpiValueRangeBuilder_ == null) {
-          kpiValueRangeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              monitoring.Monitoring.KpiValueRange, monitoring.Monitoring.KpiValueRange.Builder, monitoring.Monitoring.KpiValueRangeOrBuilder>(
-                  getKpiValueRange(),
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getAlarmIdFieldBuilder() {
+        if (alarmIdBuilder_ == null) {
+          alarmIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getAlarmId(),
                   getParentForChildren(),
                   isClean());
-          kpiValueRange_ = null;
-        }
-        return kpiValueRangeBuilder_;
-      }
-
-      private java.lang.Object timestamp_ = "";
-      /**
-       * <code>string timestamp = 5;</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 = 5;</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;
+          alarmId_ = null;
         }
-      }
-      /**
-       * <code>string timestamp = 5;</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 = 5;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearTimestamp() {
-        
-        timestamp_ = getDefaultInstance().getTimestamp();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string timestamp = 5;</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;
+        return alarmIdBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -17399,85 +16419,97 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.AlarmDescriptor)
+      // @@protoc_insertion_point(builder_scope:monitoring.AlarmID)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.AlarmDescriptor)
-    private static final monitoring.Monitoring.AlarmDescriptor DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.AlarmID)
+    private static final monitoring.Monitoring.AlarmID DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmDescriptor();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmID();
     }
 
-    public static monitoring.Monitoring.AlarmDescriptor getDefaultInstance() {
+    public static monitoring.Monitoring.AlarmID getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<AlarmDescriptor>
-        PARSER = new com.google.protobuf.AbstractParser<AlarmDescriptor>() {
+    private static final com.google.protobuf.Parser<AlarmID>
+        PARSER = new com.google.protobuf.AbstractParser<AlarmID>() {
       @java.lang.Override
-      public AlarmDescriptor parsePartialFrom(
+      public AlarmID parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new AlarmDescriptor(input, extensionRegistry);
+        return new AlarmID(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<AlarmDescriptor> parser() {
+    public static com.google.protobuf.Parser<AlarmID> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<AlarmDescriptor> getParserForType() {
+    public com.google.protobuf.Parser<AlarmID> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.AlarmDescriptor getDefaultInstanceForType() {
+    public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface AlarmIDOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:monitoring.AlarmID)
+  public interface AlarmSubscriptionOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.AlarmSubscription)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return Whether the alarmId field is set.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return Whether the alarmID field is set.
      */
-    boolean hasAlarmId();
+    boolean hasAlarmID();
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return The alarmId.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return The alarmID.
      */
-    context.ContextOuterClass.Uuid getAlarmId();
+    monitoring.Monitoring.AlarmID getAlarmID();
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder();
+    monitoring.Monitoring.AlarmIDOrBuilder getAlarmIDOrBuilder();
+
+    /**
+     * <code>float subscription_timeout_s = 2;</code>
+     * @return The subscriptionTimeoutS.
+     */
+    float getSubscriptionTimeoutS();
+
+    /**
+     * <code>float subscription_frequency_ms = 3;</code>
+     * @return The subscriptionFrequencyMs.
+     */
+    float getSubscriptionFrequencyMs();
   }
   /**
-   * Protobuf type {@code monitoring.AlarmID}
+   * Protobuf type {@code monitoring.AlarmSubscription}
    */
-  public static final class AlarmID extends
+  public static final class AlarmSubscription extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:monitoring.AlarmID)
-      AlarmIDOrBuilder {
+      // @@protoc_insertion_point(message_implements:monitoring.AlarmSubscription)
+      AlarmSubscriptionOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use AlarmID.newBuilder() to construct.
-    private AlarmID(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use AlarmSubscription.newBuilder() to construct.
+    private AlarmSubscription(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private AlarmID() {
+    private AlarmSubscription() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new AlarmID();
+      return new AlarmSubscription();
     }
 
     @java.lang.Override
@@ -17485,7 +16517,7 @@ public final class Monitoring {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private AlarmID(
+    private AlarmSubscription(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -17504,18 +16536,28 @@ public final class Monitoring {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
-              if (alarmId_ != null) {
-                subBuilder = alarmId_.toBuilder();
+              monitoring.Monitoring.AlarmID.Builder subBuilder = null;
+              if (alarmID_ != null) {
+                subBuilder = alarmID_.toBuilder();
               }
-              alarmId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              alarmID_ = input.readMessage(monitoring.Monitoring.AlarmID.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(alarmId_);
-                alarmId_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(alarmID_);
+                alarmID_ = subBuilder.buildPartial();
               }
 
               break;
             }
+            case 21: {
+
+              subscriptionTimeoutS_ = input.readFloat();
+              break;
+            }
+            case 29: {
+
+              subscriptionFrequencyMs_ = input.readFloat();
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -17537,41 +16579,63 @@ public final class Monitoring {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
+      return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+      return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
+              monitoring.Monitoring.AlarmSubscription.class, monitoring.Monitoring.AlarmSubscription.Builder.class);
     }
 
-    public static final int ALARM_ID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid alarmId_;
+    public static final int ALARMID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.AlarmID alarmID_;
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return Whether the alarmId field is set.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return Whether the alarmID field is set.
      */
     @java.lang.Override
-    public boolean hasAlarmId() {
-      return alarmId_ != null;
+    public boolean hasAlarmID() {
+      return alarmID_ != null;
     }
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
-     * @return The alarmId.
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
+     * @return The alarmID.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getAlarmId() {
-      return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+    public monitoring.Monitoring.AlarmID getAlarmID() {
+      return alarmID_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmID_;
     }
     /**
-     * <code>.context.Uuid alarm_id = 1;</code>
+     * <code>.monitoring.AlarmID alarmID = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
-      return getAlarmId();
+    public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIDOrBuilder() {
+      return getAlarmID();
+    }
+
+    public static final int SUBSCRIPTION_TIMEOUT_S_FIELD_NUMBER = 2;
+    private float subscriptionTimeoutS_;
+    /**
+     * <code>float subscription_timeout_s = 2;</code>
+     * @return The subscriptionTimeoutS.
+     */
+    @java.lang.Override
+    public float getSubscriptionTimeoutS() {
+      return subscriptionTimeoutS_;
+    }
+
+    public static final int SUBSCRIPTION_FREQUENCY_MS_FIELD_NUMBER = 3;
+    private float subscriptionFrequencyMs_;
+    /**
+     * <code>float subscription_frequency_ms = 3;</code>
+     * @return The subscriptionFrequencyMs.
+     */
+    @java.lang.Override
+    public float getSubscriptionFrequencyMs() {
+      return subscriptionFrequencyMs_;
     }
 
     private byte memoizedIsInitialized = -1;
@@ -17588,8 +16652,14 @@ public final class Monitoring {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (alarmId_ != null) {
-        output.writeMessage(1, getAlarmId());
+      if (alarmID_ != null) {
+        output.writeMessage(1, getAlarmID());
+      }
+      if (subscriptionTimeoutS_ != 0F) {
+        output.writeFloat(2, subscriptionTimeoutS_);
+      }
+      if (subscriptionFrequencyMs_ != 0F) {
+        output.writeFloat(3, subscriptionFrequencyMs_);
       }
       unknownFields.writeTo(output);
     }
@@ -17600,9 +16670,17 @@ public final class Monitoring {
       if (size != -1) return size;
 
       size = 0;
-      if (alarmId_ != null) {
+      if (alarmID_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getAlarmId());
+          .computeMessageSize(1, getAlarmID());
+      }
+      if (subscriptionTimeoutS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(2, subscriptionTimeoutS_);
+      }
+      if (subscriptionFrequencyMs_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, subscriptionFrequencyMs_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -17614,16 +16692,22 @@ public final class Monitoring {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof monitoring.Monitoring.AlarmID)) {
+      if (!(obj instanceof monitoring.Monitoring.AlarmSubscription)) {
         return super.equals(obj);
       }
-      monitoring.Monitoring.AlarmID other = (monitoring.Monitoring.AlarmID) obj;
+      monitoring.Monitoring.AlarmSubscription other = (monitoring.Monitoring.AlarmSubscription) obj;
 
-      if (hasAlarmId() != other.hasAlarmId()) return false;
-      if (hasAlarmId()) {
-        if (!getAlarmId()
-            .equals(other.getAlarmId())) return false;
+      if (hasAlarmID() != other.hasAlarmID()) return false;
+      if (hasAlarmID()) {
+        if (!getAlarmID()
+            .equals(other.getAlarmID())) return false;
       }
+      if (java.lang.Float.floatToIntBits(getSubscriptionTimeoutS())
+          != java.lang.Float.floatToIntBits(
+              other.getSubscriptionTimeoutS())) return false;
+      if (java.lang.Float.floatToIntBits(getSubscriptionFrequencyMs())
+          != java.lang.Float.floatToIntBits(
+              other.getSubscriptionFrequencyMs())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -17635,78 +16719,84 @@ public final class Monitoring {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasAlarmId()) {
-        hash = (37 * hash) + ALARM_ID_FIELD_NUMBER;
-        hash = (53 * hash) + getAlarmId().hashCode();
+      if (hasAlarmID()) {
+        hash = (37 * hash) + ALARMID_FIELD_NUMBER;
+        hash = (53 * hash) + getAlarmID().hashCode();
       }
+      hash = (37 * hash) + SUBSCRIPTION_TIMEOUT_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSubscriptionTimeoutS());
+      hash = (37 * hash) + SUBSCRIPTION_FREQUENCY_MS_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSubscriptionFrequencyMs());
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription 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.AlarmID parseFrom(byte[] data)
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription 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.AlarmID parseDelimitedFrom(java.io.InputStream input)
+    public static monitoring.Monitoring.AlarmSubscription parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.AlarmID parseDelimitedFrom(
+    public static monitoring.Monitoring.AlarmSubscription 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.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static monitoring.Monitoring.AlarmID parseFrom(
+    public static monitoring.Monitoring.AlarmSubscription parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -17719,7 +16809,7 @@ public final class Monitoring {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(monitoring.Monitoring.AlarmID prototype) {
+    public static Builder newBuilder(monitoring.Monitoring.AlarmSubscription prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -17735,26 +16825,26 @@ public final class Monitoring {
       return builder;
     }
     /**
-     * Protobuf type {@code monitoring.AlarmID}
+     * Protobuf type {@code monitoring.AlarmSubscription}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:monitoring.AlarmID)
-        monitoring.Monitoring.AlarmIDOrBuilder {
+        // @@protoc_insertion_point(builder_implements:monitoring.AlarmSubscription)
+        monitoring.Monitoring.AlarmSubscriptionOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmID_fieldAccessorTable
+        return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                monitoring.Monitoring.AlarmID.class, monitoring.Monitoring.AlarmID.Builder.class);
+                monitoring.Monitoring.AlarmSubscription.class, monitoring.Monitoring.AlarmSubscription.Builder.class);
       }
 
-      // Construct using monitoring.Monitoring.AlarmID.newBuilder()
+      // Construct using monitoring.Monitoring.AlarmSubscription.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -17772,29 +16862,33 @@ public final class Monitoring {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (alarmIdBuilder_ == null) {
-          alarmId_ = null;
+        if (alarmIDBuilder_ == null) {
+          alarmID_ = null;
         } else {
-          alarmId_ = null;
-          alarmIdBuilder_ = null;
+          alarmID_ = null;
+          alarmIDBuilder_ = null;
         }
+        subscriptionTimeoutS_ = 0F;
+
+        subscriptionFrequencyMs_ = 0F;
+
         return this;
       }
 
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return monitoring.Monitoring.internal_static_monitoring_AlarmID_descriptor;
+        return monitoring.Monitoring.internal_static_monitoring_AlarmSubscription_descriptor;
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
-        return monitoring.Monitoring.AlarmID.getDefaultInstance();
+      public monitoring.Monitoring.AlarmSubscription getDefaultInstanceForType() {
+        return monitoring.Monitoring.AlarmSubscription.getDefaultInstance();
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.AlarmID build() {
-        monitoring.Monitoring.AlarmID result = buildPartial();
+      public monitoring.Monitoring.AlarmSubscription build() {
+        monitoring.Monitoring.AlarmSubscription result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -17802,13 +16896,15 @@ public final class Monitoring {
       }
 
       @java.lang.Override
-      public monitoring.Monitoring.AlarmID buildPartial() {
-        monitoring.Monitoring.AlarmID result = new monitoring.Monitoring.AlarmID(this);
-        if (alarmIdBuilder_ == null) {
-          result.alarmId_ = alarmId_;
+      public monitoring.Monitoring.AlarmSubscription buildPartial() {
+        monitoring.Monitoring.AlarmSubscription result = new monitoring.Monitoring.AlarmSubscription(this);
+        if (alarmIDBuilder_ == null) {
+          result.alarmID_ = alarmID_;
         } else {
-          result.alarmId_ = alarmIdBuilder_.build();
+          result.alarmID_ = alarmIDBuilder_.build();
         }
+        result.subscriptionTimeoutS_ = subscriptionTimeoutS_;
+        result.subscriptionFrequencyMs_ = subscriptionFrequencyMs_;
         onBuilt();
         return result;
       }
@@ -17847,18 +16943,24 @@ public final class Monitoring {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof monitoring.Monitoring.AlarmID) {
-          return mergeFrom((monitoring.Monitoring.AlarmID)other);
+        if (other instanceof monitoring.Monitoring.AlarmSubscription) {
+          return mergeFrom((monitoring.Monitoring.AlarmSubscription)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(monitoring.Monitoring.AlarmID other) {
-        if (other == monitoring.Monitoring.AlarmID.getDefaultInstance()) return this;
-        if (other.hasAlarmId()) {
-          mergeAlarmId(other.getAlarmId());
+      public Builder mergeFrom(monitoring.Monitoring.AlarmSubscription other) {
+        if (other == monitoring.Monitoring.AlarmSubscription.getDefaultInstance()) return this;
+        if (other.hasAlarmID()) {
+          mergeAlarmID(other.getAlarmID());
+        }
+        if (other.getSubscriptionTimeoutS() != 0F) {
+          setSubscriptionTimeoutS(other.getSubscriptionTimeoutS());
+        }
+        if (other.getSubscriptionFrequencyMs() != 0F) {
+          setSubscriptionFrequencyMs(other.getSubscriptionFrequencyMs());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -17875,11 +16977,11 @@ public final class Monitoring {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        monitoring.Monitoring.AlarmID parsedMessage = null;
+        monitoring.Monitoring.AlarmSubscription parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (monitoring.Monitoring.AlarmID) e.getUnfinishedMessage();
+          parsedMessage = (monitoring.Monitoring.AlarmSubscription) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -17889,123 +16991,185 @@ public final class Monitoring {
         return this;
       }
 
-      private context.ContextOuterClass.Uuid alarmId_;
+      private monitoring.Monitoring.AlarmID alarmID_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> alarmIdBuilder_;
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> alarmIDBuilder_;
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
-       * @return Whether the alarmId field is set.
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
+       * @return Whether the alarmID field is set.
        */
-      public boolean hasAlarmId() {
-        return alarmIdBuilder_ != null || alarmId_ != null;
+      public boolean hasAlarmID() {
+        return alarmIDBuilder_ != null || alarmID_ != null;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
-       * @return The alarmId.
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
+       * @return The alarmID.
        */
-      public context.ContextOuterClass.Uuid getAlarmId() {
-        if (alarmIdBuilder_ == null) {
-          return alarmId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+      public monitoring.Monitoring.AlarmID getAlarmID() {
+        if (alarmIDBuilder_ == null) {
+          return alarmID_ == null ? monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmID_;
         } else {
-          return alarmIdBuilder_.getMessage();
+          return alarmIDBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder setAlarmId(context.ContextOuterClass.Uuid value) {
-        if (alarmIdBuilder_ == null) {
+      public Builder setAlarmID(monitoring.Monitoring.AlarmID value) {
+        if (alarmIDBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          alarmId_ = value;
+          alarmID_ = value;
           onChanged();
         } else {
-          alarmIdBuilder_.setMessage(value);
+          alarmIDBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder setAlarmId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
-        if (alarmIdBuilder_ == null) {
-          alarmId_ = builderForValue.build();
+      public Builder setAlarmID(
+          monitoring.Monitoring.AlarmID.Builder builderForValue) {
+        if (alarmIDBuilder_ == null) {
+          alarmID_ = builderForValue.build();
           onChanged();
         } else {
-          alarmIdBuilder_.setMessage(builderForValue.build());
+          alarmIDBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder mergeAlarmId(context.ContextOuterClass.Uuid value) {
-        if (alarmIdBuilder_ == null) {
-          if (alarmId_ != null) {
-            alarmId_ =
-              context.ContextOuterClass.Uuid.newBuilder(alarmId_).mergeFrom(value).buildPartial();
+      public Builder mergeAlarmID(monitoring.Monitoring.AlarmID value) {
+        if (alarmIDBuilder_ == null) {
+          if (alarmID_ != null) {
+            alarmID_ =
+              monitoring.Monitoring.AlarmID.newBuilder(alarmID_).mergeFrom(value).buildPartial();
           } else {
-            alarmId_ = value;
+            alarmID_ = value;
           }
           onChanged();
         } else {
-          alarmIdBuilder_.mergeFrom(value);
+          alarmIDBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public Builder clearAlarmId() {
-        if (alarmIdBuilder_ == null) {
-          alarmId_ = null;
+      public Builder clearAlarmID() {
+        if (alarmIDBuilder_ == null) {
+          alarmID_ = null;
           onChanged();
         } else {
-          alarmId_ = null;
-          alarmIdBuilder_ = null;
+          alarmID_ = null;
+          alarmIDBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public context.ContextOuterClass.Uuid.Builder getAlarmIdBuilder() {
+      public monitoring.Monitoring.AlarmID.Builder getAlarmIDBuilder() {
         
         onChanged();
-        return getAlarmIdFieldBuilder().getBuilder();
+        return getAlarmIDFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
-      public context.ContextOuterClass.UuidOrBuilder getAlarmIdOrBuilder() {
-        if (alarmIdBuilder_ != null) {
-          return alarmIdBuilder_.getMessageOrBuilder();
+      public monitoring.Monitoring.AlarmIDOrBuilder getAlarmIDOrBuilder() {
+        if (alarmIDBuilder_ != null) {
+          return alarmIDBuilder_.getMessageOrBuilder();
         } else {
-          return alarmId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : alarmId_;
+          return alarmID_ == null ?
+              monitoring.Monitoring.AlarmID.getDefaultInstance() : alarmID_;
         }
       }
       /**
-       * <code>.context.Uuid alarm_id = 1;</code>
+       * <code>.monitoring.AlarmID alarmID = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
-          getAlarmIdFieldBuilder() {
-        if (alarmIdBuilder_ == null) {
-          alarmIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
-                  getAlarmId(),
+          monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder> 
+          getAlarmIDFieldBuilder() {
+        if (alarmIDBuilder_ == null) {
+          alarmIDBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmID.Builder, monitoring.Monitoring.AlarmIDOrBuilder>(
+                  getAlarmID(),
                   getParentForChildren(),
                   isClean());
-          alarmId_ = null;
+          alarmID_ = null;
         }
-        return alarmIdBuilder_;
+        return alarmIDBuilder_;
+      }
+
+      private float subscriptionTimeoutS_ ;
+      /**
+       * <code>float subscription_timeout_s = 2;</code>
+       * @return The subscriptionTimeoutS.
+       */
+      @java.lang.Override
+      public float getSubscriptionTimeoutS() {
+        return subscriptionTimeoutS_;
+      }
+      /**
+       * <code>float subscription_timeout_s = 2;</code>
+       * @param value The subscriptionTimeoutS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSubscriptionTimeoutS(float value) {
+        
+        subscriptionTimeoutS_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float subscription_timeout_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSubscriptionTimeoutS() {
+        
+        subscriptionTimeoutS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float subscriptionFrequencyMs_ ;
+      /**
+       * <code>float subscription_frequency_ms = 3;</code>
+       * @return The subscriptionFrequencyMs.
+       */
+      @java.lang.Override
+      public float getSubscriptionFrequencyMs() {
+        return subscriptionFrequencyMs_;
+      }
+      /**
+       * <code>float subscription_frequency_ms = 3;</code>
+       * @param value The subscriptionFrequencyMs to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSubscriptionFrequencyMs(float value) {
+        
+        subscriptionFrequencyMs_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float subscription_frequency_ms = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSubscriptionFrequencyMs() {
+        
+        subscriptionFrequencyMs_ = 0F;
+        onChanged();
+        return this;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -18020,41 +17184,41 @@ public final class Monitoring {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:monitoring.AlarmID)
+      // @@protoc_insertion_point(builder_scope:monitoring.AlarmSubscription)
     }
 
-    // @@protoc_insertion_point(class_scope:monitoring.AlarmID)
-    private static final monitoring.Monitoring.AlarmID DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:monitoring.AlarmSubscription)
+    private static final monitoring.Monitoring.AlarmSubscription DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmID();
+      DEFAULT_INSTANCE = new monitoring.Monitoring.AlarmSubscription();
     }
 
-    public static monitoring.Monitoring.AlarmID getDefaultInstance() {
+    public static monitoring.Monitoring.AlarmSubscription getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<AlarmID>
-        PARSER = new com.google.protobuf.AbstractParser<AlarmID>() {
+    private static final com.google.protobuf.Parser<AlarmSubscription>
+        PARSER = new com.google.protobuf.AbstractParser<AlarmSubscription>() {
       @java.lang.Override
-      public AlarmID parsePartialFrom(
+      public AlarmSubscription parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new AlarmID(input, extensionRegistry);
+        return new AlarmSubscription(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<AlarmID> parser() {
+    public static com.google.protobuf.Parser<AlarmSubscription> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<AlarmID> getParserForType() {
+    public com.google.protobuf.Parser<AlarmSubscription> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public monitoring.Monitoring.AlarmID getDefaultInstanceForType() {
+    public monitoring.Monitoring.AlarmSubscription getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
@@ -18105,6 +17269,21 @@ public final class Monitoring {
      * <code>.monitoring.KpiValue kpi_value = 3;</code>
      */
     monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
+
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return Whether the timestamp field is set.
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return The timestamp.
+     */
+    context.ContextOuterClass.Timestamp getTimestamp();
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     */
+    context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder();
   }
   /**
    * Protobuf type {@code monitoring.AlarmResponse}
@@ -18184,6 +17363,19 @@ public final class Monitoring {
 
               break;
             }
+            case 34: {
+              context.ContextOuterClass.Timestamp.Builder subBuilder = null;
+              if (timestamp_ != null) {
+                subBuilder = timestamp_.toBuilder();
+              }
+              timestamp_ = input.readMessage(context.ContextOuterClass.Timestamp.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(timestamp_);
+                timestamp_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
             default: {
               if (!parseUnknownField(
                   input, unknownFields, extensionRegistry, tag)) {
@@ -18306,6 +17498,32 @@ public final class Monitoring {
       return getKpiValue();
     }
 
+    public static final int TIMESTAMP_FIELD_NUMBER = 4;
+    private context.ContextOuterClass.Timestamp timestamp_;
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return Whether the timestamp field is set.
+     */
+    @java.lang.Override
+    public boolean hasTimestamp() {
+      return timestamp_ != null;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Timestamp getTimestamp() {
+      return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+    }
+    /**
+     * <code>.context.Timestamp timestamp = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+      return getTimestamp();
+    }
+
     private byte memoizedIsInitialized = -1;
     @java.lang.Override
     public final boolean isInitialized() {
@@ -18329,6 +17547,9 @@ public final class Monitoring {
       if (kpiValue_ != null) {
         output.writeMessage(3, getKpiValue());
       }
+      if (timestamp_ != null) {
+        output.writeMessage(4, getTimestamp());
+      }
       unknownFields.writeTo(output);
     }
 
@@ -18349,6 +17570,10 @@ public final class Monitoring {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, getKpiValue());
       }
+      if (timestamp_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, getTimestamp());
+      }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
       return size;
@@ -18376,6 +17601,11 @@ public final class Monitoring {
         if (!getKpiValue()
             .equals(other.getKpiValue())) return false;
       }
+      if (hasTimestamp() != other.hasTimestamp()) return false;
+      if (hasTimestamp()) {
+        if (!getTimestamp()
+            .equals(other.getTimestamp())) return false;
+      }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -18397,6 +17627,10 @@ public final class Monitoring {
         hash = (37 * hash) + KPI_VALUE_FIELD_NUMBER;
         hash = (53 * hash) + getKpiValue().hashCode();
       }
+      if (hasTimestamp()) {
+        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + getTimestamp().hashCode();
+      }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -18544,6 +17778,12 @@ public final class Monitoring {
           kpiValue_ = null;
           kpiValueBuilder_ = null;
         }
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
         return this;
       }
 
@@ -18581,6 +17821,11 @@ public final class Monitoring {
         } else {
           result.kpiValue_ = kpiValueBuilder_.build();
         }
+        if (timestampBuilder_ == null) {
+          result.timestamp_ = timestamp_;
+        } else {
+          result.timestamp_ = timestampBuilder_.build();
+        }
         onBuilt();
         return result;
       }
@@ -18639,6 +17884,9 @@ public final class Monitoring {
         if (other.hasKpiValue()) {
           mergeKpiValue(other.getKpiValue());
         }
+        if (other.hasTimestamp()) {
+          mergeTimestamp(other.getTimestamp());
+        }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
@@ -18981,6 +18229,125 @@ public final class Monitoring {
         }
         return kpiValueBuilder_;
       }
+
+      private context.ContextOuterClass.Timestamp timestamp_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> timestampBuilder_;
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       * @return Whether the timestamp field is set.
+       */
+      public boolean hasTimestamp() {
+        return timestampBuilder_ != null || timestamp_ != null;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       * @return The timestamp.
+       */
+      public context.ContextOuterClass.Timestamp getTimestamp() {
+        if (timestampBuilder_ == null) {
+          return timestamp_ == null ? context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        } else {
+          return timestampBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder setTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          timestamp_ = value;
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder setTimestamp(
+          context.ContextOuterClass.Timestamp.Builder builderForValue) {
+        if (timestampBuilder_ == null) {
+          timestamp_ = builderForValue.build();
+          onChanged();
+        } else {
+          timestampBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder mergeTimestamp(context.ContextOuterClass.Timestamp value) {
+        if (timestampBuilder_ == null) {
+          if (timestamp_ != null) {
+            timestamp_ =
+              context.ContextOuterClass.Timestamp.newBuilder(timestamp_).mergeFrom(value).buildPartial();
+          } else {
+            timestamp_ = value;
+          }
+          onChanged();
+        } else {
+          timestampBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public Builder clearTimestamp() {
+        if (timestampBuilder_ == null) {
+          timestamp_ = null;
+          onChanged();
+        } else {
+          timestamp_ = null;
+          timestampBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public context.ContextOuterClass.Timestamp.Builder getTimestampBuilder() {
+        
+        onChanged();
+        return getTimestampFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      public context.ContextOuterClass.TimestampOrBuilder getTimestampOrBuilder() {
+        if (timestampBuilder_ != null) {
+          return timestampBuilder_.getMessageOrBuilder();
+        } else {
+          return timestamp_ == null ?
+              context.ContextOuterClass.Timestamp.getDefaultInstance() : timestamp_;
+        }
+      }
+      /**
+       * <code>.context.Timestamp timestamp = 4;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder> 
+          getTimestampFieldBuilder() {
+        if (timestampBuilder_ == null) {
+          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Timestamp, context.ContextOuterClass.Timestamp.Builder, context.ContextOuterClass.TimestampOrBuilder>(
+                  getTimestamp(),
+                  getParentForChildren(),
+                  isClean());
+          timestamp_ = null;
+        }
+        return timestampBuilder_;
+      }
       @java.lang.Override
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
@@ -19832,16 +19199,6 @@ public final class Monitoring {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_monitoring_KpiDescriptor_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_monitoring_BundleKpiDescriptor_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_monitoring_EditedKpiDescriptor_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_monitoring_MonitorKpiRequest_descriptor;
   private static final 
@@ -19912,6 +19269,11 @@ public final class Monitoring {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_monitoring_AlarmID_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_AlarmSubscription_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_AlarmSubscription_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_monitoring_AlarmResponse_descriptor;
   private static final 
@@ -19932,97 +19294,95 @@ public final class Monitoring {
   static {
     java.lang.String[] descriptorData = {
       "\n\020monitoring.proto\022\nmonitoring\032\rcontext." +
-      "proto\032\026kpi_sample_types.proto\"\376\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\022\"\n\010slice_id\030\006 \001(\0132\020.context.S" +
-      "liceId\"\254\002\n\023BundleKpiDescriptor\022\027\n\017kpi_de" +
-      "scription\030\001 \001(\t\022&\n\013kpi_id_list\030\002 \003(\0132\021.m" +
-      "onitoring.KpiId\0228\n\017kpi_sample_type\030\003 \001(\016" +
-      "2\037.kpi_sample_types.KpiSampleType\022$\n\tdev" +
-      "ice_id\030\004 \001(\0132\021.context.DeviceId\022(\n\013endpo" +
-      "int_id\030\005 \001(\0132\023.context.EndPointId\022&\n\nser" +
-      "vice_id\030\006 \001(\0132\022.context.ServiceId\022\"\n\010sli" +
-      "ce_id\030\007 \001(\0132\020.context.SliceId\"\317\002\n\023Edited" +
-      "KpiDescriptor\022!\n\006kpi_id\030\001 \001(\0132\021.monitori" +
-      "ng.KpiId\022\027\n\017kpi_description\030\002 \001(\t\022&\n\013kpi" +
-      "_id_list\030\003 \003(\0132\021.monitoring.KpiId\0228\n\017kpi" +
-      "_sample_type\030\004 \001(\0162\037.kpi_sample_types.Kp" +
-      "iSampleType\022$\n\tdevice_id\030\005 \001(\0132\021.context" +
-      ".DeviceId\022(\n\013endpoint_id\030\006 \001(\0132\023.context" +
-      ".EndPointId\022&\n\nservice_id\030\007 \001(\0132\022.contex" +
-      "t.ServiceId\022\"\n\010slice_id\030\010 \001(\0132\020.context." +
-      "SliceId\"l\n\021MonitorKpiRequest\022!\n\006kpi_id\030\001" +
-      " \001(\0132\021.monitoring.KpiId\022\033\n\023monitoring_wi" +
-      "ndow_s\030\002 \001(\002\022\027\n\017sampling_rate_s\030\003 \001(\002\"\241\001" +
-      "\n\010KpiQuery\022!\n\006kpi_id\030\001 \003(\0132\021.monitoring." +
-      "KpiId\022\033\n\023monitoring_window_s\030\002 \001(\002\022\027\n\017sa" +
-      "mpling_rate_s\030\003 \001(\002\022\026\n\016last_n_samples\030\004 " +
-      "\001(\r\022\022\n\nstart_date\030\005 \001(\t\022\020\n\010end_date\030\006 \001(" +
-      "\t\"&\n\005KpiId\022\035\n\006kpi_id\030\001 \001(\0132\r.context.Uui" +
-      "d\"d\n\003Kpi\022!\n\006kpi_id\030\001 \001(\0132\021.monitoring.Kp" +
-      "iId\022\021\n\ttimestamp\030\002 \001(\t\022\'\n\tkpi_value\030\003 \001(" +
-      "\0132\024.monitoring.KpiValue\"e\n\rKpiValueRange" +
-      "\022)\n\013kpiMinValue\030\001 \001(\0132\024.monitoring.KpiVa" +
-      "lue\022)\n\013kpiMaxValue\030\002 \001(\0132\024.monitoring.Kp" +
-      "iValue\"a\n\010KpiValue\022\020\n\006intVal\030\001 \001(\rH\000\022\022\n\010" +
-      "floatVal\030\002 \001(\002H\000\022\023\n\tstringVal\030\003 \001(\tH\000\022\021\n" +
-      "\007boolVal\030\004 \001(\010H\000B\007\n\005value\",\n\007KpiList\022!\n\010" +
-      "kpi_list\030\001 \003(\0132\017.monitoring.Kpi\"K\n\021KpiDe" +
-      "scriptorList\0226\n\023kpi_descriptor_list\030\001 \003(" +
-      "\0132\031.monitoring.KpiDescriptor\"\223\001\n\016SubsDes" +
+      "proto\032\026kpi_sample_types.proto\"\311\002\n\rKpiDes" +
       "criptor\022!\n\006kpi_id\030\001 \001(\0132\021.monitoring.Kpi" +
-      "Id\022\033\n\023sampling_duration_s\030\002 \001(\002\022\033\n\023sampl" +
-      "ing_interval_s\030\003 \001(\002\022\022\n\nstart_date\030\004 \001(\t" +
-      "\022\020\n\010end_date\030\005 \001(\t\"0\n\016SubscriptionID\022\036\n\007" +
-      "subs_id\030\001 \001(\0132\r.context.Uuid\"b\n\014SubsResp" +
-      "onse\022+\n\007subs_id\030\001 \001(\0132\032.monitoring.Subsc" +
-      "riptionID\022%\n\010kpi_list\030\002 \003(\0132\023.monitoring" +
-      ".KpiList\";\n\nSubsIDList\022-\n\tsubs_list\030\001 \003(" +
-      "\0132\032.monitoring.SubscriptionID\"\244\001\n\017AlarmD" +
-      "escriptor\022\031\n\021alarm_description\030\001 \001(\t\022\014\n\004" +
-      "name\030\002 \001(\t\022!\n\006kpi_id\030\003 \001(\0132\021.monitoring." +
-      "KpiId\0222\n\017kpi_value_range\030\004 \001(\0132\031.monitor" +
-      "ing.KpiValueRange\022\021\n\ttimestamp\030\005 \001(\t\"*\n\007" +
-      "AlarmID\022\037\n\010alarm_id\030\001 \001(\0132\r.context.Uuid" +
-      "\"m\n\rAlarmResponse\022%\n\010alarm_id\030\001 \001(\0132\023.mo" +
-      "nitoring.AlarmID\022\014\n\004text\030\002 \001(\t\022\'\n\tkpi_va" +
-      "lue\030\003 \001(\0132\024.monitoring.KpiValue\"6\n\013Alarm" +
-      "IDList\022\'\n\nalarm_list\030\001 \003(\0132\023.monitoring." +
-      "AlarmID2\271\t\n\021MonitoringService\022;\n\tCreateK" +
-      "pi\022\031.monitoring.KpiDescriptor\032\021.monitori" +
-      "ng.KpiId\"\000\022F\n\021EditKpiDescriptor\022\037.monito" +
-      "ring.EditedKpiDescriptor\032\016.context.Empty" +
-      "\"\000\0220\n\tDeleteKpi\022\021.monitoring.KpiId\032\016.con" +
-      "text.Empty\"\000\022G\n\024GetKpiDescriptorList\022\016.c" +
-      "ontext.Empty\032\035.monitoring.KpiDescriptorL" +
-      "ist\"\000\022G\n\017CreateBundleKpi\022\037.monitoring.Bu" +
-      "ndleKpiDescriptor\032\021.monitoring.KpiId\"\000\022B" +
-      "\n\020GetKpiDescriptor\022\021.monitoring.KpiId\032\031." +
-      "monitoring.KpiDescriptor\"\000\022/\n\nIncludeKpi" +
-      "\022\017.monitoring.Kpi\032\016.context.Empty\"\000\022=\n\nM" +
-      "onitorKpi\022\035.monitoring.MonitorKpiRequest" +
-      "\032\016.context.Empty\"\000\022;\n\014QueryKpiData\022\024.mon" +
-      "itoring.KpiQuery\032\023.monitoring.KpiList\"\000\022" +
-      "C\n\014SubscribeKpi\022\032.monitoring.SubsDescrip" +
-      "tor\032\023.monitoring.KpiList\"\0000\001\022M\n\021GetSubsD" +
-      "escriptor\022\032.monitoring.SubscriptionID\032\032." +
-      "monitoring.SubsDescriptor\"\000\022<\n\020GetSubscr" +
-      "iptions\022\016.context.Empty\032\026.monitoring.Sub" +
-      "sIDList\"\000\022C\n\023EditKpiSubscription\022\032.monit" +
-      "oring.SubsDescriptor\032\016.context.Empty\"\000\022D" +
-      "\n\016CreateKpiAlarm\022\033.monitoring.AlarmDescr" +
-      "iptor\032\023.monitoring.AlarmID\"\000\022=\n\014EditKpiA" +
-      "larm\022\033.monitoring.AlarmDescriptor\032\016.cont" +
-      "ext.Empty\"\000\0226\n\tGetAlarms\022\016.context.Empty" +
-      "\032\027.monitoring.AlarmIDList\"\000\022H\n\022GetAlarmD" +
-      "escriptor\022\023.monitoring.AlarmID\032\033.monitor" +
-      "ing.AlarmDescriptor\"\000\022L\n\026GetAlarmRespons" +
-      "eStream\022\023.monitoring.AlarmID\032\031.monitorin" +
-      "g.AlarmResponse\"\0000\001b\006proto3"
+      "Id\022\027\n\017kpi_description\030\002 \001(\t\022&\n\013kpi_id_li" +
+      "st\030\003 \003(\0132\021.monitoring.KpiId\0228\n\017kpi_sampl" +
+      "e_type\030\004 \001(\0162\037.kpi_sample_types.KpiSampl" +
+      "eType\022$\n\tdevice_id\030\005 \001(\0132\021.context.Devic" +
+      "eId\022(\n\013endpoint_id\030\006 \001(\0132\023.context.EndPo" +
+      "intId\022&\n\nservice_id\030\007 \001(\0132\022.context.Serv" +
+      "iceId\022\"\n\010slice_id\030\010 \001(\0132\020.context.SliceI" +
+      "d\"l\n\021MonitorKpiRequest\022!\n\006kpi_id\030\001 \001(\0132\021" +
+      ".monitoring.KpiId\022\033\n\023monitoring_window_s" +
+      "\030\002 \001(\002\022\027\n\017sampling_rate_s\030\003 \001(\002\"\323\001\n\010KpiQ" +
+      "uery\022!\n\006kpi_id\030\001 \003(\0132\021.monitoring.KpiId\022" +
+      "\033\n\023monitoring_window_s\030\002 \001(\002\022\027\n\017sampling" +
+      "_rate_s\030\003 \001(\002\022\026\n\016last_n_samples\030\004 \001(\r\022+\n" +
+      "\017start_timestamp\030\005 \001(\0132\022.context.Timesta" +
+      "mp\022)\n\rend_timestamp\030\006 \001(\0132\022.context.Time" +
+      "stamp\"&\n\005KpiId\022\035\n\006kpi_id\030\001 \001(\0132\r.context" +
+      ".Uuid\"x\n\003Kpi\022!\n\006kpi_id\030\001 \001(\0132\021.monitorin" +
+      "g.KpiId\022%\n\ttimestamp\030\002 \001(\0132\022.context.Tim" +
+      "estamp\022\'\n\tkpi_value\030\003 \001(\0132\024.monitoring.K" +
+      "piValue\"\250\001\n\rKpiValueRange\022)\n\013kpiMinValue" +
+      "\030\001 \001(\0132\024.monitoring.KpiValue\022)\n\013kpiMaxVa" +
+      "lue\030\002 \001(\0132\024.monitoring.KpiValue\022\017\n\007inRan" +
+      "ge\030\003 \001(\010\022\027\n\017includeMinValue\030\004 \001(\010\022\027\n\017inc" +
+      "ludeMaxValue\030\005 \001(\010\"\241\001\n\010KpiValue\022\022\n\010int32" +
+      "Val\030\001 \001(\005H\000\022\023\n\tuint32Val\030\002 \001(\rH\000\022\022\n\010int6" +
+      "4Val\030\003 \001(\003H\000\022\023\n\tuint64Val\030\004 \001(\004H\000\022\022\n\010flo" +
+      "atVal\030\005 \001(\002H\000\022\023\n\tstringVal\030\006 \001(\tH\000\022\021\n\007bo" +
+      "olVal\030\007 \001(\010H\000B\007\n\005value\",\n\007KpiList\022!\n\010kpi" +
+      "_list\030\001 \003(\0132\017.monitoring.Kpi\"K\n\021KpiDescr" +
+      "iptorList\0226\n\023kpi_descriptor_list\030\001 \003(\0132\031" +
+      ".monitoring.KpiDescriptor\"\362\001\n\016SubsDescri" +
+      "ptor\022+\n\007subs_id\030\001 \001(\0132\032.monitoring.Subsc" +
+      "riptionID\022!\n\006kpi_id\030\002 \001(\0132\021.monitoring.K" +
+      "piId\022\033\n\023sampling_duration_s\030\003 \001(\002\022\033\n\023sam" +
+      "pling_interval_s\030\004 \001(\002\022+\n\017start_timestam" +
+      "p\030\005 \001(\0132\022.context.Timestamp\022)\n\rend_times" +
+      "tamp\030\006 \001(\0132\022.context.Timestamp\"0\n\016Subscr" +
+      "iptionID\022\036\n\007subs_id\030\001 \001(\0132\r.context.Uuid" +
+      "\"b\n\014SubsResponse\022+\n\007subs_id\030\001 \001(\0132\032.moni" +
+      "toring.SubscriptionID\022%\n\010kpi_list\030\002 \003(\0132" +
+      "\023.monitoring.KpiList\";\n\nSubsIDList\022-\n\tsu" +
+      "bs_list\030\001 \003(\0132\032.monitoring.SubscriptionI" +
+      "D\"\337\001\n\017AlarmDescriptor\022%\n\010alarm_id\030\001 \001(\0132" +
+      "\023.monitoring.AlarmID\022\031\n\021alarm_descriptio" +
+      "n\030\002 \001(\t\022\014\n\004name\030\003 \001(\t\022!\n\006kpi_id\030\004 \003(\0132\021." +
+      "monitoring.KpiId\0222\n\017kpi_value_range\030\005 \003(" +
+      "\0132\031.monitoring.KpiValueRange\022%\n\ttimestam" +
+      "p\030\006 \001(\0132\022.context.Timestamp\"*\n\007AlarmID\022\037" +
+      "\n\010alarm_id\030\001 \001(\0132\r.context.Uuid\"|\n\021Alarm" +
+      "Subscription\022$\n\007alarmID\030\001 \001(\0132\023.monitori" +
+      "ng.AlarmID\022\036\n\026subscription_timeout_s\030\002 \001" +
+      "(\002\022!\n\031subscription_frequency_ms\030\003 \001(\002\"\224\001" +
+      "\n\rAlarmResponse\022%\n\010alarm_id\030\001 \001(\0132\023.moni" +
+      "toring.AlarmID\022\014\n\004text\030\002 \001(\t\022\'\n\tkpi_valu" +
+      "e\030\003 \001(\0132\024.monitoring.KpiValue\022%\n\ttimesta" +
+      "mp\030\004 \001(\0132\022.context.Timestamp\"6\n\013AlarmIDL" +
+      "ist\022\'\n\nalarm_list\030\001 \003(\0132\023.monitoring.Ala" +
+      "rmID2\233\t\n\021MonitoringService\0228\n\006SetKpi\022\031.m" +
+      "onitoring.KpiDescriptor\032\021.monitoring.Kpi" +
+      "Id\"\000\0220\n\tDeleteKpi\022\021.monitoring.KpiId\032\016.c" +
+      "ontext.Empty\"\000\022B\n\020GetKpiDescriptor\022\021.mon" +
+      "itoring.KpiId\032\031.monitoring.KpiDescriptor" +
+      "\"\000\022G\n\024GetKpiDescriptorList\022\016.context.Emp" +
+      "ty\032\035.monitoring.KpiDescriptorList\"\000\022/\n\nI" +
+      "ncludeKpi\022\017.monitoring.Kpi\032\016.context.Emp" +
+      "ty\"\000\022=\n\nMonitorKpi\022\035.monitoring.MonitorK" +
+      "piRequest\032\016.context.Empty\"\000\022;\n\014QueryKpiD" +
+      "ata\022\024.monitoring.KpiQuery\032\023.monitoring.K" +
+      "piList\"\000\022I\n\022SetKpiSubscription\022\032.monitor" +
+      "ing.SubsDescriptor\032\023.monitoring.KpiList\"" +
+      "\0000\001\022M\n\021GetSubsDescriptor\022\032.monitoring.Su" +
+      "bscriptionID\032\032.monitoring.SubsDescriptor" +
+      "\"\000\022<\n\020GetSubscriptions\022\016.context.Empty\032\026" +
+      ".monitoring.SubsIDList\"\000\022B\n\022DeleteSubscr" +
+      "iption\022\032.monitoring.SubscriptionID\032\016.con" +
+      "text.Empty\"\000\022A\n\013SetKpiAlarm\022\033.monitoring" +
+      ".AlarmDescriptor\032\023.monitoring.AlarmID\"\000\022" +
+      "6\n\tGetAlarms\022\016.context.Empty\032\027.monitorin" +
+      "g.AlarmIDList\"\000\022H\n\022GetAlarmDescriptor\022\023." +
+      "monitoring.AlarmID\032\033.monitoring.AlarmDes" +
+      "criptor\"\000\022V\n\026GetAlarmResponseStream\022\035.mo" +
+      "nitoring.AlarmSubscription\032\031.monitoring." +
+      "AlarmResponse\"\0000\001\0224\n\013DeleteAlarm\022\023.monit" +
+      "oring.AlarmID\032\016.context.Empty\"\000\0226\n\014GetSt" +
+      "reamKpi\022\021.monitoring.KpiId\032\017.monitoring." +
+      "Kpi\"\0000\001\0229\n\rGetInstantKpi\022\021.monitoring.Kp" +
+      "iId\032\023.monitoring.KpiList\"\000b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -20035,111 +19395,105 @@ public final class Monitoring {
     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", "SliceId", });
-    internal_static_monitoring_BundleKpiDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(1);
-    internal_static_monitoring_BundleKpiDescriptor_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_monitoring_BundleKpiDescriptor_descriptor,
-        new java.lang.String[] { "KpiDescription", "KpiIdList", "KpiSampleType", "DeviceId", "EndpointId", "ServiceId", "SliceId", });
-    internal_static_monitoring_EditedKpiDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(2);
-    internal_static_monitoring_EditedKpiDescriptor_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_monitoring_EditedKpiDescriptor_descriptor,
         new java.lang.String[] { "KpiId", "KpiDescription", "KpiIdList", "KpiSampleType", "DeviceId", "EndpointId", "ServiceId", "SliceId", });
     internal_static_monitoring_MonitorKpiRequest_descriptor =
-      getDescriptor().getMessageTypes().get(3);
+      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", "MonitoringWindowS", "SamplingRateS", });
     internal_static_monitoring_KpiQuery_descriptor =
-      getDescriptor().getMessageTypes().get(4);
+      getDescriptor().getMessageTypes().get(2);
     internal_static_monitoring_KpiQuery_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiQuery_descriptor,
-        new java.lang.String[] { "KpiId", "MonitoringWindowS", "SamplingRateS", "LastNSamples", "StartDate", "EndDate", });
+        new java.lang.String[] { "KpiId", "MonitoringWindowS", "SamplingRateS", "LastNSamples", "StartTimestamp", "EndTimestamp", });
     internal_static_monitoring_KpiId_descriptor =
-      getDescriptor().getMessageTypes().get(5);
+      getDescriptor().getMessageTypes().get(3);
     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(6);
+      getDescriptor().getMessageTypes().get(4);
     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_KpiValueRange_descriptor =
-      getDescriptor().getMessageTypes().get(7);
+      getDescriptor().getMessageTypes().get(5);
     internal_static_monitoring_KpiValueRange_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiValueRange_descriptor,
-        new java.lang.String[] { "KpiMinValue", "KpiMaxValue", });
+        new java.lang.String[] { "KpiMinValue", "KpiMaxValue", "InRange", "IncludeMinValue", "IncludeMaxValue", });
     internal_static_monitoring_KpiValue_descriptor =
-      getDescriptor().getMessageTypes().get(8);
+      getDescriptor().getMessageTypes().get(6);
     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", });
+        new java.lang.String[] { "Int32Val", "Uint32Val", "Int64Val", "Uint64Val", "FloatVal", "StringVal", "BoolVal", "Value", });
     internal_static_monitoring_KpiList_descriptor =
-      getDescriptor().getMessageTypes().get(9);
+      getDescriptor().getMessageTypes().get(7);
     internal_static_monitoring_KpiList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiList_descriptor,
         new java.lang.String[] { "KpiList", });
     internal_static_monitoring_KpiDescriptorList_descriptor =
-      getDescriptor().getMessageTypes().get(10);
+      getDescriptor().getMessageTypes().get(8);
     internal_static_monitoring_KpiDescriptorList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_KpiDescriptorList_descriptor,
         new java.lang.String[] { "KpiDescriptorList", });
     internal_static_monitoring_SubsDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(11);
+      getDescriptor().getMessageTypes().get(9);
     internal_static_monitoring_SubsDescriptor_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubsDescriptor_descriptor,
-        new java.lang.String[] { "KpiId", "SamplingDurationS", "SamplingIntervalS", "StartDate", "EndDate", });
+        new java.lang.String[] { "SubsId", "KpiId", "SamplingDurationS", "SamplingIntervalS", "StartTimestamp", "EndTimestamp", });
     internal_static_monitoring_SubscriptionID_descriptor =
-      getDescriptor().getMessageTypes().get(12);
+      getDescriptor().getMessageTypes().get(10);
     internal_static_monitoring_SubscriptionID_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubscriptionID_descriptor,
         new java.lang.String[] { "SubsId", });
     internal_static_monitoring_SubsResponse_descriptor =
-      getDescriptor().getMessageTypes().get(13);
+      getDescriptor().getMessageTypes().get(11);
     internal_static_monitoring_SubsResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubsResponse_descriptor,
         new java.lang.String[] { "SubsId", "KpiList", });
     internal_static_monitoring_SubsIDList_descriptor =
-      getDescriptor().getMessageTypes().get(14);
+      getDescriptor().getMessageTypes().get(12);
     internal_static_monitoring_SubsIDList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_SubsIDList_descriptor,
         new java.lang.String[] { "SubsList", });
     internal_static_monitoring_AlarmDescriptor_descriptor =
-      getDescriptor().getMessageTypes().get(15);
+      getDescriptor().getMessageTypes().get(13);
     internal_static_monitoring_AlarmDescriptor_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmDescriptor_descriptor,
-        new java.lang.String[] { "AlarmDescription", "Name", "KpiId", "KpiValueRange", "Timestamp", });
+        new java.lang.String[] { "AlarmId", "AlarmDescription", "Name", "KpiId", "KpiValueRange", "Timestamp", });
     internal_static_monitoring_AlarmID_descriptor =
-      getDescriptor().getMessageTypes().get(16);
+      getDescriptor().getMessageTypes().get(14);
     internal_static_monitoring_AlarmID_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmID_descriptor,
         new java.lang.String[] { "AlarmId", });
+    internal_static_monitoring_AlarmSubscription_descriptor =
+      getDescriptor().getMessageTypes().get(15);
+    internal_static_monitoring_AlarmSubscription_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_AlarmSubscription_descriptor,
+        new java.lang.String[] { "AlarmID", "SubscriptionTimeoutS", "SubscriptionFrequencyMs", });
     internal_static_monitoring_AlarmResponse_descriptor =
-      getDescriptor().getMessageTypes().get(17);
+      getDescriptor().getMessageTypes().get(16);
     internal_static_monitoring_AlarmResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmResponse_descriptor,
-        new java.lang.String[] { "AlarmId", "Text", "KpiValue", });
+        new java.lang.String[] { "AlarmId", "Text", "KpiValue", "Timestamp", });
     internal_static_monitoring_AlarmIDList_descriptor =
-      getDescriptor().getMessageTypes().get(18);
+      getDescriptor().getMessageTypes().get(17);
     internal_static_monitoring_AlarmIDList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_monitoring_AlarmIDList_descriptor,
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java
index f826e1167d1ed56567fc470ba70cc09003617eda..6372600680d57d0b351e7dd67b88c84f9d8e8cff 100644
--- a/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java
@@ -8,18 +8,14 @@ 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<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request);
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request);
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request);
     
-    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request);
-    
-    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request);
-    
     io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request);
     
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty 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);
@@ -30,20 +26,24 @@ public interface MonitoringService extends MutinyService {
     
     io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request);
     
-    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request);
-    
-    io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request);
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request);
     
-    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request);
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request);
     
     io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request);
     
     io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request);
+    
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request);
+    
+    
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request);
     
-    io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request);
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request);
     
-    io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request);
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request);
     
     
 
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
index c7f776e7bd0c56cabc7009e7b7bdb208669fb441..21f7f48acd6b6870584133dc3d665f681e78cf5e 100644
--- a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
@@ -16,25 +16,25 @@ public class MonitoringServiceBean extends MutinyMonitoringServiceGrpc.Monitorin
     }
 
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
        try {
-         return delegate.createKpi(request);
+         return delegate.setKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.editKpiDescriptor(request);
+         return delegate.deleteKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.deleteKpi(request);
+         return delegate.getKpiDescriptor(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
@@ -48,115 +48,116 @@ public class MonitoringServiceBean extends MutinyMonitoringServiceGrpc.Monitorin
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
        try {
-         return delegate.createBundleKpi(request);
+         return delegate.includeKpi(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) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
        try {
-         return delegate.getKpiDescriptor(request);
+         return delegate.monitorKpi(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) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
        try {
-         return delegate.includeKpi(request);
+         return delegate.queryKpiData(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) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
        try {
-         return delegate.monitorKpi(request);
+         return delegate.getSubsDescriptor(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
        try {
-         return delegate.queryKpiData(request);
+         return delegate.getSubscriptions(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
        try {
-         return delegate.getSubsDescriptor(request);
+         return delegate.deleteSubscription(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
        try {
-         return delegate.getSubscriptions(request);
+         return delegate.setKpiAlarm(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
        try {
-         return delegate.editKpiSubscription(request);
+         return delegate.getAlarms(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
        try {
-         return delegate.createKpiAlarm(request);
+         return delegate.getAlarmDescriptor(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
        try {
-         return delegate.editKpiAlarm(request);
+         return delegate.deleteAlarm(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.getAlarms(request);
+         return delegate.getInstantKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
+
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
        try {
-         return delegate.getAlarmDescriptor(request);
+         return delegate.setKpiSubscription(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
        try {
-         return delegate.subscribeKpi(request);
+         return delegate.getAlarmResponseStream(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
        try {
-         return delegate.getAlarmResponseStream(request);
+         return delegate.getStreamKpi(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
index 35c98e8ff2c240e749e602c4d097c3bef81c8203..6b6dc38645931ad94287b4151019c3b42a1c098d 100644
--- a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
@@ -21,30 +21,22 @@ public class MonitoringServiceClient implements MonitoringService, MutinyClient<
     }
 
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
-       return stub.createKpi(request);
-    }
-    @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
-       return stub.editKpiDescriptor(request);
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
+       return stub.setKpi(request);
     }
     @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
        return stub.deleteKpi(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
-       return stub.getKpiDescriptorList(request);
-    }
-    @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
-       return stub.createBundleKpi(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<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
+       return stub.getKpiDescriptorList(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
        return stub.includeKpi(request);
     }
@@ -65,16 +57,12 @@ public class MonitoringServiceClient implements MonitoringService, MutinyClient<
        return stub.getSubscriptions(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
-       return stub.editKpiSubscription(request);
-    }
-    @Override
-    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-       return stub.createKpiAlarm(request);
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
+       return stub.deleteSubscription(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-       return stub.editKpiAlarm(request);
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+       return stub.setKpiAlarm(request);
     }
     @Override
     public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
@@ -84,15 +72,28 @@ public class MonitoringServiceClient implements MonitoringService, MutinyClient<
     public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
        return stub.getAlarmDescriptor(request);
     }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
+       return stub.deleteAlarm(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
+       return stub.getInstantKpi(request);
+    }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
-       return stub.subscribeKpi(request);
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+       return stub.setKpiSubscription(request);
     }
 
     @Override
-    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
        return stub.getAlarmResponseStream(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
index d4ae3510a2f622b195854e4c7d197b8e3ff4d5fd..fe92a7814166b65b12db5d50bb4baaf525c59146 100644
--- a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
@@ -15,96 +15,96 @@ public final class MonitoringServiceGrpc {
 
   // Static method descriptors that strictly reflect the proto.
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor,
-      monitoring.Monitoring.KpiId> getCreateKpiMethod;
+      monitoring.Monitoring.KpiId> getSetKpiMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "CreateKpi",
+      fullMethodName = SERVICE_NAME + '/' + "SetKpi",
       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) {
+      monitoring.Monitoring.KpiId> getSetKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiId> getSetKpiMethod;
+    if ((getSetKpiMethod = MonitoringServiceGrpc.getSetKpiMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getCreateKpiMethod = MonitoringServiceGrpc.getCreateKpiMethod) == null) {
-          MonitoringServiceGrpc.getCreateKpiMethod = getCreateKpiMethod =
+        if ((getSetKpiMethod = MonitoringServiceGrpc.getSetKpiMethod) == null) {
+          MonitoringServiceGrpc.getSetKpiMethod = getSetKpiMethod =
               io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiId>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateKpi"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetKpi"))
               .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"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SetKpi"))
               .build();
         }
       }
     }
-    return getCreateKpiMethod;
+    return getSetKpiMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.EditedKpiDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiDescriptorMethod;
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      context.ContextOuterClass.Empty> getDeleteKpiMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "EditKpiDescriptor",
-      requestType = monitoring.Monitoring.EditedKpiDescriptor.class,
+      fullMethodName = SERVICE_NAME + '/' + "DeleteKpi",
+      requestType = monitoring.Monitoring.KpiId.class,
       responseType = context.ContextOuterClass.Empty.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.EditedKpiDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiDescriptorMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.EditedKpiDescriptor, context.ContextOuterClass.Empty> getEditKpiDescriptorMethod;
-    if ((getEditKpiDescriptorMethod = MonitoringServiceGrpc.getEditKpiDescriptorMethod) == null) {
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      context.ContextOuterClass.Empty> getDeleteKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty> getDeleteKpiMethod;
+    if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getEditKpiDescriptorMethod = MonitoringServiceGrpc.getEditKpiDescriptorMethod) == null) {
-          MonitoringServiceGrpc.getEditKpiDescriptorMethod = getEditKpiDescriptorMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.EditedKpiDescriptor, context.ContextOuterClass.Empty>newBuilder()
+        if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
+          MonitoringServiceGrpc.getDeleteKpiMethod = getDeleteKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "EditKpiDescriptor"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteKpi"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.EditedKpiDescriptor.getDefaultInstance()))
+                  monitoring.Monitoring.KpiId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("EditKpiDescriptor"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteKpi"))
               .build();
         }
       }
     }
-    return getEditKpiDescriptorMethod;
+    return getDeleteKpiMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
-      context.ContextOuterClass.Empty> getDeleteKpiMethod;
+      monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "DeleteKpi",
+      fullMethodName = SERVICE_NAME + '/' + "GetKpiDescriptor",
       requestType = monitoring.Monitoring.KpiId.class,
-      responseType = context.ContextOuterClass.Empty.class,
+      responseType = monitoring.Monitoring.KpiDescriptor.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
   public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
-      context.ContextOuterClass.Empty> getDeleteKpiMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty> getDeleteKpiMethod;
-    if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
+      monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod;
+    if ((getGetKpiDescriptorMethod = MonitoringServiceGrpc.getGetKpiDescriptorMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getDeleteKpiMethod = MonitoringServiceGrpc.getDeleteKpiMethod) == null) {
-          MonitoringServiceGrpc.getDeleteKpiMethod = getDeleteKpiMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, context.ContextOuterClass.Empty>newBuilder()
+        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, "DeleteKpi"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetKpiDescriptor"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.KpiId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteKpi"))
+                  monitoring.Monitoring.KpiDescriptor.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetKpiDescriptor"))
               .build();
         }
       }
     }
-    return getDeleteKpiMethod;
+    return getGetKpiDescriptorMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
@@ -138,68 +138,6 @@ public final class MonitoringServiceGrpc {
     return getGetKpiDescriptorListMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.BundleKpiDescriptor,
-      monitoring.Monitoring.KpiId> getCreateBundleKpiMethod;
-
-  @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "CreateBundleKpi",
-      requestType = monitoring.Monitoring.BundleKpiDescriptor.class,
-      responseType = monitoring.Monitoring.KpiId.class,
-      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.BundleKpiDescriptor,
-      monitoring.Monitoring.KpiId> getCreateBundleKpiMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.BundleKpiDescriptor, monitoring.Monitoring.KpiId> getCreateBundleKpiMethod;
-    if ((getCreateBundleKpiMethod = MonitoringServiceGrpc.getCreateBundleKpiMethod) == null) {
-      synchronized (MonitoringServiceGrpc.class) {
-        if ((getCreateBundleKpiMethod = MonitoringServiceGrpc.getCreateBundleKpiMethod) == null) {
-          MonitoringServiceGrpc.getCreateBundleKpiMethod = getCreateBundleKpiMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.BundleKpiDescriptor, monitoring.Monitoring.KpiId>newBuilder()
-              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateBundleKpi"))
-              .setSampledToLocalTracing(true)
-              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.BundleKpiDescriptor.getDefaultInstance()))
-              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.KpiId.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("CreateBundleKpi"))
-              .build();
-        }
-      }
-    }
-    return getCreateBundleKpiMethod;
-  }
-
-  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;
 
@@ -294,34 +232,34 @@ public final class MonitoringServiceGrpc {
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      monitoring.Monitoring.KpiList> getSubscribeKpiMethod;
+      monitoring.Monitoring.KpiList> getSetKpiSubscriptionMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "SubscribeKpi",
+      fullMethodName = SERVICE_NAME + '/' + "SetKpiSubscription",
       requestType = monitoring.Monitoring.SubsDescriptor.class,
       responseType = monitoring.Monitoring.KpiList.class,
       methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
   public static io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      monitoring.Monitoring.KpiList> getSubscribeKpiMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor, monitoring.Monitoring.KpiList> getSubscribeKpiMethod;
-    if ((getSubscribeKpiMethod = MonitoringServiceGrpc.getSubscribeKpiMethod) == null) {
+      monitoring.Monitoring.KpiList> getSetKpiSubscriptionMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor, monitoring.Monitoring.KpiList> getSetKpiSubscriptionMethod;
+    if ((getSetKpiSubscriptionMethod = MonitoringServiceGrpc.getSetKpiSubscriptionMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getSubscribeKpiMethod = MonitoringServiceGrpc.getSubscribeKpiMethod) == null) {
-          MonitoringServiceGrpc.getSubscribeKpiMethod = getSubscribeKpiMethod =
+        if ((getSetKpiSubscriptionMethod = MonitoringServiceGrpc.getSetKpiSubscriptionMethod) == null) {
+          MonitoringServiceGrpc.getSetKpiSubscriptionMethod = getSetKpiSubscriptionMethod =
               io.grpc.MethodDescriptor.<monitoring.Monitoring.SubsDescriptor, monitoring.Monitoring.KpiList>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SubscribeKpi"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetKpiSubscription"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.SubsDescriptor.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.KpiList.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SubscribeKpi"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SetKpiSubscription"))
               .build();
         }
       }
     }
-    return getSubscribeKpiMethod;
+    return getSetKpiSubscriptionMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID,
@@ -386,97 +324,66 @@ public final class MonitoringServiceGrpc {
     return getGetSubscriptionsMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiSubscriptionMethod;
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID,
+      context.ContextOuterClass.Empty> getDeleteSubscriptionMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "EditKpiSubscription",
-      requestType = monitoring.Monitoring.SubsDescriptor.class,
+      fullMethodName = SERVICE_NAME + '/' + "DeleteSubscription",
+      requestType = monitoring.Monitoring.SubscriptionID.class,
       responseType = context.ContextOuterClass.Empty.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiSubscriptionMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.SubsDescriptor, context.ContextOuterClass.Empty> getEditKpiSubscriptionMethod;
-    if ((getEditKpiSubscriptionMethod = MonitoringServiceGrpc.getEditKpiSubscriptionMethod) == null) {
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID,
+      context.ContextOuterClass.Empty> getDeleteSubscriptionMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.SubscriptionID, context.ContextOuterClass.Empty> getDeleteSubscriptionMethod;
+    if ((getDeleteSubscriptionMethod = MonitoringServiceGrpc.getDeleteSubscriptionMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getEditKpiSubscriptionMethod = MonitoringServiceGrpc.getEditKpiSubscriptionMethod) == null) {
-          MonitoringServiceGrpc.getEditKpiSubscriptionMethod = getEditKpiSubscriptionMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.SubsDescriptor, context.ContextOuterClass.Empty>newBuilder()
+        if ((getDeleteSubscriptionMethod = MonitoringServiceGrpc.getDeleteSubscriptionMethod) == null) {
+          MonitoringServiceGrpc.getDeleteSubscriptionMethod = getDeleteSubscriptionMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.SubscriptionID, context.ContextOuterClass.Empty>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "EditKpiSubscription"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteSubscription"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.SubsDescriptor.getDefaultInstance()))
+                  monitoring.Monitoring.SubscriptionID.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("EditKpiSubscription"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteSubscription"))
               .build();
         }
       }
     }
-    return getEditKpiSubscriptionMethod;
+    return getDeleteSubscriptionMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      monitoring.Monitoring.AlarmID> getCreateKpiAlarmMethod;
+      monitoring.Monitoring.AlarmID> getSetKpiAlarmMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "CreateKpiAlarm",
+      fullMethodName = SERVICE_NAME + '/' + "SetKpiAlarm",
       requestType = monitoring.Monitoring.AlarmDescriptor.class,
       responseType = monitoring.Monitoring.AlarmID.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
   public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      monitoring.Monitoring.AlarmID> getCreateKpiAlarmMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor, monitoring.Monitoring.AlarmID> getCreateKpiAlarmMethod;
-    if ((getCreateKpiAlarmMethod = MonitoringServiceGrpc.getCreateKpiAlarmMethod) == null) {
+      monitoring.Monitoring.AlarmID> getSetKpiAlarmMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor, monitoring.Monitoring.AlarmID> getSetKpiAlarmMethod;
+    if ((getSetKpiAlarmMethod = MonitoringServiceGrpc.getSetKpiAlarmMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
-        if ((getCreateKpiAlarmMethod = MonitoringServiceGrpc.getCreateKpiAlarmMethod) == null) {
-          MonitoringServiceGrpc.getCreateKpiAlarmMethod = getCreateKpiAlarmMethod =
+        if ((getSetKpiAlarmMethod = MonitoringServiceGrpc.getSetKpiAlarmMethod) == null) {
+          MonitoringServiceGrpc.getSetKpiAlarmMethod = getSetKpiAlarmMethod =
               io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmDescriptor, monitoring.Monitoring.AlarmID>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateKpiAlarm"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetKpiAlarm"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.AlarmID.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("CreateKpiAlarm"))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("SetKpiAlarm"))
               .build();
         }
       }
     }
-    return getCreateKpiAlarmMethod;
-  }
-
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiAlarmMethod;
-
-  @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "EditKpiAlarm",
-      requestType = monitoring.Monitoring.AlarmDescriptor.class,
-      responseType = context.ContextOuterClass.Empty.class,
-      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor,
-      context.ContextOuterClass.Empty> getEditKpiAlarmMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmDescriptor, context.ContextOuterClass.Empty> getEditKpiAlarmMethod;
-    if ((getEditKpiAlarmMethod = MonitoringServiceGrpc.getEditKpiAlarmMethod) == null) {
-      synchronized (MonitoringServiceGrpc.class) {
-        if ((getEditKpiAlarmMethod = MonitoringServiceGrpc.getEditKpiAlarmMethod) == null) {
-          MonitoringServiceGrpc.getEditKpiAlarmMethod = getEditKpiAlarmMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmDescriptor, context.ContextOuterClass.Empty>newBuilder()
-              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "EditKpiAlarm"))
-              .setSampledToLocalTracing(true)
-              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.AlarmDescriptor.getDefaultInstance()))
-              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  context.ContextOuterClass.Empty.getDefaultInstance()))
-              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("EditKpiAlarm"))
-              .build();
-        }
-      }
-    }
-    return getEditKpiAlarmMethod;
+    return getSetKpiAlarmMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
@@ -541,27 +448,27 @@ public final class MonitoringServiceGrpc {
     return getGetAlarmDescriptorMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmSubscription,
       monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
       fullMethodName = SERVICE_NAME + '/' + "GetAlarmResponseStream",
-      requestType = monitoring.Monitoring.AlarmID.class,
+      requestType = monitoring.Monitoring.AlarmSubscription.class,
       responseType = monitoring.Monitoring.AlarmResponse.class,
       methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
-  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmSubscription,
       monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod() {
-    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod;
+    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmSubscription, monitoring.Monitoring.AlarmResponse> getGetAlarmResponseStreamMethod;
     if ((getGetAlarmResponseStreamMethod = MonitoringServiceGrpc.getGetAlarmResponseStreamMethod) == null) {
       synchronized (MonitoringServiceGrpc.class) {
         if ((getGetAlarmResponseStreamMethod = MonitoringServiceGrpc.getGetAlarmResponseStreamMethod) == null) {
           MonitoringServiceGrpc.getGetAlarmResponseStreamMethod = getGetAlarmResponseStreamMethod =
-              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmID, monitoring.Monitoring.AlarmResponse>newBuilder()
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmSubscription, monitoring.Monitoring.AlarmResponse>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
               .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetAlarmResponseStream"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  monitoring.Monitoring.AlarmID.getDefaultInstance()))
+                  monitoring.Monitoring.AlarmSubscription.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   monitoring.Monitoring.AlarmResponse.getDefaultInstance()))
               .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetAlarmResponseStream"))
@@ -572,6 +479,99 @@ public final class MonitoringServiceGrpc {
     return getGetAlarmResponseStreamMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+      context.ContextOuterClass.Empty> getDeleteAlarmMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "DeleteAlarm",
+      requestType = monitoring.Monitoring.AlarmID.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID,
+      context.ContextOuterClass.Empty> getDeleteAlarmMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.AlarmID, context.ContextOuterClass.Empty> getDeleteAlarmMethod;
+    if ((getDeleteAlarmMethod = MonitoringServiceGrpc.getDeleteAlarmMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getDeleteAlarmMethod = MonitoringServiceGrpc.getDeleteAlarmMethod) == null) {
+          MonitoringServiceGrpc.getDeleteAlarmMethod = getDeleteAlarmMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.AlarmID, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteAlarm"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.AlarmID.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("DeleteAlarm"))
+              .build();
+        }
+      }
+    }
+    return getDeleteAlarmMethod;
+  }
+
+  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.KpiList> getGetInstantKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetInstantKpi",
+      requestType = monitoring.Monitoring.KpiId.class,
+      responseType = monitoring.Monitoring.KpiList.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.KpiList> getGetInstantKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiList> 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.KpiList>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.KpiList.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetInstantKpi"))
+              .build();
+        }
+      }
+    }
+    return getGetInstantKpiMethod;
+  }
+
   /**
    * Creates a new async stub that supports all call types for the service
    */
@@ -622,23 +622,23 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void createKpi(monitoring.Monitoring.KpiDescriptor request,
+    public void setKpi(monitoring.Monitoring.KpiDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateKpiMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetKpiMethod(), responseObserver);
     }
 
     /**
      */
-    public void editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request,
+    public void deleteKpi(monitoring.Monitoring.KpiId request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEditKpiDescriptorMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteKpiMethod(), responseObserver);
     }
 
     /**
      */
-    public void deleteKpi(monitoring.Monitoring.KpiId request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteKpiMethod(), responseObserver);
+    public void getKpiDescriptor(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetKpiDescriptorMethod(), responseObserver);
     }
 
     /**
@@ -648,20 +648,6 @@ public final class MonitoringServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetKpiDescriptorListMethod(), responseObserver);
     }
 
-    /**
-     */
-    public void createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request,
-        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateBundleKpiMethod(), 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,
@@ -685,9 +671,9 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void subscribeKpi(monitoring.Monitoring.SubsDescriptor request,
+    public void setKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSubscribeKpiMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetKpiSubscriptionMethod(), responseObserver);
     }
 
     /**
@@ -706,23 +692,16 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void editKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
+    public void deleteSubscription(monitoring.Monitoring.SubscriptionID request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEditKpiSubscriptionMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteSubscriptionMethod(), responseObserver);
     }
 
     /**
      */
-    public void createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
+    public void setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateKpiAlarmMethod(), responseObserver);
-    }
-
-    /**
-     */
-    public void editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEditKpiAlarmMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetKpiAlarmMethod(), responseObserver);
     }
 
     /**
@@ -741,34 +720,55 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void getAlarmResponseStream(monitoring.Monitoring.AlarmID request,
+    public void getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse> responseObserver) {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetAlarmResponseStreamMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void deleteAlarm(monitoring.Monitoring.AlarmID request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteAlarmMethod(), 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.KpiList> 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(),
+            getSetKpiMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 monitoring.Monitoring.KpiDescriptor,
                 monitoring.Monitoring.KpiId>(
-                  this, METHODID_CREATE_KPI)))
+                  this, METHODID_SET_KPI)))
           .addMethod(
-            getEditKpiDescriptorMethod(),
+            getDeleteKpiMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                monitoring.Monitoring.EditedKpiDescriptor,
+                monitoring.Monitoring.KpiId,
                 context.ContextOuterClass.Empty>(
-                  this, METHODID_EDIT_KPI_DESCRIPTOR)))
+                  this, METHODID_DELETE_KPI)))
           .addMethod(
-            getDeleteKpiMethod(),
+            getGetKpiDescriptorMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 monitoring.Monitoring.KpiId,
-                context.ContextOuterClass.Empty>(
-                  this, METHODID_DELETE_KPI)))
+                monitoring.Monitoring.KpiDescriptor>(
+                  this, METHODID_GET_KPI_DESCRIPTOR)))
           .addMethod(
             getGetKpiDescriptorListMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -776,20 +776,6 @@ public final class MonitoringServiceGrpc {
                 context.ContextOuterClass.Empty,
                 monitoring.Monitoring.KpiDescriptorList>(
                   this, METHODID_GET_KPI_DESCRIPTOR_LIST)))
-          .addMethod(
-            getCreateBundleKpiMethod(),
-            io.grpc.stub.ServerCalls.asyncUnaryCall(
-              new MethodHandlers<
-                monitoring.Monitoring.BundleKpiDescriptor,
-                monitoring.Monitoring.KpiId>(
-                  this, METHODID_CREATE_BUNDLE_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(
@@ -812,12 +798,12 @@ public final class MonitoringServiceGrpc {
                 monitoring.Monitoring.KpiList>(
                   this, METHODID_QUERY_KPI_DATA)))
           .addMethod(
-            getSubscribeKpiMethod(),
+            getSetKpiSubscriptionMethod(),
             io.grpc.stub.ServerCalls.asyncServerStreamingCall(
               new MethodHandlers<
                 monitoring.Monitoring.SubsDescriptor,
                 monitoring.Monitoring.KpiList>(
-                  this, METHODID_SUBSCRIBE_KPI)))
+                  this, METHODID_SET_KPI_SUBSCRIPTION)))
           .addMethod(
             getGetSubsDescriptorMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -833,26 +819,19 @@ public final class MonitoringServiceGrpc {
                 monitoring.Monitoring.SubsIDList>(
                   this, METHODID_GET_SUBSCRIPTIONS)))
           .addMethod(
-            getEditKpiSubscriptionMethod(),
+            getDeleteSubscriptionMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                monitoring.Monitoring.SubsDescriptor,
+                monitoring.Monitoring.SubscriptionID,
                 context.ContextOuterClass.Empty>(
-                  this, METHODID_EDIT_KPI_SUBSCRIPTION)))
+                  this, METHODID_DELETE_SUBSCRIPTION)))
           .addMethod(
-            getCreateKpiAlarmMethod(),
+            getSetKpiAlarmMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 monitoring.Monitoring.AlarmDescriptor,
                 monitoring.Monitoring.AlarmID>(
-                  this, METHODID_CREATE_KPI_ALARM)))
-          .addMethod(
-            getEditKpiAlarmMethod(),
-            io.grpc.stub.ServerCalls.asyncUnaryCall(
-              new MethodHandlers<
-                monitoring.Monitoring.AlarmDescriptor,
-                context.ContextOuterClass.Empty>(
-                  this, METHODID_EDIT_KPI_ALARM)))
+                  this, METHODID_SET_KPI_ALARM)))
           .addMethod(
             getGetAlarmsMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -871,9 +850,30 @@ public final class MonitoringServiceGrpc {
             getGetAlarmResponseStreamMethod(),
             io.grpc.stub.ServerCalls.asyncServerStreamingCall(
               new MethodHandlers<
-                monitoring.Monitoring.AlarmID,
+                monitoring.Monitoring.AlarmSubscription,
                 monitoring.Monitoring.AlarmResponse>(
                   this, METHODID_GET_ALARM_RESPONSE_STREAM)))
+          .addMethod(
+            getDeleteAlarmMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.AlarmID,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_DELETE_ALARM)))
+          .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.KpiList>(
+                  this, METHODID_GET_INSTANT_KPI)))
           .build();
     }
   }
@@ -894,26 +894,26 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void createKpi(monitoring.Monitoring.KpiDescriptor request,
+    public void setKpi(monitoring.Monitoring.KpiDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getCreateKpiMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getSetKpiMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request,
+    public void deleteKpi(monitoring.Monitoring.KpiId request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getEditKpiDescriptorMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void deleteKpi(monitoring.Monitoring.KpiId request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+    public void getKpiDescriptor(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getGetKpiDescriptorMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
@@ -924,22 +924,6 @@ public final class MonitoringServiceGrpc {
           getChannel().newCall(getGetKpiDescriptorListMethod(), getCallOptions()), request, responseObserver);
     }
 
-    /**
-     */
-    public void createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request,
-        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
-      io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getCreateBundleKpiMethod(), 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,
@@ -966,10 +950,10 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void subscribeKpi(monitoring.Monitoring.SubsDescriptor request,
+    public void setKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList> responseObserver) {
       io.grpc.stub.ClientCalls.asyncServerStreamingCall(
-          getChannel().newCall(getSubscribeKpiMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getSetKpiSubscriptionMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
@@ -990,26 +974,18 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void editKpiSubscription(monitoring.Monitoring.SubsDescriptor request,
+    public void deleteSubscription(monitoring.Monitoring.SubscriptionID request,
         io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getEditKpiSubscriptionMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getDeleteSubscriptionMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
+    public void setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getCreateKpiAlarmMethod(), getCallOptions()), request, responseObserver);
-    }
-
-    /**
-     */
-    public void editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request,
-        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
-      io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getEditKpiAlarmMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getSetKpiAlarmMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
@@ -1030,11 +1006,35 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public void getAlarmResponseStream(monitoring.Monitoring.AlarmID request,
+    public void getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request,
         io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse> responseObserver) {
       io.grpc.stub.ClientCalls.asyncServerStreamingCall(
           getChannel().newCall(getGetAlarmResponseStreamMethod(), getCallOptions()), request, responseObserver);
     }
+
+    /**
+     */
+    public void deleteAlarm(monitoring.Monitoring.AlarmID request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getDeleteAlarmMethod(), 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.KpiList> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getGetInstantKpiMethod(), getCallOptions()), request, responseObserver);
+    }
   }
 
   /**
@@ -1053,16 +1053,9 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public monitoring.Monitoring.KpiId createKpi(monitoring.Monitoring.KpiDescriptor request) {
+    public monitoring.Monitoring.KpiId setKpi(monitoring.Monitoring.KpiDescriptor request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getCreateKpiMethod(), getCallOptions(), request);
-    }
-
-    /**
-     */
-    public context.ContextOuterClass.Empty editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
-      return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getEditKpiDescriptorMethod(), getCallOptions(), request);
+          getChannel(), getSetKpiMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1074,23 +1067,16 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public monitoring.Monitoring.KpiDescriptorList getKpiDescriptorList(context.ContextOuterClass.Empty request) {
-      return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getGetKpiDescriptorListMethod(), getCallOptions(), request);
-    }
-
-    /**
-     */
-    public monitoring.Monitoring.KpiId createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
+    public monitoring.Monitoring.KpiDescriptor getKpiDescriptor(monitoring.Monitoring.KpiId request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getCreateBundleKpiMethod(), getCallOptions(), request);
+          getChannel(), getGetKpiDescriptorMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public monitoring.Monitoring.KpiDescriptor getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+    public monitoring.Monitoring.KpiDescriptorList getKpiDescriptorList(context.ContextOuterClass.Empty request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getGetKpiDescriptorMethod(), getCallOptions(), request);
+          getChannel(), getGetKpiDescriptorListMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1116,10 +1102,10 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public java.util.Iterator<monitoring.Monitoring.KpiList> subscribeKpi(
+    public java.util.Iterator<monitoring.Monitoring.KpiList> setKpiSubscription(
         monitoring.Monitoring.SubsDescriptor request) {
       return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
-          getChannel(), getSubscribeKpiMethod(), getCallOptions(), request);
+          getChannel(), getSetKpiSubscriptionMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1138,23 +1124,16 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public context.ContextOuterClass.Empty editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+    public context.ContextOuterClass.Empty deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getEditKpiSubscriptionMethod(), getCallOptions(), request);
+          getChannel(), getDeleteSubscriptionMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public monitoring.Monitoring.AlarmID createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+    public monitoring.Monitoring.AlarmID setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getCreateKpiAlarmMethod(), getCallOptions(), request);
-    }
-
-    /**
-     */
-    public context.ContextOuterClass.Empty editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-      return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getEditKpiAlarmMethod(), getCallOptions(), request);
+          getChannel(), getSetKpiAlarmMethod(), getCallOptions(), request);
     }
 
     /**
@@ -1174,10 +1153,32 @@ public final class MonitoringServiceGrpc {
     /**
      */
     public java.util.Iterator<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(
-        monitoring.Monitoring.AlarmID request) {
+        monitoring.Monitoring.AlarmSubscription request) {
       return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
           getChannel(), getGetAlarmResponseStreamMethod(), getCallOptions(), request);
     }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty deleteAlarm(monitoring.Monitoring.AlarmID request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getDeleteAlarmMethod(), 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.KpiList getInstantKpi(monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getGetInstantKpiMethod(), getCallOptions(), request);
+    }
   }
 
   /**
@@ -1196,26 +1197,26 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> createKpi(
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> setKpi(
         monitoring.Monitoring.KpiDescriptor request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getCreateKpiMethod(), getCallOptions()), request);
+          getChannel().newCall(getSetKpiMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> editKpiDescriptor(
-        monitoring.Monitoring.EditedKpiDescriptor request) {
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteKpi(
+        monitoring.Monitoring.KpiId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getEditKpiDescriptorMethod(), getCallOptions()), request);
+          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteKpi(
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(
         monitoring.Monitoring.KpiId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getDeleteKpiMethod(), getCallOptions()), request);
+          getChannel().newCall(getGetKpiDescriptorMethod(), getCallOptions()), request);
     }
 
     /**
@@ -1226,22 +1227,6 @@ public final class MonitoringServiceGrpc {
           getChannel().newCall(getGetKpiDescriptorListMethod(), getCallOptions()), request);
     }
 
-    /**
-     */
-    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> createBundleKpi(
-        monitoring.Monitoring.BundleKpiDescriptor request) {
-      return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getCreateBundleKpiMethod(), 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(
@@ -1284,26 +1269,18 @@ public final class MonitoringServiceGrpc {
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> editKpiSubscription(
-        monitoring.Monitoring.SubsDescriptor request) {
-      return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getEditKpiSubscriptionMethod(), getCallOptions()), request);
-    }
-
-    /**
-     */
-    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.AlarmID> createKpiAlarm(
-        monitoring.Monitoring.AlarmDescriptor request) {
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteSubscription(
+        monitoring.Monitoring.SubscriptionID request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getCreateKpiAlarmMethod(), getCallOptions()), request);
+          getChannel().newCall(getDeleteSubscriptionMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> editKpiAlarm(
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.AlarmID> setKpiAlarm(
         monitoring.Monitoring.AlarmDescriptor request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getEditKpiAlarmMethod(), getCallOptions()), request);
+          getChannel().newCall(getSetKpiAlarmMethod(), getCallOptions()), request);
     }
 
     /**
@@ -1321,26 +1298,42 @@ public final class MonitoringServiceGrpc {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
           getChannel().newCall(getGetAlarmDescriptorMethod(), getCallOptions()), request);
     }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteAlarm(
+        monitoring.Monitoring.AlarmID request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getDeleteAlarmMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiList> 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_EDIT_KPI_DESCRIPTOR = 1;
-  private static final int METHODID_DELETE_KPI = 2;
+  private static final int METHODID_SET_KPI = 0;
+  private static final int METHODID_DELETE_KPI = 1;
+  private static final int METHODID_GET_KPI_DESCRIPTOR = 2;
   private static final int METHODID_GET_KPI_DESCRIPTOR_LIST = 3;
-  private static final int METHODID_CREATE_BUNDLE_KPI = 4;
-  private static final int METHODID_GET_KPI_DESCRIPTOR = 5;
-  private static final int METHODID_INCLUDE_KPI = 6;
-  private static final int METHODID_MONITOR_KPI = 7;
-  private static final int METHODID_QUERY_KPI_DATA = 8;
-  private static final int METHODID_SUBSCRIBE_KPI = 9;
-  private static final int METHODID_GET_SUBS_DESCRIPTOR = 10;
-  private static final int METHODID_GET_SUBSCRIPTIONS = 11;
-  private static final int METHODID_EDIT_KPI_SUBSCRIPTION = 12;
-  private static final int METHODID_CREATE_KPI_ALARM = 13;
-  private static final int METHODID_EDIT_KPI_ALARM = 14;
-  private static final int METHODID_GET_ALARMS = 15;
-  private static final int METHODID_GET_ALARM_DESCRIPTOR = 16;
-  private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 17;
+  private static final int METHODID_INCLUDE_KPI = 4;
+  private static final int METHODID_MONITOR_KPI = 5;
+  private static final int METHODID_QUERY_KPI_DATA = 6;
+  private static final int METHODID_SET_KPI_SUBSCRIPTION = 7;
+  private static final int METHODID_GET_SUBS_DESCRIPTOR = 8;
+  private static final int METHODID_GET_SUBSCRIPTIONS = 9;
+  private static final int METHODID_DELETE_SUBSCRIPTION = 10;
+  private static final int METHODID_SET_KPI_ALARM = 11;
+  private static final int METHODID_GET_ALARMS = 12;
+  private static final int METHODID_GET_ALARM_DESCRIPTOR = 13;
+  private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 14;
+  private static final int METHODID_DELETE_ALARM = 15;
+  private static final int METHODID_GET_STREAM_KPI = 16;
+  private static final int METHODID_GET_INSTANT_KPI = 17;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -1359,30 +1352,22 @@ public final class MonitoringServiceGrpc {
     @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,
+        case METHODID_SET_KPI:
+          serviceImpl.setKpi((monitoring.Monitoring.KpiDescriptor) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId>) responseObserver);
           break;
-        case METHODID_EDIT_KPI_DESCRIPTOR:
-          serviceImpl.editKpiDescriptor((monitoring.Monitoring.EditedKpiDescriptor) request,
-              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
-          break;
         case METHODID_DELETE_KPI:
           serviceImpl.deleteKpi((monitoring.Monitoring.KpiId) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
           break;
-        case METHODID_GET_KPI_DESCRIPTOR_LIST:
-          serviceImpl.getKpiDescriptorList((context.ContextOuterClass.Empty) request,
-              (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver);
-          break;
-        case METHODID_CREATE_BUNDLE_KPI:
-          serviceImpl.createBundleKpi((monitoring.Monitoring.BundleKpiDescriptor) 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_GET_KPI_DESCRIPTOR_LIST:
+          serviceImpl.getKpiDescriptorList((context.ContextOuterClass.Empty) request,
+              (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver);
+          break;
         case METHODID_INCLUDE_KPI:
           serviceImpl.includeKpi((monitoring.Monitoring.Kpi) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
@@ -1395,8 +1380,8 @@ public final class MonitoringServiceGrpc {
           serviceImpl.queryKpiData((monitoring.Monitoring.KpiQuery) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList>) responseObserver);
           break;
-        case METHODID_SUBSCRIBE_KPI:
-          serviceImpl.subscribeKpi((monitoring.Monitoring.SubsDescriptor) request,
+        case METHODID_SET_KPI_SUBSCRIPTION:
+          serviceImpl.setKpiSubscription((monitoring.Monitoring.SubsDescriptor) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList>) responseObserver);
           break;
         case METHODID_GET_SUBS_DESCRIPTOR:
@@ -1407,18 +1392,14 @@ public final class MonitoringServiceGrpc {
           serviceImpl.getSubscriptions((context.ContextOuterClass.Empty) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.SubsIDList>) responseObserver);
           break;
-        case METHODID_EDIT_KPI_SUBSCRIPTION:
-          serviceImpl.editKpiSubscription((monitoring.Monitoring.SubsDescriptor) request,
+        case METHODID_DELETE_SUBSCRIPTION:
+          serviceImpl.deleteSubscription((monitoring.Monitoring.SubscriptionID) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
           break;
-        case METHODID_CREATE_KPI_ALARM:
-          serviceImpl.createKpiAlarm((monitoring.Monitoring.AlarmDescriptor) request,
+        case METHODID_SET_KPI_ALARM:
+          serviceImpl.setKpiAlarm((monitoring.Monitoring.AlarmDescriptor) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID>) responseObserver);
           break;
-        case METHODID_EDIT_KPI_ALARM:
-          serviceImpl.editKpiAlarm((monitoring.Monitoring.AlarmDescriptor) request,
-              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
-          break;
         case METHODID_GET_ALARMS:
           serviceImpl.getAlarms((context.ContextOuterClass.Empty) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmIDList>) responseObserver);
@@ -1428,9 +1409,21 @@ public final class MonitoringServiceGrpc {
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmDescriptor>) responseObserver);
           break;
         case METHODID_GET_ALARM_RESPONSE_STREAM:
-          serviceImpl.getAlarmResponseStream((monitoring.Monitoring.AlarmID) request,
+          serviceImpl.getAlarmResponseStream((monitoring.Monitoring.AlarmSubscription) request,
               (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse>) responseObserver);
           break;
+        case METHODID_DELETE_ALARM:
+          serviceImpl.deleteAlarm((monitoring.Monitoring.AlarmID) 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.KpiList>) responseObserver);
+          break;
         default:
           throw new AssertionError();
       }
@@ -1492,24 +1485,24 @@ public final class MonitoringServiceGrpc {
         if (result == null) {
           serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
               .setSchemaDescriptor(new MonitoringServiceFileDescriptorSupplier())
-              .addMethod(getCreateKpiMethod())
-              .addMethod(getEditKpiDescriptorMethod())
+              .addMethod(getSetKpiMethod())
               .addMethod(getDeleteKpiMethod())
-              .addMethod(getGetKpiDescriptorListMethod())
-              .addMethod(getCreateBundleKpiMethod())
               .addMethod(getGetKpiDescriptorMethod())
+              .addMethod(getGetKpiDescriptorListMethod())
               .addMethod(getIncludeKpiMethod())
               .addMethod(getMonitorKpiMethod())
               .addMethod(getQueryKpiDataMethod())
-              .addMethod(getSubscribeKpiMethod())
+              .addMethod(getSetKpiSubscriptionMethod())
               .addMethod(getGetSubsDescriptorMethod())
               .addMethod(getGetSubscriptionsMethod())
-              .addMethod(getEditKpiSubscriptionMethod())
-              .addMethod(getCreateKpiAlarmMethod())
-              .addMethod(getEditKpiAlarmMethod())
+              .addMethod(getDeleteSubscriptionMethod())
+              .addMethod(getSetKpiAlarmMethod())
               .addMethod(getGetAlarmsMethod())
               .addMethod(getGetAlarmDescriptorMethod())
               .addMethod(getGetAlarmResponseStreamMethod())
+              .addMethod(getDeleteAlarmMethod())
+              .addMethod(getGetStreamKpiMethod())
+              .addMethod(getGetInstantKpiMethod())
               .build();
         }
       }
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java b/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
index 46f442b743ee176a83a416fe13711beda6baf937..d663b38c923a2b5401642db4e697e16be4720f05 100644
--- a/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
@@ -36,13 +36,8 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        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<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::editKpiDescriptor);
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::setKpi);
         }
 
         
@@ -51,18 +46,13 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptorList);
-        }
-
-        
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::createBundleKpi);
+        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<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptor);
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptorList> getKpiDescriptorList(context.ContextOuterClass.Empty request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptorList);
         }
 
         
@@ -91,18 +81,13 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::editKpiSubscription);
-        }
-
-        
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::createKpiAlarm);
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::deleteSubscription);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::editKpiAlarm);
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::setKpiAlarm);
         }
 
         
@@ -116,15 +101,30 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::subscribeKpi);
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::deleteAlarm);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getInstantKpi);
+        }
+
+        
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::setKpiSubscription);
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getAlarmResponseStream);
         }
 
+        
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getStreamKpi);
+        }
+
     }
 
     
@@ -143,17 +143,17 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
 
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> setKpi(monitoring.Monitoring.KpiDescriptor request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiDescriptor(monitoring.Monitoring.EditedKpiDescriptor request) {
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteKpi(monitoring.Monitoring.KpiId request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
@@ -163,98 +163,98 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createBundleKpi(monitoring.Monitoring.BundleKpiDescriptor request) {
+        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<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+        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<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> queryKpiData(monitoring.Monitoring.KpiQuery request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsDescriptor> getSubsDescriptor(monitoring.Monitoring.SubscriptionID request) {
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteSubscription(monitoring.Monitoring.SubscriptionID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.SubsIDList> getSubscriptions(context.ContextOuterClass.Empty request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> setKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmID> createKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> editKpiAlarm(monitoring.Monitoring.AlarmDescriptor request) {
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteAlarm(monitoring.Monitoring.AlarmID request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmIDList> getAlarms(context.ContextOuterClass.Empty request) {
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiList> getInstantKpi(monitoring.Monitoring.KpiId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<monitoring.Monitoring.AlarmDescriptor> getAlarmDescriptor(monitoring.Monitoring.AlarmID request) {
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> setKpiSubscription(monitoring.Monitoring.SubsDescriptor request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.KpiList> subscribeKpi(monitoring.Monitoring.SubsDescriptor request) {
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmSubscription request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Multi<monitoring.Monitoring.AlarmResponse> getAlarmResponseStream(monitoring.Monitoring.AlarmID request) {
+        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(),
+                            monitoring.MonitoringServiceGrpc.getSetKpiMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.KpiDescriptor,
                                             monitoring.Monitoring.KpiId>(
-                                            this, METHODID_CREATE_KPI, compression)))
+                                            this, METHODID_SET_KPI, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getEditKpiDescriptorMethod(),
+                            monitoring.MonitoringServiceGrpc.getDeleteKpiMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            monitoring.Monitoring.EditedKpiDescriptor,
+                                            monitoring.Monitoring.KpiId,
                                             context.ContextOuterClass.Empty>(
-                                            this, METHODID_EDIT_KPI_DESCRIPTOR, compression)))
+                                            this, METHODID_DELETE_KPI, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getDeleteKpiMethod(),
+                            monitoring.MonitoringServiceGrpc.getGetKpiDescriptorMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.KpiId,
-                                            context.ContextOuterClass.Empty>(
-                                            this, METHODID_DELETE_KPI, compression)))
+                                            monitoring.Monitoring.KpiDescriptor>(
+                                            this, METHODID_GET_KPI_DESCRIPTOR, compression)))
                     .addMethod(
                             monitoring.MonitoringServiceGrpc.getGetKpiDescriptorListMethod(),
                             asyncUnaryCall(
@@ -262,20 +262,6 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                                             context.ContextOuterClass.Empty,
                                             monitoring.Monitoring.KpiDescriptorList>(
                                             this, METHODID_GET_KPI_DESCRIPTOR_LIST, compression)))
-                    .addMethod(
-                            monitoring.MonitoringServiceGrpc.getCreateBundleKpiMethod(),
-                            asyncUnaryCall(
-                                    new MethodHandlers<
-                                            monitoring.Monitoring.BundleKpiDescriptor,
-                                            monitoring.Monitoring.KpiId>(
-                                            this, METHODID_CREATE_BUNDLE_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(
@@ -298,12 +284,12 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                                             monitoring.Monitoring.KpiList>(
                                             this, METHODID_QUERY_KPI_DATA, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getSubscribeKpiMethod(),
+                            monitoring.MonitoringServiceGrpc.getSetKpiSubscriptionMethod(),
                             asyncServerStreamingCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.SubsDescriptor,
                                             monitoring.Monitoring.KpiList>(
-                                            this, METHODID_SUBSCRIBE_KPI, compression)))
+                                            this, METHODID_SET_KPI_SUBSCRIPTION, compression)))
                     .addMethod(
                             monitoring.MonitoringServiceGrpc.getGetSubsDescriptorMethod(),
                             asyncUnaryCall(
@@ -319,26 +305,19 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                                             monitoring.Monitoring.SubsIDList>(
                                             this, METHODID_GET_SUBSCRIPTIONS, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getEditKpiSubscriptionMethod(),
+                            monitoring.MonitoringServiceGrpc.getDeleteSubscriptionMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            monitoring.Monitoring.SubsDescriptor,
+                                            monitoring.Monitoring.SubscriptionID,
                                             context.ContextOuterClass.Empty>(
-                                            this, METHODID_EDIT_KPI_SUBSCRIPTION, compression)))
+                                            this, METHODID_DELETE_SUBSCRIPTION, compression)))
                     .addMethod(
-                            monitoring.MonitoringServiceGrpc.getCreateKpiAlarmMethod(),
+                            monitoring.MonitoringServiceGrpc.getSetKpiAlarmMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             monitoring.Monitoring.AlarmDescriptor,
                                             monitoring.Monitoring.AlarmID>(
-                                            this, METHODID_CREATE_KPI_ALARM, compression)))
-                    .addMethod(
-                            monitoring.MonitoringServiceGrpc.getEditKpiAlarmMethod(),
-                            asyncUnaryCall(
-                                    new MethodHandlers<
-                                            monitoring.Monitoring.AlarmDescriptor,
-                                            context.ContextOuterClass.Empty>(
-                                            this, METHODID_EDIT_KPI_ALARM, compression)))
+                                            this, METHODID_SET_KPI_ALARM, compression)))
                     .addMethod(
                             monitoring.MonitoringServiceGrpc.getGetAlarmsMethod(),
                             asyncUnaryCall(
@@ -357,31 +336,52 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             monitoring.MonitoringServiceGrpc.getGetAlarmResponseStreamMethod(),
                             asyncServerStreamingCall(
                                     new MethodHandlers<
-                                            monitoring.Monitoring.AlarmID,
+                                            monitoring.Monitoring.AlarmSubscription,
                                             monitoring.Monitoring.AlarmResponse>(
                                             this, METHODID_GET_ALARM_RESPONSE_STREAM, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getDeleteAlarmMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.AlarmID,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_DELETE_ALARM, 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.KpiList>(
+                                            this, METHODID_GET_INSTANT_KPI, compression)))
                     .build();
         }
     }
 
-    private static final int METHODID_CREATE_KPI = 0;
-    private static final int METHODID_EDIT_KPI_DESCRIPTOR = 1;
-    private static final int METHODID_DELETE_KPI = 2;
+    private static final int METHODID_SET_KPI = 0;
+    private static final int METHODID_DELETE_KPI = 1;
+    private static final int METHODID_GET_KPI_DESCRIPTOR = 2;
     private static final int METHODID_GET_KPI_DESCRIPTOR_LIST = 3;
-    private static final int METHODID_CREATE_BUNDLE_KPI = 4;
-    private static final int METHODID_GET_KPI_DESCRIPTOR = 5;
-    private static final int METHODID_INCLUDE_KPI = 6;
-    private static final int METHODID_MONITOR_KPI = 7;
-    private static final int METHODID_QUERY_KPI_DATA = 8;
-    private static final int METHODID_SUBSCRIBE_KPI = 9;
-    private static final int METHODID_GET_SUBS_DESCRIPTOR = 10;
-    private static final int METHODID_GET_SUBSCRIPTIONS = 11;
-    private static final int METHODID_EDIT_KPI_SUBSCRIPTION = 12;
-    private static final int METHODID_CREATE_KPI_ALARM = 13;
-    private static final int METHODID_EDIT_KPI_ALARM = 14;
-    private static final int METHODID_GET_ALARMS = 15;
-    private static final int METHODID_GET_ALARM_DESCRIPTOR = 16;
-    private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 17;
+    private static final int METHODID_INCLUDE_KPI = 4;
+    private static final int METHODID_MONITOR_KPI = 5;
+    private static final int METHODID_QUERY_KPI_DATA = 6;
+    private static final int METHODID_SET_KPI_SUBSCRIPTION = 7;
+    private static final int METHODID_GET_SUBS_DESCRIPTOR = 8;
+    private static final int METHODID_GET_SUBSCRIPTIONS = 9;
+    private static final int METHODID_DELETE_SUBSCRIPTION = 10;
+    private static final int METHODID_SET_KPI_ALARM = 11;
+    private static final int METHODID_GET_ALARMS = 12;
+    private static final int METHODID_GET_ALARM_DESCRIPTOR = 13;
+    private static final int METHODID_GET_ALARM_RESPONSE_STREAM = 14;
+    private static final int METHODID_DELETE_ALARM = 15;
+    private static final int METHODID_GET_STREAM_KPI = 16;
+    private static final int METHODID_GET_INSTANT_KPI = 17;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -402,17 +402,11 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
         @java.lang.SuppressWarnings("unchecked")
         public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
             switch (methodId) {
-                case METHODID_CREATE_KPI:
+                case METHODID_SET_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_EDIT_KPI_DESCRIPTOR:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.EditedKpiDescriptor) request,
-                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
-                            compression,
-                            serviceImpl::editKpiDescriptor);
+                            serviceImpl::setKpi);
                     break;
                 case METHODID_DELETE_KPI:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.KpiId) request,
@@ -420,24 +414,18 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::deleteKpi);
                     break;
-                case METHODID_GET_KPI_DESCRIPTOR_LIST:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Empty) request,
-                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver,
-                            compression,
-                            serviceImpl::getKpiDescriptorList);
-                    break;
-                case METHODID_CREATE_BUNDLE_KPI:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.BundleKpiDescriptor) request,
-                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId>) responseObserver,
-                            compression,
-                            serviceImpl::createBundleKpi);
-                    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_GET_KPI_DESCRIPTOR_LIST:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Empty) request,
+                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptorList>) responseObserver,
+                            compression,
+                            serviceImpl::getKpiDescriptorList);
+                    break;
                 case METHODID_INCLUDE_KPI:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.Kpi) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
@@ -456,11 +444,11 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::queryKpiData);
                     break;
-                case METHODID_SUBSCRIBE_KPI:
+                case METHODID_SET_KPI_SUBSCRIPTION:
                     io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.SubsDescriptor) request,
                             (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiList>) responseObserver,
                             compression,
-                            serviceImpl::subscribeKpi);
+                            serviceImpl::setKpiSubscription);
                     break;
                 case METHODID_GET_SUBS_DESCRIPTOR:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.SubscriptionID) request,
@@ -474,23 +462,17 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::getSubscriptions);
                     break;
-                case METHODID_EDIT_KPI_SUBSCRIPTION:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.SubsDescriptor) request,
+                case METHODID_DELETE_SUBSCRIPTION:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.SubscriptionID) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
                             compression,
-                            serviceImpl::editKpiSubscription);
+                            serviceImpl::deleteSubscription);
                     break;
-                case METHODID_CREATE_KPI_ALARM:
+                case METHODID_SET_KPI_ALARM:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.AlarmDescriptor) request,
                             (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmID>) responseObserver,
                             compression,
-                            serviceImpl::createKpiAlarm);
-                    break;
-                case METHODID_EDIT_KPI_ALARM:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.AlarmDescriptor) request,
-                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
-                            compression,
-                            serviceImpl::editKpiAlarm);
+                            serviceImpl::setKpiAlarm);
                     break;
                 case METHODID_GET_ALARMS:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Empty) request,
@@ -505,11 +487,29 @@ public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtim
                             serviceImpl::getAlarmDescriptor);
                     break;
                 case METHODID_GET_ALARM_RESPONSE_STREAM:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.AlarmID) request,
+                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.AlarmSubscription) request,
                             (io.grpc.stub.StreamObserver<monitoring.Monitoring.AlarmResponse>) responseObserver,
                             compression,
                             serviceImpl::getAlarmResponseStream);
                     break;
+                case METHODID_DELETE_ALARM:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.AlarmID) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::deleteAlarm);
+                    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.KpiList>) responseObserver,
+                            compression,
+                            serviceImpl::getInstantKpi);
+                    break;
                 default:
                     throw new java.lang.AssertionError();
             }
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
deleted file mode 100644
index 680929bc031df90594a743eb96316d3c99508cef..0000000000000000000000000000000000000000
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ /dev/null
@@ -1,89 +0,0 @@
----
-apiVersion: v1
-kind: Service
-metadata:
-  annotations:
-    app.quarkus.io/commit-id: 7d24cfdf286fcca1ff04620ee026933bedd8960e
-    app.quarkus.io/build-timestamp: 2022-08-04 - 22:13:18 +0000
-  labels:
-    app.kubernetes.io/name: policyservice
-    app: policyservice
-  name: policyservice
-spec:
-  ports:
-    - name: http
-      port: 8080
-      targetPort: 8080
-    - name: grpc
-      port: 6060
-      targetPort: 6060
-  selector:
-    app.kubernetes.io/name: policyservice
-  type: ClusterIP
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  annotations:
-    app.quarkus.io/commit-id: 7d24cfdf286fcca1ff04620ee026933bedd8960e
-    app.quarkus.io/build-timestamp: 2022-08-04 - 22:13:18 +0000
-  labels:
-    app: policyservice
-    app.kubernetes.io/name: policyservice
-  name: policyservice
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app.kubernetes.io/name: policyservice
-  template:
-    metadata:
-      annotations:
-        app.quarkus.io/commit-id: 7d24cfdf286fcca1ff04620ee026933bedd8960e
-        app.quarkus.io/build-timestamp: 2022-08-04 - 22:13:18 +0000
-      labels:
-        app: policyservice
-        app.kubernetes.io/name: policyservice
-    spec:
-      containers:
-        - env:
-            - name: KUBERNETES_NAMESPACE
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.namespace
-            - 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
-          imagePullPolicy: Always
-          livenessProbe:
-            failureThreshold: 3
-            httpGet:
-              path: /q/health/live
-              port: 8080
-              scheme: HTTP
-            initialDelaySeconds: 2
-            periodSeconds: 10
-            successThreshold: 1
-            timeoutSeconds: 10
-          name: policyservice
-          ports:
-            - containerPort: 8080
-              name: http
-              protocol: TCP
-            - containerPort: 6060
-              name: grpc
-              protocol: TCP
-          readinessProbe:
-            failureThreshold: 3
-            httpGet:
-              path: /q/health/ready
-              port: 8080
-              scheme: HTTP
-            initialDelaySeconds: 2
-            periodSeconds: 10
-            successThreshold: 1
-            timeoutSeconds: 10
diff --git a/src/service/Dockerfile b/src/service/Dockerfile
index c53a897821b759a8005118ba81a3a0f5c0b73c66..e469898e590b8797e8d3305e1c583caed41bfc80 100644
--- a/src/service/Dockerfile
+++ b/src/service/Dockerfile
@@ -64,6 +64,7 @@ RUN python3 -m pip install -r requirements.txt
 WORKDIR /var/teraflow
 COPY src/context/. context/
 COPY src/device/. device/
+COPY src/pathcomp/frontend/. pathcomp/frontend/
 COPY src/service/. service/
 
 # Start the service
diff --git a/src/service/service/ServiceService.py b/src/service/service/ServiceService.py
index b152376254b52f39c7351eca628165a4a05fac31..2f44fe01894230f84749115ce781178b7d955a36 100644
--- a/src/service/service/ServiceService.py
+++ b/src/service/service/ServiceService.py
@@ -14,9 +14,6 @@
 
 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 common.proto.service_pb2_grpc import add_ServiceServiceServicer_to_server
 from common.tools.service.GenericGrpcService import GenericGrpcService
 from .ServiceServiceServicerImpl import ServiceServiceServicerImpl
@@ -26,8 +23,7 @@ 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)
+        self.service_servicer = ServiceServiceServicerImpl(service_handler_factory)
 
     def install_servicers(self):
         add_ServiceServiceServicer_to_server(self.service_servicer, self.server)
diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py
index 6355cafbef0fc65338269df064a0f56e115b746e..bc71168f621afc9f0a9ed93d51844542beed813c 100644
--- a/src/service/service/ServiceServiceServicerImpl.py
+++ b/src/service/service/ServiceServiceServicerImpl.py
@@ -12,25 +12,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from typing import Dict, List
 import grpc, json, logging
-from common.orm.Database import Database
-from common.orm.HighLevel import get_object
-from common.orm.backend.Tools import key_to_str
-from common.proto.context_pb2 import Empty, Service, ServiceId
+from typing import Optional
+from common.proto.context_pb2 import Empty, Service, ServiceId, ServiceStatusEnum
+from common.proto.pathcomp_pb2 import PathCompRequest
 from common.proto.service_pb2_grpc import ServiceServiceServicer
 from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
-from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException, NotFoundException
+from common.rpc_method_wrapper.ServiceExceptions import AlreadyExistsException, InvalidArgumentException
 from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from service.service.database.DeviceModel import DeviceModel
-from .database.DatabaseServiceTools import (
-    sync_service_from_context, sync_service_to_context, update_service_in_local_database)
-from .database.ServiceModel import ServiceModel
-from .path_computation_element.PathComputationElement import PathComputationElement, dump_connectivity
+from pathcomp.frontend.client.PathCompClient import PathCompClient
+from service.service.tools.ContextGetters import get_service
 from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
-from .Tools import delete_service, sync_devices_from_context, update_service
+from .task_scheduler.TaskScheduler import TasksScheduler
 
 LOGGER = logging.getLogger(__name__)
 
@@ -39,11 +33,8 @@ METHOD_NAMES = ['CreateService', 'UpdateService', 'DeleteService']
 METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
 class ServiceServiceServicerImpl(ServiceServiceServicer):
-    def __init__(self, database : Database, service_handler_factory : ServiceHandlerFactory) -> None:
+    def __init__(self, service_handler_factory : ServiceHandlerFactory) -> None:
         LOGGER.debug('Creating Servicer...')
-        self.context_client = ContextClient()
-        self.device_client = DeviceClient()
-        self.database = database
         self.service_handler_factory = service_handler_factory
         LOGGER.debug('Servicer Created')
 
@@ -84,96 +75,81 @@ class ServiceServiceServicerImpl(ServiceServiceServicer):
                 extra_details='RPC method CreateService does not accept Config Rules. '\
                               'Config Rules should be configured after creating the service.')
 
-        sync_service_from_context(service_context_uuid, service_uuid, self.context_client, self.database)
-        db_service,_ = update_service_in_local_database(self.database, request)
+        # check that service does not exist
+        context_client = ContextClient()
+        current_service = get_service(context_client, request.service_id)
+        if current_service is not None:
+            context_uuid = request.service_id.context_id.context_uuid.uuid
+            service_uuid = request.service_id.service_uuid.uuid
+            raise AlreadyExistsException(
+                'Service', service_uuid, extra_details='context_uuid={:s}'.format(str(context_uuid)))
 
-        LOGGER.info('[CreateService] db_service = {:s}'.format(str(db_service.dump(
-            include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-
-        sync_service_to_context(db_service, self.context_client)
-        return ServiceId(**db_service.dump_id())
+        # just create the service in the Context database to lock the service_id
+        # update will perform changes on the resources
+        service_id = context_client.SetService(request)
+        return service_id
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def UpdateService(self, request : Service, context : grpc.ServicerContext) -> ServiceId:
         LOGGER.info('[UpdateService] 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
-
-        pce = PathComputationElement()
-        pce.load_topology(self.context_client)
-        pce.load_connectivity(self.context_client, service_id)
-        #pce.dump_topology_to_file('../data/topo.dot')
-        #pce.dump_connectivity_to_file('../data/conn-before.txt')
-        connectivity = pce.route_service(request)
-        #pce.dump_connectivity_to_file('../data/conn-after.txt')
-
-        LOGGER.info('[UpdateService] connectivity = {:s}'.format(str(dump_connectivity(connectivity))))
-
-        if connectivity is None:
-            # just update local database and context
-            str_service_key = key_to_str([service_context_uuid, service_uuid])
-            db_service = get_object(self.database, ServiceModel, str_service_key, raise_if_not_found=False)
-            LOGGER.info('[UpdateService] before db_service = {:s}'.format(str(db_service.dump(
-                include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-            db_devices : Dict[str, DeviceModel] = sync_devices_from_context(
-                self.context_client, self.database, db_service, request.service_endpoint_ids)
-            LOGGER.info('[UpdateService] db_devices[{:d}] = {:s}'.format(
-                len(db_devices), str({
-                    device_uuid:db_device.dump(include_config_rules=True, include_drivers=True, include_endpoints=True)
-                    for device_uuid,db_device in db_devices.items()
-                })))
-            sync_service_from_context(service_context_uuid, service_uuid, self.context_client, self.database)
-            db_service,_ = update_service_in_local_database(self.database, request)
-            LOGGER.info('[UpdateService] after db_service = {:s}'.format(str(db_service.dump(
-                include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-            sync_service_to_context(db_service, self.context_client)
-        else:
-            for sub_service, sub_connections in connectivity.get('requirements', []):
-                for sub_connection in sub_connections:
-                    update_service(
-                        self.database, self.context_client, self.device_client, self.service_handler_factory,
-                        sub_service, sub_connection)
-
-            for connection in connectivity.get('connections'):
-                db_service = update_service(
-                    self.database, self.context_client, self.device_client, self.service_handler_factory,
-                    request, connection)
-
-            str_service_key = key_to_str([service_context_uuid, service_uuid])
-            db_service = get_object(self.database, ServiceModel, str_service_key, raise_if_not_found=False)
-            if db_service is None: raise NotFoundException('Service', str_service_key)
-
-        LOGGER.info('[UpdateService] db_service = {:s}'.format(str(db_service.dump(
-            include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-
-        return ServiceId(**db_service.dump_id())
+        # Set service status to "SERVICESTATUS_PLANNED" to ensure rest of components are aware the service is
+        # being modified.
+        context_client = ContextClient()
+        _service : Optional[Service] = get_service(context_client, request.service_id)
+        service = Service()
+        service.CopyFrom(request if _service is None else _service)
+        service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
+        context_client.SetService(service)
+
+        num_disjoint_paths = None
+        for constraint in request.service_constraints:
+            if constraint.WhichOneof('constraint') == 'sla_availability':
+                num_disjoint_paths = constraint.sla_availability.num_disjoint_paths
+                break
+
+        tasks_scheduler = TasksScheduler(self.service_handler_factory)
+        if len(request.service_endpoint_ids) >= (2 if num_disjoint_paths is None else 4):
+            pathcomp_request = PathCompRequest()
+            pathcomp_request.services.append(request)
+
+            if num_disjoint_paths is None:
+                pathcomp_request.shortest_path.Clear()
+            else:
+                pathcomp_request.k_disjoint_path.num_disjoint = num_disjoint_paths
+
+            pathcomp = PathCompClient()
+            LOGGER.info('pathcomp_request={:s}'.format(grpc_message_to_json_string(pathcomp_request)))
+            pathcomp_reply = pathcomp.Compute(pathcomp_request)
+            LOGGER.info('pathcomp_reply={:s}'.format(grpc_message_to_json_string(pathcomp_reply)))
+
+            # Feed TaskScheduler with this path computation reply. TaskScheduler identifies inter-dependencies among
+            # the services and connections retrieved and produces a schedule of tasks (an ordered list of tasks to be
+            # executed) to implement the requested create/update operation.
+            tasks_scheduler.compose_from_pathcompreply(pathcomp_reply, is_delete=False)
+
+        tasks_scheduler.execute_all()
+        return request.service_id
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def DeleteService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty:
         LOGGER.info('[DeleteService] begin ; request = {:s}'.format(grpc_message_to_json_string(request)))
 
-        pce = PathComputationElement()
-        pce.load_topology(self.context_client)
-        pce.load_connectivity(self.context_client, request)
-        #pce.dump_topology_to_file('../data/topo.dot')
-        #pce.dump_connectivity_to_file('../data/conn-before.txt')
-        connectivity = pce.get_connectivity_from_service_id(request)
-        if connectivity is None: return Empty()
-        #pce.dump_connectivity_to_file('../data/conn-after.txt')
-
-        LOGGER.info('[DeleteService] connectivity = {:s}'.format(str(dump_connectivity(connectivity))))
-
-        for connection in connectivity.get('connections'):
-            delete_service(
-                self.database, self.context_client, self.device_client, self.service_handler_factory,
-                request, connection)
-
-        for sub_service, sub_connections in connectivity.get('requirements', []):
-            for sub_connection in sub_connections:
-                delete_service(
-                    self.database, self.context_client, self.device_client, self.service_handler_factory,
-                    sub_service.service_id, sub_connection)
-
+        context_client = ContextClient()
+
+        # Set service status to "SERVICESTATUS_PENDING_REMOVAL" to ensure rest of components are aware the service is
+        # being modified.
+        _service : Optional[Service] = get_service(context_client, request)
+        if _service is None: raise Exception('Service({:s}) not found'.format(grpc_message_to_json_string(request)))
+        service = Service()
+        service.CopyFrom(_service)
+        service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL
+        context_client.SetService(service)
+
+        # Feed TaskScheduler with this service and the sub-services and sub-connections related to this service.
+        # TaskScheduler identifies inter-dependencies among them and produces a schedule of tasks (an ordered list of
+        # tasks to be executed) to implement the requested delete operation.
+        tasks_scheduler = TasksScheduler(self.service_handler_factory)
+        tasks_scheduler.compose_from_service(service, is_delete=True)
+        tasks_scheduler.execute_all()
         return Empty()
diff --git a/src/service/service/Tools.py b/src/service/service/Tools.py
deleted file mode 100644
index 4386793c52a979cd0b3d86701a3476314857f3ac..0000000000000000000000000000000000000000
--- a/src/service/service/Tools.py
+++ /dev/null
@@ -1,342 +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
-from typing import Any, Dict, List, Optional, Tuple
-from common.orm.Database import Database
-from common.orm.HighLevel import get_object, get_related_objects
-from common.orm.backend.Tools import key_to_str
-from common.proto.context_pb2 import (
-    ConfigRule, Connection, Constraint, EndPointId, Service, ServiceId, ServiceStatusEnum)
-from common.rpc_method_wrapper.ServiceExceptions import (
-    InvalidArgumentException, NotFoundException, OperationFailedException)
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from .database.ConfigModel import (
-    ConfigModel, ConfigRuleModel, ORM_ConfigActionEnum, get_config_rules, grpc_config_rules_to_raw)
-from .database.ConstraintModel import ConstraintModel, ConstraintsModel, get_constraints, grpc_constraints_to_raw
-from .database.DatabaseDeviceTools import sync_device_from_context
-from .database.DatabaseServiceTools import (
-    delete_service_from_context, sync_service_from_context, sync_service_to_context, update_service_in_local_database)
-from .database.DeviceModel import DeviceModel, DriverModel
-from .database.EndPointModel import EndPointModel, grpc_endpointids_to_raw
-from .database.RelationModels import ServiceEndPointModel
-from .database.ServiceModel import ServiceModel
-from .service_handler_api._ServiceHandler import _ServiceHandler
-from .service_handler_api.FilterFields import FilterFieldEnum
-from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
-from .service_handler_api.Tools import (
-    check_errors_deleteconfig, check_errors_deleteconstraint, check_errors_deleteendpoint, check_errors_setconfig,
-    check_errors_setconstraint, check_errors_setendpoint)
-
-LOGGER = logging.getLogger(__name__)
-
-def sync_devices_from_context(
-        context_client : ContextClient, database : Database, db_service : Optional[ServiceModel],
-        service_endpoint_ids : List[EndPointId]
-    ) -> Dict[str, DeviceModel]:
-
-    required_device_uuids = set()
-    if db_service is not None:
-        db_endpoints = get_related_objects(db_service, ServiceEndPointModel, 'endpoint_fk')
-        for db_endpoint in db_endpoints:
-            db_device = get_object(database, DeviceModel, db_endpoint.device_fk, raise_if_not_found=False)
-            required_device_uuids.add(db_device.device_uuid)
-
-    for endpoint_id in service_endpoint_ids:
-        required_device_uuids.add(endpoint_id.device_id.device_uuid.uuid)
-
-    db_devices = {}
-    devices_not_found = set()
-    for device_uuid in required_device_uuids:
-        sync_device_from_context(device_uuid, context_client, database)
-        db_device = get_object(database, DeviceModel, device_uuid, raise_if_not_found=False)
-        if db_device is None:
-            devices_not_found.add(device_uuid)
-        else:
-            db_devices[device_uuid] = db_device
-
-    if len(devices_not_found) > 0:
-        extra_details = ['Devices({:s}) cannot be retrieved from Context'.format(str(devices_not_found))]
-        raise NotFoundException('Device', '...', extra_details=extra_details)
-
-    return db_devices
-
-def classify_config_rules(
-    db_service : ServiceModel, service_config_rules : List[ConfigRule],
-    resources_to_set: List[Tuple[str, Any]], resources_to_delete : List[Tuple[str, Any]]):
-
-    context_config_rules = get_config_rules(db_service.database, db_service.pk, 'running')
-    context_config_rules = {config_rule[1]: config_rule[2] for config_rule in context_config_rules}
-    #LOGGER.info('[classify_config_rules] context_config_rules = {:s}'.format(str(context_config_rules)))
-
-    request_config_rules = grpc_config_rules_to_raw(service_config_rules)
-    #LOGGER.info('[classify_config_rules] request_config_rules = {:s}'.format(str(request_config_rules)))
-
-    for config_rule in request_config_rules:
-        action, key, value = config_rule
-        if action == ORM_ConfigActionEnum.SET:
-            if (key not in context_config_rules) or (context_config_rules[key] != value):
-                resources_to_set.append((key, value))
-        elif action == ORM_ConfigActionEnum.DELETE:
-            if key in context_config_rules:
-                resources_to_delete.append((key, value))
-        else:
-            raise InvalidArgumentException('config_rule.action', str(action), extra_details=str(request_config_rules))
-
-    #LOGGER.info('[classify_config_rules] resources_to_set = {:s}'.format(str(resources_to_set)))
-    #LOGGER.info('[classify_config_rules] resources_to_delete = {:s}'.format(str(resources_to_delete)))
-
-def classify_constraints(
-    db_service : ServiceModel, service_constraints : List[Constraint],
-    constraints_to_set: List[Tuple[str, str]], constraints_to_delete : List[Tuple[str, str]]):
-
-    context_constraints = get_constraints(db_service.database, db_service.pk, 'running')
-    context_constraints = {constraint[0]: constraint[1] for constraint in context_constraints}
-    #LOGGER.info('[classify_constraints] context_constraints = {:s}'.format(str(context_constraints)))
-
-    request_constraints = grpc_constraints_to_raw(service_constraints)
-    #LOGGER.info('[classify_constraints] request_constraints = {:s}'.format(str(request_constraints)))
-
-    for constraint in request_constraints:
-        constraint_type, constraint_value = constraint
-        if constraint_type in context_constraints:
-            if context_constraints[constraint_type] != constraint_value:
-                constraints_to_set.append(constraint)
-        else:
-            constraints_to_set.append(constraint)
-        context_constraints.pop(constraint_type, None)
-
-    for constraint in context_constraints:
-        constraints_to_delete.append(constraint)
-
-    #LOGGER.info('[classify_constraints] constraints_to_set = {:s}'.format(str(constraints_to_set)))
-    #LOGGER.info('[classify_constraints] constraints_to_delete = {:s}'.format(str(constraints_to_delete)))
-
-def get_service_endpointids(db_service : ServiceModel) -> List[Tuple[str, str, Optional[str]]]:
-    db_endpoints : List[EndPointModel] = get_related_objects(db_service, ServiceEndPointModel, 'endpoint_fk')
-    endpoint_ids = [db_endpoint.dump_id() for db_endpoint in db_endpoints]
-    return [
-        (endpoint_id['device_id']['device_uuid']['uuid'], endpoint_id['endpoint_uuid']['uuid'],
-            endpoint_id.get('topology_id', {}).get('topology_uuid', {}).get('uuid', None))
-        for endpoint_id in endpoint_ids
-    ]
-
-def classify_endpointids(
-    db_service : ServiceModel, service_endpoint_ids : List[EndPointId],
-    endpointids_to_set: List[Tuple[str, str, Optional[str]]],
-    endpointids_to_delete : List[Tuple[str, str, Optional[str]]]):
-
-    context_endpoint_ids = get_service_endpointids(db_service)
-    #LOGGER.info('[classify_endpointids] context_endpoint_ids = {:s}'.format(str(context_endpoint_ids)))
-    context_endpoint_ids = set(context_endpoint_ids)
-    #LOGGER.info('[classify_endpointids] context_endpoint_ids = {:s}'.format(str(context_endpoint_ids)))
-
-    request_endpoint_ids = grpc_endpointids_to_raw(service_endpoint_ids)
-    #LOGGER.info('[classify_endpointids] request_endpoint_ids = {:s}'.format(str(request_endpoint_ids)))
-
-    if len(service_endpoint_ids) != 2: return
-    for endpoint_id in request_endpoint_ids:
-        #if endpoint_id not in context_endpoint_ids:
-        #    endpointids_to_set.append(endpoint_id)
-        #context_endpoint_ids.discard(endpoint_id)
-        endpointids_to_set.append(endpoint_id)
-
-    #for endpoint_id in context_endpoint_ids:
-    #    endpointids_to_delete.append(endpoint_id)
-
-    #LOGGER.info('[classify_endpointids] endpointids_to_set = {:s}'.format(str(endpointids_to_set)))
-    #LOGGER.info('[classify_endpointids] endpointids_to_delete = {:s}'.format(str(endpointids_to_delete)))
-
-def get_service_handler_class(
-    service_handler_factory : ServiceHandlerFactory, db_service : ServiceModel, db_devices : Dict[str, DeviceModel]
-    ) -> Optional[_ServiceHandler]:
-
-    str_service_key = db_service.pk
-    database = db_service.database
-
-    # Assume all devices involved in the service must support at least one driver in common
-    device_drivers = None
-    for _,db_device in db_devices.items():
-        db_driver_pks = db_device.references(DriverModel)
-        db_driver_names = [DriverModel(database, pk).driver.value for pk,_ in db_driver_pks]
-        if device_drivers is None:
-            device_drivers = set(db_driver_names)
-        else:
-            device_drivers.intersection_update(db_driver_names)
-
-    filter_fields = {
-        FilterFieldEnum.SERVICE_TYPE.value  : db_service.service_type.value,    # must be supported
-        FilterFieldEnum.DEVICE_DRIVER.value : device_drivers,                   # at least one must be supported
-    }
-
-    msg = 'Selecting service handler for service({:s}) with filter_fields({:s})...'
-    LOGGER.info(msg.format(str(str_service_key), str(filter_fields)))
-    service_handler_class = service_handler_factory.get_service_handler_class(**filter_fields)
-    msg = 'ServiceHandler({:s}) selected for service({:s}) with filter_fields({:s})...'
-    LOGGER.info(msg.format(str(service_handler_class.__name__), str(str_service_key), str(filter_fields)))
-    return service_handler_class
-
-def update_service(
-        database : Database, context_client : ContextClient, device_client : DeviceClient,
-        service_handler_factory : ServiceHandlerFactory, service : Service, connection : Connection
-    ) -> ServiceModel:
-
-    service_id = service.service_id
-    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])
-
-    # Sync before updating service to ensure we have devices, endpoints, constraints, and config rules to be
-    # set/deleted before actuallymodifying them in the local in-memory database.
-
-    sync_service_from_context(service_context_uuid, service_uuid, context_client, database)
-    db_service = get_object(database, ServiceModel, str_service_key, raise_if_not_found=False)
-    db_devices = sync_devices_from_context(context_client, database, db_service, service.service_endpoint_ids)
-
-    if db_service is None: db_service,_ = update_service_in_local_database(database, service)
-    LOGGER.info('[update_service] db_service = {:s}'.format(str(db_service.dump(
-        include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-
-    resources_to_set    : List[Tuple[str, Any]] = [] # resource_key, resource_value
-    resources_to_delete : List[Tuple[str, Any]] = [] # resource_key, resource_value
-    classify_config_rules(db_service, service.service_config.config_rules, resources_to_set, resources_to_delete)
-
-    constraints_to_set    : List[Tuple[str, str]] = [] # constraint_type, constraint_value
-    constraints_to_delete : List[Tuple[str, str]] = [] # constraint_type, constraint_value
-    classify_constraints(db_service, service.service_constraints, constraints_to_set, constraints_to_delete)
-
-    endpointids_to_set    : List[Tuple[str, str, Optional[str]]] = [] # device_uuid, endpoint_uuid, topology_uuid
-    endpointids_to_delete : List[Tuple[str, str, Optional[str]]] = [] # device_uuid, endpoint_uuid, topology_uuid
-    classify_endpointids(db_service, service.service_endpoint_ids, endpointids_to_set, endpointids_to_delete)
-
-    service_handler_class = get_service_handler_class(service_handler_factory, db_service, db_devices)
-    service_handler_settings = {}
-    service_handler : _ServiceHandler = service_handler_class(
-        db_service, database, context_client, device_client, **service_handler_settings)
-
-    errors = []
-
-    if len(errors) == 0:
-        results_deleteendpoint = service_handler.DeleteEndpoint(endpointids_to_delete)
-        errors.extend(check_errors_deleteendpoint(endpointids_to_delete, results_deleteendpoint))
-
-    if len(errors) == 0:
-        results_deleteconstraint = service_handler.DeleteConstraint(constraints_to_delete)
-        errors.extend(check_errors_deleteconstraint(constraints_to_delete, results_deleteconstraint))
-
-    if len(errors) == 0:
-        results_deleteconfig = service_handler.DeleteConfig(resources_to_delete)
-        errors.extend(check_errors_deleteconfig(resources_to_delete, results_deleteconfig))
-
-    if len(errors) == 0:
-        results_setconfig = service_handler.SetConfig(resources_to_set)
-        errors.extend(check_errors_setconfig(resources_to_set, results_setconfig))
-
-    if len(errors) == 0:
-        results_setconstraint = service_handler.SetConstraint(constraints_to_set)
-        errors.extend(check_errors_setconstraint(constraints_to_set, results_setconstraint))
-
-    if len(errors) == 0:
-        results_setendpoint = service_handler.SetEndpoint(endpointids_to_set)
-        errors.extend(check_errors_setendpoint(endpointids_to_set, results_setendpoint))
-
-    if len(errors) > 0:
-        raise OperationFailedException('UpdateService', extra_details=errors)
-
-    LOGGER.info('[update_service] len(service.service_endpoint_ids) = {:d}'.format(len(service.service_endpoint_ids)))
-    if len(service.service_endpoint_ids) >= 2:
-        service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
-
-    db_service,_ = update_service_in_local_database(database, service)
-    LOGGER.info('[update_service] db_service = {:s}'.format(str(db_service.dump(
-        include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-
-    sync_service_to_context(db_service, context_client)
-    context_client.SetConnection(connection)
-    return db_service
-
-def delete_service(
-        database : Database, context_client : ContextClient, device_client : DeviceClient,
-        service_handler_factory : ServiceHandlerFactory, service_id : ServiceId, connection : Connection
-    ) -> None:
-
-    context_client.RemoveConnection(connection.connection_id)
-
-    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])
-
-    # Sync before updating service to ensure we have devices, endpoints, constraints, and config rules to be
-    # set/deleted before actuallymodifying them in the local in-memory database.
-
-    sync_service_from_context(service_context_uuid, service_uuid, context_client, database)
-    db_service : ServiceModel = get_object(database, ServiceModel, str_service_key, raise_if_not_found=False)
-    if db_service is None: return
-    LOGGER.info('[delete_service] db_service = {:s}'.format(str(db_service.dump(
-        include_endpoint_ids=True, include_constraints=True, include_config_rules=True))))
-
-    db_devices = sync_devices_from_context(context_client, database, db_service, [])
-
-    resources_to_delete : List[Tuple[str, str]] = [     # resource_key, resource_value
-        (config_rule[1], config_rule[2])
-        for config_rule in get_config_rules(db_service.database, db_service.pk, 'running')
-    ]
-
-    constraints_to_delete : List[Tuple[str, str]] = [   # constraint_type, constraint_value
-        (constraint[0], constraint[1])
-        for constraint in get_constraints(db_service.database, db_service.pk, 'running')
-    ]
-
-    # device_uuid, endpoint_uuid, topology_uuid
-    endpointids_to_delete : List[Tuple[str, str, Optional[str]]] = list(set(get_service_endpointids(db_service)))
-
-    service_handler_class = get_service_handler_class(service_handler_factory, db_service, db_devices)
-    service_handler_settings = {}
-    service_handler : _ServiceHandler = service_handler_class(
-        db_service, database, context_client, device_client, **service_handler_settings)
-
-    errors = []
-
-    if len(errors) == 0:
-        results_deleteendpoint = service_handler.DeleteEndpoint(endpointids_to_delete)
-        errors.extend(check_errors_deleteendpoint(endpointids_to_delete, results_deleteendpoint))
-
-    if len(errors) == 0:
-        results_deleteconstraint = service_handler.DeleteConstraint(constraints_to_delete)
-        errors.extend(check_errors_deleteconstraint(constraints_to_delete, results_deleteconstraint))
-
-    if len(errors) == 0:
-        results_deleteconfig = service_handler.DeleteConfig(resources_to_delete)
-        errors.extend(check_errors_deleteconfig(resources_to_delete, results_deleteconfig))
-
-    if len(errors) > 0:
-        raise OperationFailedException('DeleteService', extra_details=errors)
-
-    delete_service_from_context(db_service, context_client)
-
-    for db_service_endpoint_pk,_ in db_service.references(ServiceEndPointModel):
-        ServiceEndPointModel(database, db_service_endpoint_pk).delete()
-
-    db_running_config = ConfigModel(database, db_service.service_config_fk)
-    for db_config_rule_pk,_ in db_running_config.references(ConfigRuleModel):
-        ConfigRuleModel(database, db_config_rule_pk).delete()
-
-    db_running_constraints = ConstraintsModel(database, db_service.service_constraints_fk)
-    for db_constraint_pk,_ in db_running_constraints.references(ConstraintModel):
-        ConstraintModel(database, db_constraint_pk).delete()
-
-    db_service.delete()
-    db_running_config.delete()
-    db_running_constraints.delete()
diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py
index 1a67a309ff19bda2bf3174c80dfb908e99f72d14..04cf00b06bff809f837833964a9e093f18888ac2 100644
--- a/src/service/service/__main__.py
+++ b/src/service/service/__main__.py
@@ -33,14 +33,16 @@ def main():
     global LOGGER # pylint: disable=global-statement
 
     log_level = get_log_level()
-    logging.basicConfig(level=log_level)
+    logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        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),
+        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),
+        get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
     signal.signal(signal.SIGINT,  signal_handler)
diff --git a/src/service/service/path_computation_element/PathComputationElement.py b/src/service/service/path_computation_element/PathComputationElement.py
index 08331377d3ebcf485b34319ff2f6d36f49e2071c..54fa9ab7e99965c1212838a0bf8e1471b2e524ee 100644
--- a/src/service/service/path_computation_element/PathComputationElement.py
+++ b/src/service/service/path_computation_element/PathComputationElement.py
@@ -31,11 +31,11 @@ LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.INFO)
 
 SUB_SERVICE_TYPES = {
-    DeviceTypeEnum.EMULATED_PACKET_ROUTER.value      : ServiceTypeEnum.SERVICETYPE_L3NM,
-    DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value: ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
-    DeviceTypeEnum.PACKET_ROUTER.value               : ServiceTypeEnum.SERVICETYPE_L3NM,
-    DeviceTypeEnum.OPTICAL_LINE_SYSTEM.value         : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
-    DeviceTypeEnum.XR_CONSTELLATION.value            : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+    DeviceTypeEnum.EMULATED_PACKET_ROUTER.value   : ServiceTypeEnum.SERVICETYPE_L3NM,
+    DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value: ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+    DeviceTypeEnum.PACKET_ROUTER.value            : ServiceTypeEnum.SERVICETYPE_L3NM,
+    DeviceTypeEnum.OPEN_LINE_SYSTEM.value         : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+    DeviceTypeEnum.XR_CONSTELLATION.value         : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
 }
 DEFAULT_SUB_SERVICE_TYPE = ServiceTypeEnum.SERVICETYPE_UNKNOWN
 
diff --git a/src/service/service/service_handler_api/FilterFields.py b/src/service/service/service_handler_api/FilterFields.py
index 9d8f9ad28f69ef606bcf2e06e3a6a17514f016b4..0f21812089e2af8271884ef7539f979ff0426a5a 100644
--- a/src/service/service/service_handler_api/FilterFields.py
+++ b/src/service/service/service_handler_api/FilterFields.py
@@ -13,15 +13,31 @@
 # limitations under the License.
 
 from enum import Enum
-from service.service.database.ServiceModel import ORM_ServiceTypeEnum
-from service.service.database.DeviceModel import ORM_DeviceDriverEnum
+from common.proto.context_pb2 import DeviceDriverEnum, ServiceTypeEnum
 
 class FilterFieldEnum(Enum):
     SERVICE_TYPE  = 'service_type'
     DEVICE_DRIVER = 'device_driver'
 
+SERVICE_TYPE_VALUES = {
+    ServiceTypeEnum.SERVICETYPE_UNKNOWN,
+    ServiceTypeEnum.SERVICETYPE_L3NM,
+    ServiceTypeEnum.SERVICETYPE_L2NM,
+    ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+}
+
+DEVICE_DRIVER_VALUES = {
+    DeviceDriverEnum.DEVICEDRIVER_UNDEFINED,
+    DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG,
+    DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API,
+    DeviceDriverEnum.DEVICEDRIVER_P4,
+    DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY,
+    DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352,
+    DeviceDriverEnum.DEVICEDRIVER_XR
+}
+
 # Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified
 FILTER_FIELD_ALLOWED_VALUES = {
-    FilterFieldEnum.SERVICE_TYPE.value  : {i.value for i in ORM_ServiceTypeEnum},
-    FilterFieldEnum.DEVICE_DRIVER.value : {i.value for i in ORM_DeviceDriverEnum},
+    FilterFieldEnum.SERVICE_TYPE.value  : SERVICE_TYPE_VALUES,
+    FilterFieldEnum.DEVICE_DRIVER.value : DEVICE_DRIVER_VALUES,
 }
diff --git a/src/service/service/service_handler_api/ServiceHandlerFactory.py b/src/service/service/service_handler_api/ServiceHandlerFactory.py
index 8b7223a95613a8b490862bb3dad091baf3b38388..09a56775d4f391d71fe5ac30f9be74430120e306 100644
--- a/src/service/service/service_handler_api/ServiceHandlerFactory.py
+++ b/src/service/service/service_handler_api/ServiceHandlerFactory.py
@@ -14,7 +14,9 @@
 
 import logging, operator
 from enum import Enum
-from typing import Any, Dict, Iterable, List, Set, Tuple
+from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
+from common.proto.context_pb2 import Device, Service
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from service.service.service_handler_api._ServiceHandler import _ServiceHandler
 from .Exceptions import (
     UnsatisfiedFilterException, UnsupportedServiceHandlerClassException, UnsupportedFilterFieldException,
@@ -91,3 +93,40 @@ class ServiceHandlerFactory:
         candidate_service_handler_classes = sorted(
             candidate_service_handler_classes.items(), key=operator.itemgetter(1), reverse=True)
         return candidate_service_handler_classes[0][0]
+
+def get_device_supported_drivers(device : Device) -> Set[int]:
+    return {device_driver for device_driver in device.device_drivers}
+
+def get_common_device_drivers(drivers_per_device : List[Set[int]]) -> Set[int]:
+    common_device_drivers = None
+    for device_drivers in drivers_per_device:
+        if common_device_drivers is None:
+            common_device_drivers = set(device_drivers)
+        else:
+            common_device_drivers.intersection_update(device_drivers)
+    if common_device_drivers is None: common_device_drivers = set()
+    return common_device_drivers
+
+def get_service_handler_class(
+    service_handler_factory : ServiceHandlerFactory, service : Service, connection_devices : Dict[str, Device]
+) -> Optional[_ServiceHandler]:
+
+    str_service_key = grpc_message_to_json_string(service.service_id)
+
+    # Assume all devices involved in the service's connection must support at least one driver in common
+    common_device_drivers = get_common_device_drivers([
+        get_device_supported_drivers(device)
+        for device in connection_devices.values()
+    ])
+
+    filter_fields = {
+        FilterFieldEnum.SERVICE_TYPE.value  : service.service_type,     # must be supported
+        FilterFieldEnum.DEVICE_DRIVER.value : common_device_drivers,    # at least one must be supported
+    }
+
+    MSG = 'Selecting service handler for service({:s}) with filter_fields({:s})...'
+    LOGGER.info(MSG.format(str(str_service_key), str(filter_fields)))
+    service_handler_class = service_handler_factory.get_service_handler_class(**filter_fields)
+    MSG = 'ServiceHandler({:s}) selected for service({:s}) with filter_fields({:s})...'
+    LOGGER.info(MSG.format(str(service_handler_class.__name__), str(str_service_key), str(filter_fields)))
+    return service_handler_class
diff --git a/src/service/service/service_handler_api/_ServiceHandler.py b/src/service/service/service_handler_api/_ServiceHandler.py
index e724ebcc986a1c5d205c2b77d9cb944d6faeb359..9cbe3f49e8594badf3b419b24154cb59a30a17bf 100644
--- a/src/service/service/service_handler_api/_ServiceHandler.py
+++ b/src/service/service/service_handler_api/_ServiceHandler.py
@@ -19,10 +19,12 @@ from device.client.DeviceClient import DeviceClient
 from service.service.database.ServiceModel import ServiceModel
 
 class _ServiceHandler:
-    def __init__(
-        self, db_service : ServiceModel, database : Database, context_client : ContextClient,
-        device_client : DeviceClient, **settings
-    ) -> None:
+    def __init__(self,
+                 db_service: ServiceModel,
+                 database: Database,
+                 context_client: ContextClient,
+                 device_client: DeviceClient,
+                 **settings) -> None:
         """ Initialize Driver.
             Parameters:
                 db_service
@@ -30,94 +32,129 @@ class _ServiceHandler:
                 database
                     The instance of the local in-memory database.
                 context_client
-                    An instance of context client to be used to retrieve information from the service and the devices.
+                    An instance of context client to be used to retrieve
+                    information from the service and the devices.
                 device_client
-                    An instance of device client to be used to configure the devices.
+                    An instance of device client to be used to configure
+                    the devices.
                 **settings
                     Extra settings required by the service handler.
         """
         raise NotImplementedError()
 
-    def SetEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
-        """ Set endpoints from a list.
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]],
+        connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        """ Create/Update service endpoints form a list.
             Parameters:
-                endpoints : List[Tuple[str, str, Optional[str]]]
-                    List of tuples, each containing a device_uuid, endpoint_uuid and, optionally, the topology_uuid
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid and, optionally, the topology_uuid
                     of the endpoint to be added.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
             Returns:
-                results : List[Union[bool, Exception]]
-                    List of results for endpoint changes requested. Return values must be in the same order than
-                    endpoints requested. If an endpoint is properly added, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint changes requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly added, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
         """
         raise NotImplementedError()
 
-    def DeleteEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
-        """ Delete endpoints form a list.
+    def DeleteEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]],
+        connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        """ Delete service endpoints form a list.
             Parameters:
-                endpoints : List[Tuple[str, str, Optional[str]]]
-                    List of tuples, each containing a device_uuid, endpoint_uuid, and the topology_uuid of the endpoint
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid, and the topology_uuid of the endpoint
                     to be removed.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
             Returns:
-                results : List[Union[bool, Exception]]
-                    List of results for endpoint deletions requested. Return values must be in the same order than
-                    endpoints requested. If an endpoint is properly deleted, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results: List[Union[bool, Exception]]
+                    List of results for endpoint deletions requested.
+                    Return values must be in the same order as the requested
+                    endpoints. If an endpoint is properly deleted, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
         """
         raise NotImplementedError()
 
-    def SetConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
-        """ Create/Update constraints.
+    def SetConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Create/Update service constraints.
             Parameters:
-                constraints : List[Tuple[str, Any]]
-                    List of tuples, each containing a constraint_type and the new constraint_value to be set.
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type and the
+                    new constraint_value to be set.
             Returns:
-                results : List[Union[bool, Exception]]
-                    List of results for constraint changes requested. Return values must be in the same order than
-                    constraints requested. If a constraint is properly set, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results: List[Union[bool, Exception]]
+                    List of results for constraint changes requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
         """
         raise NotImplementedError()
 
-    def DeleteConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
-        """ Delete constraints.
+    def DeleteConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Delete service constraints.
             Parameters:
-                constraints : List[Tuple[str, Any]]
-                    List of tuples, each containing a constraint_type pointing to the constraint to be deleted, and a
-                    constraint_value containing possible additionally required values to locate the constraint to be
-                    removed.
+                constraints: List[Tuple[str, Any]]
+                    List of tuples, each containing a constraint_type pointing
+                    to the constraint to be deleted, and a constraint_value
+                    containing possible additionally required values to locate
+                    the constraint to be removed.
             Returns:
-                results : List[Union[bool, Exception]]
-                    List of results for constraint deletions requested. Return values must be in the same order than
-                    constraints requested. If a constraint is properly deleted, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results: List[Union[bool, Exception]]
+                    List of results for constraint deletions requested.
+                    Return values must be in the same order as the requested
+                    constraints. If a constraint is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
         """
         raise NotImplementedError()
 
-    def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
-        """ Create/Update configuration for a list of resources.
+    def SetConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Create/Update configuration for a list of service resources.
             Parameters:
-                resources : List[Tuple[str, Any]]
-                    List of tuples, each containing a resource_key pointing the resource to be modified, and a
-                    resource_value containing the new value to be set.
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value
+                    containing the new value to be set.
             Returns:
-                results : List[Union[bool, Exception]]
-                    List of results for resource key changes requested. Return values must be in the same order than
-                    resource keys requested. If a resource is properly set, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results: List[Union[bool, Exception]]
+                    List of results for resource key changes requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly set, True must be
+                    returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
         """
         raise NotImplementedError()
 
-    def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
-        """ Delete configuration for a list of resources.
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """ Delete configuration for a list of service resources.
             Parameters:
-                resources : List[Tuple[str, Any]]
-                    List of tuples, each containing a resource_key pointing the resource to be modified, and a
-                    resource_value containing possible additionally required values to locate the value to be removed.
+                resources: List[Tuple[str, Any]]
+                    List of tuples, each containing a resource_key pointing to
+                    the resource to be modified, and a resource_value containing
+                    possible additionally required values to locate the value
+                    to be removed.
             Returns:
-                results : List[Union[bool, Exception]]
-                    List of results for resource key deletions requested. Return values must be in the same order than
-                    resource keys requested. If a resource is properly deleted, True must be retrieved; otherwise, the
-                    Exception that is raised during the processing must be retrieved.
+                results: List[Union[bool, Exception]]
+                    List of results for resource key deletions requested.
+                    Return values must be in the same order as the requested
+                    resource keys. If a resource is properly deleted, True must
+                    be returned; otherwise, the Exception that is raised during
+                    the processing must be returned.
         """
         raise NotImplementedError()
diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index 07a653a4faf7974561341abbbbe953061bca787d..81c7d9d362e2e076a359f3bf33414a98dcf1d655 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -12,28 +12,36 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from ..service_handler_api.FilterFields import FilterFieldEnum, ORM_DeviceDriverEnum, ORM_ServiceTypeEnum
+from common.proto.context_pb2 import DeviceDriverEnum, ServiceTypeEnum
+from ..service_handler_api.FilterFields import FilterFieldEnum
+from .l2nm_emulated.L2NMEmulatedServiceHandler import L2NMEmulatedServiceHandler
 from .l3nm_emulated.L3NMEmulatedServiceHandler import L3NMEmulatedServiceHandler
 from .l3nm_openconfig.L3NMOpenConfigServiceHandler import L3NMOpenConfigServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 
 SERVICE_HANDLERS = [
+    (L2NMEmulatedServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L2NM,
+            FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_UNDEFINED,
+        }
+    ]),
     (L3NMEmulatedServiceHandler, [
         {
-            FilterFieldEnum.SERVICE_TYPE  : ORM_ServiceTypeEnum.L3NM,
-            FilterFieldEnum.DEVICE_DRIVER : ORM_DeviceDriverEnum.UNDEFINED,
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L3NM,
+            FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_UNDEFINED,
         }
     ]),
     (L3NMOpenConfigServiceHandler, [
         {
-            FilterFieldEnum.SERVICE_TYPE  : ORM_ServiceTypeEnum.L3NM,
-            FilterFieldEnum.DEVICE_DRIVER : ORM_DeviceDriverEnum.OPENCONFIG,
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_L3NM,
+            FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG,
         }
     ]),
     (TapiServiceHandler, [
         {
-            FilterFieldEnum.SERVICE_TYPE  : ORM_ServiceTypeEnum.TAPI_CONNECTIVITY_SERVICE,
-            FilterFieldEnum.DEVICE_DRIVER : [ORM_DeviceDriverEnum.TRANSPORT_API, ORM_DeviceDriverEnum.XR],
+            FilterFieldEnum.SERVICE_TYPE  : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+            FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API, DeviceDriverEnum.DEVICEDRIVER_XR],
         }
     ]),
 ]
\ No newline at end of file
diff --git a/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py
new file mode 100644
index 0000000000000000000000000000000000000000..70f2ea093b886a9c1745d7fb63360de77124f3fb
--- /dev/null
+++ b/src/service/service/service_handlers/l2nm_emulated/ConfigRules.py
@@ -0,0 +1,132 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Dict, List
+from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from service.service.service_handler_api.AnyTreeTools import TreeNode
+
+def setup_config_rules(
+    service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str,
+    service_settings : TreeNode, endpoint_settings : TreeNode
+) -> List[Dict]:
+
+    json_settings          : Dict = {} if service_settings  is None else service_settings.value
+    json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value
+
+    mtu                 = json_settings.get('mtu',                 1450 )    # 1512
+    #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+    #bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+    #bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
+    router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+    sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    #address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    #address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+    remote_router       = json_endpoint_settings.get('remote_router',       '0.0.0.0')  # '5.5.5.5'
+    circuit_id          = json_endpoint_settings.get('circuit_id',          '000'    )  # '111'
+
+    if_cirid_name         = '{:s}.{:s}'.format(endpoint_uuid, str(circuit_id))
+    network_instance_name = 'ELAN-AC:{:s}'.format(str(circuit_id))
+    connection_point_id   = 'VC-1'
+
+    json_config_rules = [
+        json_config_rule_set(
+            '/network_instance[default]',
+            {'name': 'default', 'type': 'DEFAULT_INSTANCE', 'router_id': router_id}),
+
+        json_config_rule_set(
+            '/network_instance[default]/protocols[OSPF]',
+            {'name': 'default', 'identifier': 'OSPF', 'protocol_name': 'OSPF'}),
+
+        json_config_rule_set(
+            '/network_instance[default]/protocols[STATIC]',
+            {'name': 'default', 'identifier': 'STATIC', 'protocol_name': 'STATIC'}),
+
+        json_config_rule_set(
+            '/network_instance[{:s}]'.format(network_instance_name),
+            {'name': network_instance_name, 'type': 'L2VSI'}),
+
+        json_config_rule_set(
+            '/interface[{:s}]/subinterface[0]'.format(if_cirid_name, sub_interface_index),
+            {'name': if_cirid_name, 'type': 'l2vlan', 'index': sub_interface_index, 'vlan_id': vlan_id}),
+
+        json_config_rule_set(
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_cirid_name),
+            {'name': network_instance_name, 'id': if_cirid_name, 'interface': if_cirid_name, 'subinterface': 0}),
+
+        json_config_rule_set(
+            '/network_instance[{:s}]/connection_point[{:s}]'.format(network_instance_name, connection_point_id),
+            {'name': network_instance_name, 'connection_point': connection_point_id, 'VC_ID': circuit_id,
+             'remote_system': remote_router}),
+    ]
+    return json_config_rules
+
+def teardown_config_rules(
+    service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str,
+    service_settings : TreeNode, endpoint_settings : TreeNode
+) -> List[Dict]:
+
+    json_settings          : Dict = {} if service_settings  is None else service_settings.value
+    json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value
+
+    mtu                 = json_settings.get('mtu',                 1450 )    # 1512
+    #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+    #bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+    #bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
+    router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+    sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    #address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    #address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+    remote_router       = json_endpoint_settings.get('remote_router',       '0.0.0.0')  # '5.5.5.5'
+    circuit_id          = json_endpoint_settings.get('circuit_id',          '000'    )  # '111'
+
+    if_cirid_name         = '{:s}.{:s}'.format(endpoint_uuid, str(circuit_id))
+    network_instance_name = 'ELAN-AC:{:s}'.format(str(circuit_id))
+    connection_point_id   = 'VC-1'
+
+    json_config_rules = [
+        json_config_rule_delete(
+            '/network_instance[{:s}]/connection_point[{:s}]'.format(network_instance_name, connection_point_id),
+            {'name': network_instance_name, 'connection_point': connection_point_id}),
+
+        json_config_rule_delete(
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_cirid_name),
+            {'name': network_instance_name, 'id': if_cirid_name, 'interface': if_cirid_name, 'subinterface': 0}),
+
+        json_config_rule_delete(
+            '/interface[{:s}]/subinterface[0]'.format(if_cirid_name, sub_interface_index),
+            {'name': if_cirid_name, 'index': sub_interface_index}),
+
+        json_config_rule_delete(
+            '/network_instance[{:s}]'.format(network_instance_name),
+            {'name': network_instance_name}),
+
+        json_config_rule_delete(
+            '/network_instance[default]/protocols[STATIC]',
+            {'name': 'default', 'identifier': 'STATIC', 'protocol_name': 'STATIC'}),
+
+        json_config_rule_delete(
+            '/network_instance[default]/protocols[OSPF]',
+            {'name': 'default', 'identifier': 'OSPF', 'protocol_name': 'OSPF'}),
+
+        json_config_rule_delete(
+            '/network_instance[default]',
+            {'name': 'default', 'type': 'DEFAULT_INSTANCE', 'router_id': router_id}),
+    ]
+    return json_config_rules
diff --git a/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py b/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d1e0126e3b36b7b5c687fc25c96af46721da69b
--- /dev/null
+++ b/src/service/service/service_handlers/l2nm_emulated/L2NMEmulatedServiceHandler.py
@@ -0,0 +1,161 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 anytree, json, logging
+from typing import Any, List, Optional, Tuple, Union
+from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, DeviceId, Service
+from common.tools.object_factory.Device import json_device_id
+from common.type_checkers.Checkers import chk_length, chk_type
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.AnyTreeTools import TreeNode, delete_subnode, get_subnode, set_subnode_value
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from .ConfigRules import setup_config_rules, teardown_config_rules
+
+LOGGER = logging.getLogger(__name__)
+
+class L2NMEmulatedServiceHandler(_ServiceHandler):
+    def __init__(   # pylint: disable=super-init-not-called
+        self, service : Service, task_executor : TaskExecutor, **settings
+    ) -> None:
+        self.__service = service
+        self.__task_executor = task_executor # pylint: disable=unused-private-member
+        self.__resolver = anytree.Resolver(pathattr='name')
+        self.__config = TreeNode('.')
+        for config_rule in service.service_config.config_rules:
+            action = config_rule.action
+            if config_rule.WhichOneof('config_rule') != 'custom': continue
+            resource_key = config_rule.custom.resource_key
+            resource_value = config_rule.custom.resource_value
+            if action == ConfigActionEnum.CONFIGACTION_SET:
+                try:
+                    resource_value = json.loads(resource_value)
+                except: # pylint: disable=bare-except
+                    pass
+                set_subnode_value(self.__resolver, self.__config, resource_key, resource_value)
+            elif action == ConfigActionEnum.CONFIGACTION_DELETE:
+                delete_subnode(self.__resolver, self.__config, resource_key)
+
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        service_uuid = self.__service.service_id.service_uuid.uuid
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
+
+        results = []
+        for endpoint in endpoints:
+            try:
+                chk_type('endpoint', endpoint, (tuple, list))
+                chk_length('endpoint', endpoint, min_length=2, max_length=3)
+                device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
+
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
+
+                json_config_rules = setup_config_rules(
+                    service_uuid, connection_uuid, device_uuid, endpoint_uuid, settings, endpoint_settings)
+
+                device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                for json_config_rule in json_config_rules:
+                    device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+                self.__task_executor.configure_device(device)
+                results.append(True)
+            except Exception as e: # pylint: disable=broad-except
+                LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint)))
+                results.append(e)
+
+        return results
+
+    def DeleteEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+
+        service_uuid = self.__service.service_id.service_uuid.uuid
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
+
+        results = []
+        for endpoint in endpoints:
+            try:
+                chk_type('endpoint', endpoint, (tuple, list))
+                chk_length('endpoint', endpoint, min_length=2, max_length=3)
+                device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
+
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
+
+                json_config_rules = teardown_config_rules(
+                    service_uuid, connection_uuid, device_uuid, endpoint_uuid, settings, endpoint_settings)
+
+                device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                for json_config_rule in json_config_rules:
+                    device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+                self.__task_executor.configure_device(device)
+                results.append(True)
+            except Exception as e: # pylint: disable=broad-except
+                LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint)))
+                results.append(e)
+
+        return results
+
+    def SetConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+        chk_type('constraints', constraints, list)
+        if len(constraints) == 0: return []
+
+        msg = '[SetConstraint] Method not implemented. Constraints({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    def DeleteConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+        chk_type('constraints', constraints, list)
+        if len(constraints) == 0: return []
+
+        msg = '[DeleteConstraint] Method not implemented. Constraints({:s}) are being ignored.'
+        LOGGER.warning(msg.format(str(constraints)))
+        return [True for _ in range(len(constraints))]
+
+    def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+        chk_type('resources', resources, list)
+        if len(resources) == 0: return []
+
+        results = []
+        for resource in resources:
+            try:
+                resource_key, resource_value = resource
+                resource_value = json.loads(resource_value)
+                set_subnode_value(self.__resolver, self.__config, resource_key, resource_value)
+                results.append(True)
+            except Exception as e: # pylint: disable=broad-except
+                LOGGER.exception('Unable to SetConfig({:s})'.format(str(resource)))
+                results.append(e)
+
+        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 = []
+        for resource in resources:
+            try:
+                resource_key, _ = resource
+                delete_subnode(self.__resolver, self.__config, resource_key)
+            except Exception as e: # pylint: disable=broad-except
+                LOGGER.exception('Unable to DeleteConfig({:s})'.format(str(resource)))
+                results.append(e)
+
+        return results
diff --git a/src/service/service/service_handlers/l2nm_emulated/__init__.py b/src/service/service/service_handlers/l2nm_emulated/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/service/service/service_handlers/l2nm_emulated/__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/service/service/service_handlers/l3nm_emulated/ConfigRules.py b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a5aff5884c72f1384666a223a3b07da6d4ae4ec
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_emulated/ConfigRules.py
@@ -0,0 +1,249 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Dict, List
+from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from service.service.service_handler_api.AnyTreeTools import TreeNode
+
+def setup_config_rules(
+    service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str,
+    service_settings : TreeNode, endpoint_settings : TreeNode
+) -> List[Dict]:
+
+    json_settings          : Dict = {} if service_settings  is None else service_settings.value
+    json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value
+
+    service_short_uuid        = service_uuid.split('-')[-1]
+    network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
+    network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
+    network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
+
+    mtu                 = json_settings.get('mtu',                 1450 )    # 1512
+    #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+    bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+    bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
+    #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+    sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+    if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
+
+    json_config_rules = [
+        json_config_rule_set(
+            '/network_instance[{:s}]'.format(network_instance_name), {
+                'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
+                'route_distinguisher': route_distinguisher,
+                #'router_id': router_id, 'address_families': address_families,
+        }),
+        json_config_rule_set(
+            '/interface[{:s}]'.format(endpoint_uuid), {
+                'name': endpoint_uuid, 'description': network_interface_desc, 'mtu': mtu,
+        }),
+        json_config_rule_set(
+            '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
+                'name': endpoint_uuid, 'index': sub_interface_index,
+                'description': network_subinterface_desc, 'vlan_id': vlan_id,
+                'address_ip': address_ip, 'address_prefix': address_prefix,
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
+                'subinterface': sub_interface_index,
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                'policy_name': '{:s}_import'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+        }),
+        json_config_rule_set(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                network_instance_name, network_instance_name), {
+                'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                'policy_name': '{:s}_export'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+        }),
+        json_config_rule_set(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                network_instance_name, network_instance_name), {
+                'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
+        }),
+    ]
+
+    return json_config_rules
+
+def teardown_config_rules(
+    service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str,
+    service_settings : TreeNode, endpoint_settings : TreeNode
+) -> List[Dict]:
+
+    json_settings          : Dict = {} if service_settings  is None else service_settings.value
+    json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value
+
+    #mtu                 = json_settings.get('mtu',                 1450 )    # 1512
+    #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+    #bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+    bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
+    #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+    sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    #address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    #address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+
+    if_subif_name             = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
+    service_short_uuid        = service_uuid.split('-')[-1]
+    network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
+    #network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
+    #network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
+
+    json_config_rules = [
+        json_config_rule_delete(
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                'name': network_instance_name, 'id': if_subif_name,
+        }),
+        json_config_rule_delete(
+            '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
+                'name': endpoint_uuid, 'index': sub_interface_index,
+        }),
+        json_config_rule_delete(
+            '/interface[{:s}]'.format(endpoint_uuid), {
+                'name': endpoint_uuid,
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4',
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4',
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
+        }),
+        json_config_rule_delete(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                network_instance_name, network_instance_name), {
+            'name': network_instance_name,
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                'policy_name': '{:s}_import'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                network_instance_name, network_instance_name), {
+                'name': network_instance_name,
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                'policy_name': '{:s}_export'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]'.format(network_instance_name), {
+                'name': network_instance_name
+        }),
+    ]
+    return json_config_rules
diff --git a/src/service/service/service_handlers/l3nm_emulated/ConfigRulesOld.py b/src/service/service/service_handlers/l3nm_emulated/ConfigRulesOld.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b12049bae40829ed329c3509bdeaedbf55badb4
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_emulated/ConfigRulesOld.py
@@ -0,0 +1,109 @@
+
+                # json_endpoint_settings : Dict = endpoint_settings.value
+                # #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+                # route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+                # sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+                # vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+                # address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+                # address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+                # if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
+
+                # db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
+                # device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                # json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
+                # json_device_config : Dict = json_device.setdefault('device_config', {})
+                # json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
+                # json_device_config_rules.extend([
+                #     json_config_rule_set(
+                #         '/network_instance[{:s}]'.format(network_instance_name), {
+                #             'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
+                #             'route_distinguisher': route_distinguisher,
+                #             #'router_id': router_id, 'address_families': address_families,
+                #     }),
+                #     json_config_rule_set(
+                #         '/interface[{:s}]'.format(endpoint_uuid), {
+                #             'name': endpoint_uuid, 'description': network_interface_desc, 'mtu': mtu,
+                #     }),
+                #     json_config_rule_set(
+                #         '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
+                #             'name': endpoint_uuid, 'index': sub_interface_index,
+                #             'description': network_subinterface_desc, 'vlan_id': vlan_id,
+                #             'address_ip': address_ip, 'address_prefix': address_prefix,
+                #     }),
+                #     json_config_rule_set(
+                #         '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                #             'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
+                #             'subinterface': sub_interface_index,
+                #     }),
+                #     json_config_rule_set(
+                #         '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                #             'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
+                #     }),
+                #     json_config_rule_set(
+                #         '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                #             'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                #             'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+                #     }),
+                #     json_config_rule_set(
+                #         '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                #             network_instance_name), {
+                #             'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                #             'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                #             'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                #             network_instance_name, bgp_route_target), {
+                #             'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                #             'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                #             'policy_name': '{:s}_import'.format(network_instance_name),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                #             network_instance_name, '3'), {
+                #             'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                #             'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                #             'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+                #     }),
+                #     json_config_rule_set(
+                #         # pylint: disable=duplicate-string-formatting-argument
+                #         '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                #             network_instance_name, network_instance_name), {
+                #             'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                #             'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                #             network_instance_name, bgp_route_target), {
+                #             'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                #             'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                #             'policy_name': '{:s}_export'.format(network_instance_name),
+                #     }),
+                #     json_config_rule_set(
+                #         '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                #             network_instance_name, '3'), {
+                #             'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                #             'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                #             'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+                #     }),
+                #     json_config_rule_set(
+                #         # pylint: disable=duplicate-string-formatting-argument
+                #         '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                #             network_instance_name, network_instance_name), {
+                #             'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
+                #     }),
+                # ])
+                # self.__device_client.ConfigureDevice(Device(**json_device))
+                # results.append(True)
diff --git a/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py b/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py
index 316b2ef8739efadf3f9f40d76d4e698117cc505f..27cfb46e0375962140278c5952ebc94e0a1a2223 100644
--- a/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py
+++ b/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py
@@ -13,188 +13,65 @@
 # limitations under the License.
 
 import anytree, json, logging
-from typing import Any, Dict, List, Optional, Tuple, Union
-from common.orm.Database import Database
-from common.orm.HighLevel import get_object
-from common.orm.backend.Tools import key_to_str
-from common.proto.context_pb2 import Device
-from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from typing import Any, List, Optional, Tuple, Union
+from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, DeviceId, Service
+from common.tools.object_factory.Device import json_device_id
 from common.type_checkers.Checkers import chk_length, chk_type
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from service.service.database.ConfigModel import ORM_ConfigActionEnum, get_config_rules
-from service.service.database.ContextModel import ContextModel
-from service.service.database.DeviceModel import DeviceModel
-from service.service.database.ServiceModel import ServiceModel
 from service.service.service_handler_api._ServiceHandler import _ServiceHandler
 from service.service.service_handler_api.AnyTreeTools import TreeNode, delete_subnode, get_subnode, set_subnode_value
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from .ConfigRules import setup_config_rules, teardown_config_rules
 
 LOGGER = logging.getLogger(__name__)
 
 class L3NMEmulatedServiceHandler(_ServiceHandler):
     def __init__(   # pylint: disable=super-init-not-called
-        self, db_service : ServiceModel, database : Database, context_client : ContextClient,
-        device_client : DeviceClient, **settings
+        self, service : Service, task_executor : TaskExecutor, **settings
     ) -> None:
-        self.__db_service = db_service
-        self.__database = database
-        self.__context_client = context_client # pylint: disable=unused-private-member
-        self.__device_client = device_client
-
-        self.__db_context : ContextModel = get_object(self.__database, ContextModel, self.__db_service.context_fk)
-        str_service_key = key_to_str([self.__db_context.context_uuid, self.__db_service.service_uuid])
-        db_config = get_config_rules(self.__database, str_service_key, 'running')
+        self.__service = service
+        self.__task_executor = task_executor # pylint: disable=unused-private-member
         self.__resolver = anytree.Resolver(pathattr='name')
         self.__config = TreeNode('.')
-        for action, resource_key, resource_value in db_config:
-            if action == ORM_ConfigActionEnum.SET:
+        for config_rule in service.service_config.config_rules:
+            action = config_rule.action
+            if config_rule.WhichOneof('config_rule') != 'custom': continue
+            resource_key = config_rule.custom.resource_key
+            resource_value = config_rule.custom.resource_value
+            if action == ConfigActionEnum.CONFIGACTION_SET:
                 try:
                     resource_value = json.loads(resource_value)
                 except: # pylint: disable=bare-except
                     pass
                 set_subnode_value(self.__resolver, self.__config, resource_key, resource_value)
-            elif action == ORM_ConfigActionEnum.DELETE:
+            elif action == ConfigActionEnum.CONFIGACTION_DELETE:
                 delete_subnode(self.__resolver, self.__config, resource_key)
 
-    def SetEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
         chk_type('endpoints', endpoints, list)
         if len(endpoints) == 0: return []
 
-        service_uuid              = self.__db_service.service_uuid
-        service_short_uuid        = service_uuid.split('-')[-1]
-        network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
-        network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
-        network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
-
+        service_uuid = self.__service.service_id.service_uuid.uuid
         settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
-        if settings is None: raise Exception('Unable to retrieve service settings')
-        json_settings : Dict = settings.value
-        mtu                 = json_settings.get('mtu',                 1450 )    # 1512
-        #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
-        bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
-        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
 
         results = []
         for endpoint in endpoints:
             try:
                 chk_type('endpoint', endpoint, (tuple, list))
                 chk_length('endpoint', endpoint, min_length=2, max_length=3)
-                if len(endpoint) == 2:
-                    device_uuid, endpoint_uuid = endpoint
-                else:
-                    device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
+                device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
 
                 endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
-                if endpoint_settings is None:
-                    raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
-                        str(endpoint_settings_uri)))
-                json_endpoint_settings : Dict = endpoint_settings.value
-                #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
-                route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
-                sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
-                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
-                address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
-                address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
-                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
-                db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-                json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-                json_device_config : Dict = json_device.setdefault('device_config', {})
-                json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-                json_device_config_rules.extend([
-                    json_config_rule_set(
-                        '/network_instance[{:s}]'.format(network_instance_name), {
-                            'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
-                            'route_distinguisher': route_distinguisher,
-                            #'router_id': router_id, 'address_families': address_families,
-                    }),
-                    json_config_rule_set(
-                        '/interface[{:s}]'.format(endpoint_uuid), {
-                            'name': endpoint_uuid, 'description': network_interface_desc, 'mtu': mtu,
-                    }),
-                    json_config_rule_set(
-                        '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
-                            'name': endpoint_uuid, 'index': sub_interface_index,
-                            'description': network_subinterface_desc, 'vlan_id': vlan_id,
-                            'address_ip': address_ip, 'address_prefix': address_prefix,
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
-                            'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
-                            'subinterface': sub_interface_index,
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
-                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
-                            network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
-                            'policy_name': '{:s}_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
-                            network_instance_name, network_instance_name), {
-                            'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
-                            'policy_name': '{:s}_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
-                            network_instance_name, network_instance_name), {
-                            'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
-                    }),
-                ])
-                self.__device_client.ConfigureDevice(Device(**json_device))
+                json_config_rules = setup_config_rules(
+                    service_uuid, connection_uuid, device_uuid, endpoint_uuid, settings, endpoint_settings)
+
+                device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                for json_config_rule in json_config_rules:
+                    device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+                self.__task_executor.configure_device(device)
                 results.append(True)
             except Exception as e: # pylint: disable=broad-except
                 LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint)))
@@ -202,127 +79,32 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
 
         return results
 
-    def DeleteEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
+    def DeleteEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
         chk_type('endpoints', endpoints, list)
         if len(endpoints) == 0: return []
 
-        service_uuid              = self.__db_service.service_uuid
-        service_short_uuid        = service_uuid.split('-')[-1]
-        network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
-
+        service_uuid = self.__service.service_id.service_uuid.uuid
         settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
-        if settings is None: raise Exception('Unable to retrieve service settings')
-        json_settings : Dict = settings.value
-        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
 
         results = []
         for endpoint in endpoints:
             try:
                 chk_type('endpoint', endpoint, (tuple, list))
                 chk_length('endpoint', endpoint, min_length=2, max_length=3)
-                if len(endpoint) == 2:
-                    device_uuid, endpoint_uuid = endpoint
-                else:
-                    device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
+                device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
 
                 endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
-                if endpoint_settings is None:
-                    raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
-                        str(endpoint_settings_uri)))
-                json_endpoint_settings : Dict = endpoint_settings.value
-                sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
-                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
-                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
-                db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-                json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-                json_device_config : Dict = json_device.setdefault('device_config', {})
-                json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-                json_device_config_rules.extend([
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
-                            'name': network_instance_name, 'id': if_subif_name,
-                    }),
-                    json_config_rule_delete(
-                        '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
-                            'name': endpoint_uuid, 'index': sub_interface_index,
-                    }),
-                    json_config_rule_delete(
-                        '/interface[{:s}]'.format(endpoint_uuid), {
-                            'name': endpoint_uuid,
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
-                            network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4',
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4',
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
-                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
-                    }),
-                    json_config_rule_delete(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
-                            network_instance_name, network_instance_name), {
-                        'name': network_instance_name,
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
-                            'policy_name': '{:s}_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
-                            network_instance_name, network_instance_name), {
-                            'name': network_instance_name,
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
-                            'policy_name': '{:s}_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]'.format(network_instance_name), {
-                            'name': network_instance_name
-                    }),
-                ])
-                self.__device_client.ConfigureDevice(Device(**json_device))
+                json_config_rules = teardown_config_rules(
+                    service_uuid, connection_uuid, device_uuid, endpoint_uuid, settings, endpoint_settings)
+
+                device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                for json_config_rule in json_config_rules:
+                    device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+                self.__task_executor.configure_device(device)
                 results.append(True)
             except Exception as e: # pylint: disable=broad-except
                 LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint)))
diff --git a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py
index 1249af0ae7944f09bd12f2fab4e6e78523320c06..aeba6a26ab5d3fdc42925bcd9bda0a3c5790ece4 100644
--- a/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py
+++ b/src/service/service/service_handlers/tapi_tapi/TapiServiceHandler.py
@@ -14,58 +14,54 @@
 
 import anytree, json, logging
 from typing import Any, Dict, List, Optional, Tuple, Union
-from common.orm.Database import Database
 from common.orm.HighLevel import get_object
-from common.orm.backend.Tools import key_to_str
-from common.proto.context_pb2 import Device
+from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, Device, DeviceId, Service
 from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from common.tools.object_factory.Device import json_device_id
 from common.type_checkers.Checkers import chk_type
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from service.service.database.ConfigModel import ORM_ConfigActionEnum, get_config_rules
-from service.service.database.ContextModel import ContextModel
 from service.service.database.DeviceModel import DeviceModel
-from service.service.database.ServiceModel import ServiceModel
 from service.service.service_handler_api._ServiceHandler import _ServiceHandler
 from service.service.service_handler_api.AnyTreeTools import TreeNode, delete_subnode, get_subnode, set_subnode_value
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
 
 LOGGER = logging.getLogger(__name__)
 
 class TapiServiceHandler(_ServiceHandler):
     def __init__(   # pylint: disable=super-init-not-called
-        self, db_service : ServiceModel, database : Database, context_client : ContextClient,
-        device_client : DeviceClient, **settings
+        self, service : Service, task_executor : TaskExecutor, **settings
     ) -> None:
-        self.__db_service = db_service
-        self.__database = database
-        self.__context_client = context_client # pylint: disable=unused-private-member
-        self.__device_client = device_client
-
-        self.__db_context : ContextModel = get_object(self.__database, ContextModel, self.__db_service.context_fk)
-        str_service_key = key_to_str([self.__db_context.context_uuid, self.__db_service.service_uuid])
-        db_config = get_config_rules(self.__database, str_service_key, 'running')
+        self.__service = service
+        self.__task_executor = task_executor # pylint: disable=unused-private-member
         self.__resolver = anytree.Resolver(pathattr='name')
         self.__config = TreeNode('.')
-        for action, resource_key, resource_value in db_config:
-            if action == ORM_ConfigActionEnum.SET:
+        for config_rule in service.service_config.config_rules:
+            action = config_rule.action
+            if config_rule.WhichOneof('config_rule') != 'custom': continue
+            resource_key = config_rule.custom.resource_key
+            resource_value = config_rule.custom.resource_value
+            if action == ConfigActionEnum.CONFIGACTION_SET:
                 try:
                     resource_value = json.loads(resource_value)
                 except: # pylint: disable=bare-except
                     pass
                 set_subnode_value(self.__resolver, self.__config, resource_key, resource_value)
-            elif action == ORM_ConfigActionEnum.DELETE:
+            elif action == ConfigActionEnum.CONFIGACTION_DELETE:
                 delete_subnode(self.__resolver, self.__config, resource_key)
 
-    def SetEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        LOGGER.info('[SetEndpoint] endpoints={:s}'.format(str(endpoints)))
+        LOGGER.info('[SetEndpoint] connection_uuid={:s}'.format(str(connection_uuid)))
         chk_type('endpoints', endpoints, list)
         if len(endpoints) != 2: return []
 
-        service_uuid = self.__db_service.service_uuid
-        service_settings : TreeNode = get_subnode(self.__resolver, self.__config, 'settings', None)
-        if service_settings is None: raise Exception('Unable to settings for Service({:s})'.format(str(service_uuid)))
+        service_uuid = self.__service.service_id.service_uuid.uuid
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
+        if settings is None: raise Exception('Unable to retrieve settings for Service({:s})'.format(str(service_uuid)))
 
-        json_settings : Dict = service_settings.value
-        capacity_value   = json_settings.get('capacity_value',   1)
+        json_settings : Dict = settings.value
+        capacity_value   = json_settings.get('capacity_value',   50.0)
         capacity_unit    = json_settings.get('capacity_unit',    'GHz')
         layer_proto_name = json_settings.get('layer_proto_name', 'PHOTONIC_MEDIA')
         layer_proto_qual = json_settings.get('layer_proto_qual', 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC')
@@ -74,46 +70,44 @@ class TapiServiceHandler(_ServiceHandler):
         results = []
         try:
             device_uuid = endpoints[0][0]
-            db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-            json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-            json_device_config : Dict = json_device.setdefault('device_config', {})
-            json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-            json_device_config_rules.extend([
-                json_config_rule_set('/service[{:s}]'.format(service_uuid), {
-                    'uuid'                    : service_uuid,
-                    'input_sip'               : endpoints[0][1],
-                    'output_sip'              : endpoints[1][1],
-                    'capacity_unit'           : capacity_unit,
-                    'capacity_value'          : capacity_value,
-                    'layer_protocol_name'     : layer_proto_name,
-                    'layer_protocol_qualifier': layer_proto_qual,
-                    'direction'               : direction,
-                }),
-            ])
-            self.__device_client.ConfigureDevice(Device(**json_device))
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            json_config_rule = json_config_rule_set('/service[{:s}]'.format(service_uuid), {
+                'uuid'                    : service_uuid,
+                'input_sip'               : endpoints[0][1],
+                'output_sip'              : endpoints[1][1],
+                'capacity_unit'           : capacity_unit,
+                'capacity_value'          : capacity_value,
+                'layer_protocol_name'     : layer_proto_name,
+                'layer_protocol_qualifier': layer_proto_qual,
+                'direction'               : direction,
+            })
+            del device.device_config.config_rules[:]
+            device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+            self.__task_executor.configure_device(device)
             results.append(True)
         except Exception as e: # pylint: disable=broad-except
-            LOGGER.exception('Unable to SetEndpoint for Service({:s})'.format(str(service_uuid)))
+            LOGGER.exception('Unable to configure Service({:s})'.format(str(service_uuid)))
             results.append(e)
 
         return results
 
-    def DeleteEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
+    def DeleteEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        LOGGER.info('[DeleteEndpoint] endpoints={:s}'.format(str(endpoints)))
+        LOGGER.info('[DeleteEndpoint] connection_uuid={:s}'.format(str(connection_uuid)))
+
         chk_type('endpoints', endpoints, list)
         if len(endpoints) != 2: return []
 
-        service_uuid = self.__db_service.service_uuid
+        service_uuid = self.__service.service_id.service_uuid.uuid
         results = []
         try:
             device_uuid = endpoints[0][0]
-            db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-            json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-            json_device_config : Dict = json_device.setdefault('device_config', {})
-            json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-            json_device_config_rules.extend([
-                json_config_rule_delete('/service[{:s}]'.format(service_uuid), {'uuid': service_uuid})
-            ])
-            self.__device_client.ConfigureDevice(Device(**json_device))
+            device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+            json_config_rule = json_config_rule_delete('/service[{:s}]'.format(service_uuid), {'uuid': service_uuid})
+            device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+            self.__task_executor.configure_device(device)
             results.append(True)
         except Exception as e: # pylint: disable=broad-except
             LOGGER.exception('Unable to DeleteEndpoint for Service({:s})'.format(str(service_uuid)))
diff --git a/src/service/service/task_scheduler/ConnectionExpander.py b/src/service/service/task_scheduler/ConnectionExpander.py
new file mode 100644
index 0000000000000000000000000000000000000000..39c91b1ba7129d6915ab578f2e85b670049def04
--- /dev/null
+++ b/src/service/service/task_scheduler/ConnectionExpander.py
@@ -0,0 +1,66 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Dict, List, Optional, Tuple
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.proto.context_pb2 import Connection, Empty, EndPointId, Link
+from context.client.ContextClient import ContextClient
+
+class ConnectionExpander:
+    def __init__(self) -> None:
+        self.context_client = ContextClient()
+        self.endpointkey_to_link : Dict[Tuple[str, str], Link] = dict()
+        self.refresh_links()
+    
+    def refresh_links(self) -> None:
+        links = self.context_client.ListLinks(Empty())
+        for link in links.links:
+            for link_endpoint_id in link.link_endpoint_ids:
+                device_uuid = link_endpoint_id.device_id.device_uuid.uuid
+                endpoint_uuid = link_endpoint_id.endpoint_uuid.uuid
+                endpoint_key = (device_uuid, endpoint_uuid)
+                self.endpointkey_to_link[endpoint_key] = link
+
+    def get_link_from_endpoint_id(self, endpoint_id : EndPointId, raise_if_not_found : bool = False) -> Optional[Link]:
+        device_uuid = endpoint_id.device_id.device_uuid.uuid
+        endpoint_uuid = endpoint_id.endpoint_uuid.uuid
+        endpoint_key = (device_uuid, endpoint_uuid)
+        link = self.endpointkey_to_link.get(endpoint_key)
+        if link is None and raise_if_not_found:
+            str_endpoint_id = grpc_message_to_json_string(endpoint_id)
+            raise Exception('Link for Endpoint({:s}) not found'.format(str_endpoint_id))
+        return link
+
+    def get_links(self, connection : Connection) -> List[Link]:
+        path_links = list()
+        last_link_uuid = None
+        for endpoint_id in connection.path_hops_endpoint_ids:
+            link = self.get_link_from_endpoint_id(endpoint_id, raise_if_not_found=True)
+            link_uuid = link.link_id.link_uuid.uuid
+            if last_link_uuid is None or last_link_uuid != link_uuid:
+                path_links.append(link)
+                last_link_uuid = link_uuid
+        return path_links
+
+    def get_endpoints_traversed(self, connection : Connection) -> List[EndPointId]:
+        path_endpoint_ids = list()
+        last_link_uuid = None
+        for endpoint_id in connection.path_hops_endpoint_ids:
+            link = self.get_link_from_endpoint_id(endpoint_id, raise_if_not_found=True)
+            link_uuid = link.link_id.link_uuid.uuid
+            if last_link_uuid is None or last_link_uuid != link_uuid:
+                for link_endpoint_id in link.link_endpoint_ids:
+                    path_endpoint_ids.append(link_endpoint_id)
+                last_link_uuid = link_uuid
+        return path_endpoint_ids
diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py
new file mode 100644
index 0000000000000000000000000000000000000000..416e1698f2432e22ae5cfe8e437570fc7d3c8880
--- /dev/null
+++ b/src/service/service/task_scheduler/TaskExecutor.py
@@ -0,0 +1,142 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from enum import Enum
+from typing import Any, Dict, Optional, Union
+from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceId, Service, ServiceId
+from common.rpc_method_wrapper.ServiceExceptions import NotFoundException
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory, get_service_handler_class
+from service.service.tools.ContextGetters import get_connection, get_device, get_service
+from service.service.tools.ObjectKeys import get_connection_key, get_device_key, get_service_key
+
+CacheableObject = Union[Connection, Device, Service]
+
+class CacheableObjectType(Enum):
+    CONNECTION = 'connection'
+    DEVICE     = 'device'
+    SERVICE    = 'service'
+
+class TaskExecutor:
+    def __init__(self, service_handler_factory : ServiceHandlerFactory) -> None:
+        self._service_handler_factory = service_handler_factory
+        self._context_client = ContextClient()
+        self._device_client = DeviceClient()
+        self._grpc_objects_cache : Dict[str, CacheableObject] = dict()
+
+    @property
+    def service_handler_factory(self) -> ServiceHandlerFactory: return self._service_handler_factory
+
+    # ----- Common methods ---------------------------------------------------------------------------------------------
+
+    def _load_grpc_object(self, object_type : CacheableObjectType, object_key : str) -> Optional[CacheableObject]:
+        object_key = '{:s}:{:s}'.format(object_type.value, object_key)
+        return self._grpc_objects_cache.get(object_key)
+
+    def _store_grpc_object(self, object_type : CacheableObjectType, object_key : str, grpc_object) -> None:
+        object_key = '{:s}:{:s}'.format(object_type.value, object_key)
+        self._grpc_objects_cache[object_key] = grpc_object
+    
+    def _delete_grpc_object(self, object_type : CacheableObjectType, object_key : str) -> None:
+        object_key = '{:s}:{:s}'.format(object_type.value, object_key)
+        self._grpc_objects_cache.pop(object_key, None)
+
+    def _store_editable_grpc_object(
+        self, object_type : CacheableObjectType, object_key : str, grpc_class, grpc_ro_object
+    ) -> Any:
+        grpc_rw_object = grpc_class()
+        grpc_rw_object.CopyFrom(grpc_ro_object)
+        self._store_grpc_object(object_type, object_key, grpc_rw_object)
+        return grpc_rw_object
+
+    # ----- Connection-related methods ---------------------------------------------------------------------------------
+
+    def get_connection(self, connection_id : ConnectionId) -> Connection:
+        connection_key = get_connection_key(connection_id)
+        connection = self._load_grpc_object(CacheableObjectType.CONNECTION, connection_key)
+        if connection is None:
+            connection = get_connection(self._context_client, connection_id)
+            if connection is None: raise NotFoundException('Connection', connection_key)
+            connection : Connection = self._store_editable_grpc_object(
+                CacheableObjectType.CONNECTION, connection_key, Connection, connection)
+        return connection
+
+    def set_connection(self, connection : Connection) -> None:
+        connection_key = get_connection_key(connection.connection_id)
+        self._context_client.SetConnection(connection)
+        self._store_grpc_object(CacheableObjectType.CONNECTION, connection_key, connection)
+
+    def delete_connection(self, connection_id : ConnectionId) -> None:
+        connection_key = get_connection_key(connection_id)
+        self._context_client.RemoveConnection(connection_id)
+        self._delete_grpc_object(CacheableObjectType.CONNECTION, connection_key)
+
+    # ----- Device-related methods -------------------------------------------------------------------------------------
+
+    def get_device(self, device_id : DeviceId) -> Device:
+        device_key = get_device_key(device_id)
+        device = self._load_grpc_object(CacheableObjectType.DEVICE, device_key)
+        if device is None:
+            device = get_device(self._context_client, device_id)
+            if device is None: raise NotFoundException('Device', device_key)
+            device : Device = self._store_editable_grpc_object(
+                CacheableObjectType.DEVICE, device_key, Device, device)
+        return device
+
+    def configure_device(self, device : Device) -> None:
+        device_key = get_device_key(device.device_id)
+        self._device_client.ConfigureDevice(device)
+        self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device)
+
+    def get_devices_from_connection(self, connection : Connection) -> Dict[str, Device]:
+        devices = dict()
+        for endpoint_id in connection.path_hops_endpoint_ids:
+            device = self.get_device(endpoint_id.device_id)
+            device_uuid = endpoint_id.device_id.device_uuid.uuid
+            if device is None: raise Exception('Device({:s}) not found'.format(str(device_uuid)))
+            devices[device_uuid] = device
+        return devices
+
+    # ----- Service-related methods ------------------------------------------------------------------------------------
+
+    def get_service(self, service_id : ServiceId) -> Service:
+        service_key = get_service_key(service_id)
+        service = self._load_grpc_object(CacheableObjectType.SERVICE, service_key)
+        if service is None:
+            service = get_service(self._context_client, service_id)
+            if service is None: raise NotFoundException('Service', service_key)
+            service : service = self._store_editable_grpc_object(
+                CacheableObjectType.SERVICE, service_key, Service, service)
+        return service
+
+    def set_service(self, service : Service) -> None:
+        service_key = get_service_key(service.service_id)
+        self._context_client.SetService(service)
+        self._store_grpc_object(CacheableObjectType.SERVICE, service_key, service)
+
+    def delete_service(self, service_id : ServiceId) -> None:
+        service_key = get_service_key(service_id)
+        self._context_client.RemoveService(service_id)
+        self._delete_grpc_object(CacheableObjectType.SERVICE, service_key)
+
+    # ----- Service Handler Factory ------------------------------------------------------------------------------------
+
+    def get_service_handler(
+        self, connection : Connection, service : Service, **service_handler_settings
+    ) -> _ServiceHandler:
+        connection_devices = self.get_devices_from_connection(connection)
+        service_handler_class = get_service_handler_class(self._service_handler_factory, service, connection_devices)
+        return service_handler_class(service, self, **service_handler_settings)
diff --git a/src/service/service/task_scheduler/TaskScheduler.py b/src/service/service/task_scheduler/TaskScheduler.py
new file mode 100644
index 0000000000000000000000000000000000000000..de7e9eb7a70e683051e9d2fd906252713dcdba54
--- /dev/null
+++ b/src/service/service/task_scheduler/TaskScheduler.py
@@ -0,0 +1,210 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 graphlib, logging, queue, time
+from typing import Dict, Tuple
+from common.proto.context_pb2 import Connection, ConnectionId, Service, ServiceId, ServiceStatusEnum
+from common.proto.pathcomp_pb2 import PathCompReply
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
+from service.service.tools.ObjectKeys import get_connection_key, get_service_key
+from .tasks._Task import _Task
+from .tasks.Task_ConnectionConfigure import Task_ConnectionConfigure
+from .tasks.Task_ConnectionDeconfigure import Task_ConnectionDeconfigure
+from .tasks.Task_ServiceDelete import Task_ServiceDelete
+from .tasks.Task_ServiceSetStatus import Task_ServiceSetStatus
+from .TaskExecutor import CacheableObjectType, TaskExecutor
+
+LOGGER = logging.getLogger(__name__)
+
+class TasksScheduler:
+    def __init__(self, service_handler_factory : ServiceHandlerFactory) -> None:
+        self._dag = graphlib.TopologicalSorter()
+        self._executor = TaskExecutor(service_handler_factory)
+        self._tasks : Dict[str, _Task] = dict()
+        self._context_client = ContextClient()
+
+    # ----- Helper methods ---------------------------------------------------------------------------------------------
+
+    def _add_task_if_not_exists(self, task : _Task) -> str:
+        task_key = task.key
+        if task_key not in self._tasks:
+            self._tasks[task_key] = task
+        return task_key
+
+    def _add_connection_to_executor_cache(self, connection : Connection) -> None:
+        connection_key = get_connection_key(connection.connection_id)
+        self._executor._store_editable_grpc_object(
+            CacheableObjectType.CONNECTION, connection_key, Connection, connection)
+
+    def _add_service_to_executor_cache(self, service : Service) -> None:
+        service_key = get_service_key(service.service_id)
+        self._executor._store_editable_grpc_object(
+            CacheableObjectType.SERVICE, service_key, Service, service)
+
+    # ----- Task & DAG composition methods -----------------------------------------------------------------------------
+
+    def _service_create(self, service_id : ServiceId) -> Tuple[str, str]:
+        service_planned_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PLANNED))
+
+        service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE))
+
+        # activating a service requires the service is in planning state
+        self._dag.add(service_active_key, service_planned_key)
+        return service_planned_key, service_active_key
+
+    def _service_remove(self, service_id : ServiceId) -> Tuple[str, str]:
+        service_removing_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL))
+
+        service_delete_key = self._add_task_if_not_exists(Task_ServiceDelete(self._executor, service_id))
+
+        # deleting a service requires the service is in removing state
+        self._dag.add(service_delete_key, service_removing_key)
+        return service_removing_key, service_delete_key
+
+    def _connection_configure(self, connection_id : ConnectionId, service_id : ServiceId) -> str:
+        connection_configure_key = self._add_task_if_not_exists(Task_ConnectionConfigure(
+            self._executor, connection_id))
+
+        # the connection configuration depends on its connection's service being in planning state
+        service_planned_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PLANNED))
+        self._dag.add(connection_configure_key, service_planned_key)
+
+        # the connection's service depends on the connection configuration to transition to active state
+        service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE))
+        self._dag.add(service_active_key, connection_configure_key)
+
+        return connection_configure_key
+
+    def _connection_deconfigure(self, connection_id : ConnectionId, service_id : ServiceId) -> str:
+        connection_deconfigure_key = self._add_task_if_not_exists(Task_ConnectionDeconfigure(
+            self._executor, connection_id))
+
+        # the connection deconfiguration depends on its connection's service being in removing state
+        service_pending_removal_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL))
+        self._dag.add(connection_deconfigure_key, service_pending_removal_key)
+
+        # the connection's service depends on the connection deconfiguration to transition to delete
+        service_delete_key = self._add_task_if_not_exists(Task_ServiceDelete(
+            self._executor, service_id))
+        self._dag.add(service_delete_key, connection_deconfigure_key)
+
+        return connection_deconfigure_key
+
+    def compose_from_pathcompreply(self, pathcomp_reply : PathCompReply, is_delete : bool = False) -> None:
+        t0 = time.time()
+        include_service = self._service_remove if is_delete else self._service_create
+        include_connection = self._connection_deconfigure if is_delete else self._connection_configure
+
+        for service in pathcomp_reply.services:
+            include_service(service.service_id)
+            self._add_service_to_executor_cache(service)
+
+        for connection in pathcomp_reply.connections:
+            connection_key = include_connection(connection.connection_id, connection.service_id)
+            self._add_connection_to_executor_cache(connection)
+            self._executor.get_service(connection.service_id)
+            for sub_service_id in connection.sub_service_ids:
+                _,service_key_done = include_service(sub_service_id)
+                self._executor.get_service(sub_service_id)
+                self._dag.add(connection_key, service_key_done)
+
+        t1 = time.time()
+        LOGGER.info('[compose_from_pathcompreply] elapsed_time: {:f} sec'.format(t1-t0))
+
+    def compose_from_service(self, service : Service, is_delete : bool = False) -> None:
+        t0 = time.time()
+        include_service = self._service_remove if is_delete else self._service_create
+        include_connection = self._connection_deconfigure if is_delete else self._connection_configure
+
+        explored_items = set()
+        pending_items_to_explore = queue.Queue()
+        pending_items_to_explore.put(service)
+
+        while not pending_items_to_explore.empty():
+            try:
+                item = pending_items_to_explore.get(block=False)
+            except queue.Empty:
+                break
+
+            if isinstance(item, Service):
+                str_item_key = grpc_message_to_json_string(item.service_id)
+                if str_item_key in explored_items: continue
+
+                include_service(item.service_id)
+                self._add_service_to_executor_cache(item)
+                connections = self._context_client.ListConnections(item.service_id)
+                for connection in connections.connections:
+                    self._add_connection_to_executor_cache(connection)
+                    pending_items_to_explore.put(connection)
+
+                explored_items.add(str_item_key)
+
+            elif isinstance(item, ServiceId):
+                str_item_key = grpc_message_to_json_string(item)
+                if str_item_key in explored_items: continue
+
+                include_service(item)
+                self._executor.get_service(item)
+                connections = self._context_client.ListConnections(item)
+                for connection in connections.connections:
+                    self._add_connection_to_executor_cache(connection)
+                    pending_items_to_explore.put(connection)
+
+                explored_items.add(str_item_key)
+
+            elif isinstance(item, Connection):
+                str_item_key = grpc_message_to_json_string(item.connection_id)
+                if str_item_key in explored_items: continue
+
+                connection_key = include_connection(item.connection_id, item.service_id)
+                self._add_connection_to_executor_cache(connection)
+
+                self._executor.get_service(item.service_id)
+                pending_items_to_explore.put(item.service_id)
+
+                for sub_service_id in item.sub_service_ids:
+                    _,service_key_done = include_service(sub_service_id)
+                    self._executor.get_service(sub_service_id)
+                    self._dag.add(service_key_done, connection_key)
+                    pending_items_to_explore.put(sub_service_id)
+
+                explored_items.add(str_item_key)
+
+            else:
+                MSG = 'Unsupported item {:s}({:s})'
+                raise Exception(MSG.format(type(item).__name__, grpc_message_to_json_string(item)))
+
+        t1 = time.time()
+        LOGGER.info('[compose_from_service] elapsed_time: {:f} sec'.format(t1-t0))
+
+    def execute_all(self, dry_run : bool = False) -> None:
+        ordered_task_keys = list(self._dag.static_order())
+        LOGGER.info('[execute_all] ordered_task_keys={:s}'.format(str(ordered_task_keys)))
+
+        results = []
+        for task_key in ordered_task_keys:
+            task = self._tasks.get(task_key)
+            succeeded = True if dry_run else task.execute()
+            results.append(succeeded)
+
+        LOGGER.info('[execute_all] results={:s}'.format(str(results)))
+        return zip(ordered_task_keys, results)
diff --git a/src/service/service/task_scheduler/__init__.py b/src/service/service/task_scheduler/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70bfa5118f47eb93d5cdd0832ee7928030369286
--- /dev/null
+++ b/src/service/service/task_scheduler/__init__.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.
+
+# TaskScheduler is initialized with a PathComputation Reply or a Service, and it collects/identifies the sub-services,
+# sub-connections, and operations associated to them. It discovers and takes care of the inter-dependencies among them,
+# and produces an ordered list of tasks to be executed to implement the desired create/delete operation on the service.
+# E.g., a service cannot be deleted if connections supporting that service still exist. If these connections are
+# supported by sub-services, the connection needs to be torn down before destroying the services.
+#
+# Internally, it composes a Directed Acyclic Graph (DAG) of dependencies between tasks. Each task performs a specific
+# operation on a connection or service. The DAG composition is based on information extracted from a PathComp reply
+# and/or interrogating the Context component.
+#
+# Example:
+#   A        B        C
+#   *---L3---*---L3---*
+#    *--L0--* *--L0--*
+# - L3 service between A and C, depends on L3 connections A-B and B-C.
+# - Each L3 connection is supported by an L0 service and its corresponding L0 connection.
+#
+# Dependency structure:
+#   service L3:A-C
+#       connection L3:A-B
+#           service L0:A-B
+#               connection L0:A-B
+#       connection L3:B-C
+#           service L0:B-C
+#               connection L0:B-C
+#
+# Resolution:
+#    - service.set(L3:A-C, state=PLANNING)
+#    - service.set(L0:A-B, state=PLANNING)
+#    - connection.configure(L0:A-B)
+#    - service.set(L0:A-B, state=ACTIVE)
+#    - connection.configure(L3:A-B)
+#    - service.set(L0:B-C, state=PLANNING)
+#    - connection.configure(L0:B-C)
+#    - service.set(L0:B-C, state=ACTIVE)
+#    - connection.configure(L3:B-C)
+#    - service.set(L3:A-C, state=ACTIVE)
diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.py
new file mode 100644
index 0000000000000000000000000000000000000000..beb7e5a0426b7705dbf780d8305a587a3d4fec14
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/Task_ConnectionConfigure.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.
+
+from common.proto.context_pb2 import ConnectionId
+from common.rpc_method_wrapper.ServiceExceptions import OperationFailedException
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from service.service.service_handler_api.Tools import check_errors_setendpoint
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from service.service.tools.EndpointIdFormatters import endpointids_to_raw
+from service.service.tools.ObjectKeys import get_connection_key
+from ._Task import _Task
+
+KEY_TEMPLATE = 'connection({connection_id:s}):configure'
+
+class Task_ConnectionConfigure(_Task):
+    def __init__(self, task_executor : TaskExecutor, connection_id : ConnectionId) -> None:
+        super().__init__(task_executor)
+        self._connection_id = connection_id
+
+    @property
+    def connection_id(self) -> ConnectionId: return self._connection_id
+
+    @staticmethod
+    def build_key(connection_id : ConnectionId) -> str:
+        str_connection_id = get_connection_key(connection_id)
+        return KEY_TEMPLATE.format(connection_id=str_connection_id)
+
+    @property
+    def key(self) -> str: return self.build_key(self._connection_id)
+
+    def execute(self) -> None:
+        connection = self._task_executor.get_connection(self._connection_id)
+        service = self._task_executor.get_service(connection.service_id)
+
+        service_handler_settings = {}
+        service_handler = self._task_executor.get_service_handler(connection, service, **service_handler_settings)
+
+        endpointids_to_set = endpointids_to_raw(connection.path_hops_endpoint_ids)
+        connection_uuid = connection.connection_id.connection_uuid.uuid
+        results_setendpoint = service_handler.SetEndpoint(endpointids_to_set, connection_uuid=connection_uuid)
+        errors = check_errors_setendpoint(endpointids_to_set, results_setendpoint)
+        if len(errors) > 0:
+            MSG = 'SetEndpoint for Connection({:s}) from Service({:s})'
+            str_connection = grpc_message_to_json_string(connection)
+            str_service = grpc_message_to_json_string(service)
+            raise OperationFailedException(MSG.format(str_connection, str_service), extra_details=errors)
+
+        self._task_executor.set_connection(connection)
diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py
new file mode 100644
index 0000000000000000000000000000000000000000..c04d950a8993166c3bbfab3c083d4f2898dcd3e8
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.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.
+
+from common.proto.context_pb2 import ConnectionId
+from common.rpc_method_wrapper.ServiceExceptions import OperationFailedException
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from service.service.service_handler_api.Tools import check_errors_deleteendpoint
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from service.service.tools.EndpointIdFormatters import endpointids_to_raw
+from service.service.tools.ObjectKeys import get_connection_key
+from ._Task import _Task
+
+KEY_TEMPLATE = 'connection({connection_id:s}):deconfigure'
+
+class Task_ConnectionDeconfigure(_Task):
+    def __init__(self, task_executor : TaskExecutor, connection_id : ConnectionId) -> None:
+        super().__init__(task_executor)
+        self._connection_id = connection_id
+
+    @property
+    def connection_id(self) -> ConnectionId: return self._connection_id
+
+    @staticmethod
+    def build_key(connection_id : ConnectionId) -> str:
+        str_connection_id = get_connection_key(connection_id)
+        return KEY_TEMPLATE.format(connection_id=str_connection_id)
+
+    @property
+    def key(self) -> str: return self.build_key(self._connection_id)
+
+    def execute(self) -> None:
+        connection = self._task_executor.get_connection(self._connection_id)
+        service = self._task_executor.get_service(connection.service_id)
+
+        service_handler_settings = {}
+        service_handler = self._task_executor.get_service_handler(connection, service, **service_handler_settings)
+
+        endpointids_to_delete = endpointids_to_raw(connection.path_hops_endpoint_ids)
+        connection_uuid = connection.connection_id.connection_uuid.uuid
+        results_deleteendpoint = service_handler.DeleteEndpoint(endpointids_to_delete, connection_uuid=connection_uuid)
+        errors = check_errors_deleteendpoint(endpointids_to_delete, results_deleteendpoint)
+        if len(errors) > 0:
+            MSG = 'DeleteEndpoint for Connection({:s}) from Service({:s})'
+            str_connection = grpc_message_to_json_string(connection)
+            str_service = grpc_message_to_json_string(service)
+            raise OperationFailedException(MSG.format(str_connection, str_service), extra_details=errors)
+
+        self._task_executor.delete_connection(self._connection_id)
diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py
new file mode 100644
index 0000000000000000000000000000000000000000..15da1ffedbb3235e6697dcd6c4b0c0429cad0450
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/Task_ServiceDelete.py
@@ -0,0 +1,39 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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.proto.context_pb2 import ServiceId
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from service.service.tools.ObjectKeys import get_service_key
+from ._Task import _Task
+
+KEY_TEMPLATE = 'service({service_id:s}):delete'
+
+class Task_ServiceDelete(_Task):
+    def __init__(self, task_executor : TaskExecutor, service_id : ServiceId) -> None:
+        super().__init__(task_executor)
+        self._service_id = service_id
+
+    @property
+    def service_id(self) -> ServiceId: return self._service_id
+
+    @staticmethod
+    def build_key(service_id : ServiceId) -> str:
+        str_service_id = get_service_key(service_id)
+        return KEY_TEMPLATE.format(service_id=str_service_id)
+
+    @property
+    def key(self) -> str: return self.build_key(self._service_id)
+
+    def execute(self) -> None:
+        self._task_executor.delete_service(self._service_id)
diff --git a/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.py
new file mode 100644
index 0000000000000000000000000000000000000000..163954f1b786916ad8c5fde5e8a04def84af259b
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/Task_ServiceSetStatus.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.proto.context_pb2 import ServiceId, ServiceStatusEnum
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from service.service.tools.ObjectKeys import get_service_key
+from ._Task import _Task
+
+KEY_TEMPLATE = 'service({service_id:s}):set_status({new_status:s})'
+
+class Task_ServiceSetStatus(_Task):
+    def __init__(self, task_executor : TaskExecutor, service_id : ServiceId, new_status : ServiceStatusEnum) -> None:
+        super().__init__(task_executor)
+        self._service_id = service_id
+        self._new_status = new_status
+
+    @property
+    def service_id(self) -> ServiceId: return self._service_id
+
+    @property
+    def new_status(self) -> ServiceStatusEnum: return self._new_status
+
+    @staticmethod
+    def build_key(service_id : ServiceId, new_status : ServiceStatusEnum) -> str:
+        str_service_id = get_service_key(service_id)
+        str_new_status = ServiceStatusEnum.Name(new_status)
+        return KEY_TEMPLATE.format(service_id=str_service_id, new_status=str_new_status)
+
+    @property
+    def key(self) -> str: return self.build_key(self._service_id, self._new_status)
+
+    def execute(self) -> None:
+        service = self._task_executor.get_service(self._service_id)
+        service.service_status.service_status = self._new_status
+        self._task_executor.set_service(service)
diff --git a/src/service/service/task_scheduler/tasks/_Task.py b/src/service/service/task_scheduler/tasks/_Task.py
new file mode 100644
index 0000000000000000000000000000000000000000..c36f92973bfa3847c86d2d745792062ec828492f
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/_Task.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 service.service.task_scheduler.TaskExecutor import TaskExecutor
+
+class _Task:
+    def __init__(self, task_executor : TaskExecutor) -> None:
+        self._task_executor = task_executor
+
+    @staticmethod
+    def build_key() -> str:
+        raise NotImplementedError('Task:build_key() not implemented')
+
+    @property
+    def key(self) -> str:
+        raise NotImplementedError('Task:key() not implemented')
+
+    def execute(self) -> bool:
+        raise NotImplementedError('Task:execute() not implemented')
diff --git a/src/service/service/task_scheduler/tasks/__init__.py b/src/service/service/task_scheduler/tasks/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/__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/service/service/tools/ContextGetters.py b/src/service/service/tools/ContextGetters.py
new file mode 100644
index 0000000000000000000000000000000000000000..79ccf956b26e914bfbe6bdedd005d9f98e216d38
--- /dev/null
+++ b/src/service/service/tools/ContextGetters.py
@@ -0,0 +1,42 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 typing import Optional
+from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceId, Service, ServiceId
+from context.client.ContextClient import ContextClient
+
+def get_connection(context_client : ContextClient, connection_id : ConnectionId) -> Optional[Connection]:
+    try:
+        connection : Connection = context_client.GetConnection(connection_id)
+        return connection
+    except grpc.RpcError as e:
+        if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member
+        return None
+
+def get_device(context_client : ContextClient, device_id : DeviceId) -> Optional[Device]:
+    try:
+        device : Device = context_client.GetDevice(device_id)
+        return device
+    except grpc.RpcError as e:
+        if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member
+        return None
+
+def get_service(context_client : ContextClient, service_id : ServiceId) -> Optional[Service]:
+    try:
+        service : Service = context_client.GetService(service_id)
+        return service
+    except grpc.RpcError as e:
+        if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member
+        return None
diff --git a/src/service/service/tools/EndpointIdFormatters.py b/src/service/service/tools/EndpointIdFormatters.py
new file mode 100644
index 0000000000000000000000000000000000000000..2435df42cfa10d336553945e7e70171838f69237
--- /dev/null
+++ b/src/service/service/tools/EndpointIdFormatters.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 typing import List, Optional, Tuple
+from common.proto.context_pb2 import EndPointId
+
+def endpointids_to_raw(traversed_endpoint_ids : List[EndPointId]) -> List[Tuple[str, str, Optional[str]]]:
+    raw_endpoint_ids : List[Tuple[str, str, Optional[str]]] = []
+    for endpoint_id in traversed_endpoint_ids:
+        device_uuid   = endpoint_id.device_id.device_uuid.uuid
+        endpoint_uuid = endpoint_id.endpoint_uuid.uuid
+        topology_uuid = endpoint_id.topology_id.topology_uuid.uuid
+        if len(topology_uuid) == 0: topology_uuid = None
+        endpoint_id_tuple = device_uuid, endpoint_uuid, topology_uuid
+        raw_endpoint_ids.append(endpoint_id_tuple)
+    return raw_endpoint_ids
diff --git a/src/service/service/tools/ObjectKeys.py b/src/service/service/tools/ObjectKeys.py
new file mode 100644
index 0000000000000000000000000000000000000000..e58d8bd3e9e5c992a3b9be9c3275f3b40c7ba5e9
--- /dev/null
+++ b/src/service/service/tools/ObjectKeys.py
@@ -0,0 +1,26 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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.proto.context_pb2 import ConnectionId, DeviceId, ServiceId
+
+def get_connection_key(connection_id : ConnectionId) -> str:
+    return connection_id.connection_uuid.uuid
+
+def get_device_key(device_id : DeviceId) -> str:
+    return device_id.device_uuid.uuid
+
+def get_service_key(service_id : ServiceId) -> str:
+    context_uuid = service_id.context_id.context_uuid.uuid
+    service_uuid = service_id.service_uuid.uuid
+    return '{:s}/{:s}'.format(context_uuid, service_uuid)
diff --git a/src/service/service/tools/__init__.py b/src/service/service/tools/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/service/service/tools/__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/service/tests/ServiceHandler_L3NM_EMU.py b/src/service/tests/ServiceHandler_L3NM_EMU.py
index 0ac5fbf24cf1937104646374f60ab9487ee1c84d..45df80e4265018e802be587285fce318fc6b0736 100644
--- a/src/service/tests/ServiceHandler_L3NM_EMU.py
+++ b/src/service/tests/ServiceHandler_L3NM_EMU.py
@@ -14,7 +14,7 @@
 
 from typing import Dict, List, Tuple
 from common.tools.object_factory.ConfigRule import json_config_rule_set
-from common.tools.object_factory.Constraint import json_constraint
+from common.tools.object_factory.Constraint import json_constraint_custom
 from common.tools.object_factory.Device import (
     json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled, json_device_id)
 from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
@@ -101,8 +101,8 @@ SERVICE_R1_R3_UUID         = 'SVC:{:s}/{:s}-{:s}/{:s}'.format(
     DEVICE_R3_UUID, ENDPOINT_ID_R3_EP100['endpoint_uuid']['uuid'])
 SERVICE_R1_R3_ENDPOINT_IDS = [ENDPOINT_ID_R1_EP100, ENDPOINT_ID_R3_EP100]
 SERVICE_R1_R3_CONSTRAINTS  = [
-    json_constraint('latency_ms', 15.2),
-    json_constraint('jitter_us', 1.2),
+    json_constraint_custom('latency_ms', 15.2),
+    json_constraint_custom('jitter_us', 1.2),
 ]
 SERVICE_R1_R3_CONFIG_RULES = [
     json_config_rule_set(
diff --git a/src/service/tests/ServiceHandler_L3NM_OC.py b/src/service/tests/ServiceHandler_L3NM_OC.py
index 0797a4af5505e78e2af49cefc29970f9c8ff11e7..717536f6d1ee60564752f3107cd366796e3a36e2 100644
--- a/src/service/tests/ServiceHandler_L3NM_OC.py
+++ b/src/service/tests/ServiceHandler_L3NM_OC.py
@@ -15,7 +15,7 @@
 import uuid
 from typing import Dict, List, Tuple
 from common.tools.object_factory.ConfigRule import json_config_rule_set
-from common.tools.object_factory.Constraint import json_constraint
+from common.tools.object_factory.Constraint import json_constraint_custom
 from common.tools.object_factory.Device import (
     json_device_connect_rules, json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled,
     json_device_id)
@@ -115,8 +115,8 @@ SERVICE_R1_R2_UUID         = 'SVC:{:s}/{:s}-{:s}/{:s}'.format(
     DEVICE_R2_UUID, ENDPOINT_ID_R2_EP100['endpoint_uuid']['uuid'])
 SERVICE_R1_R2_ENDPOINT_IDS = [ENDPOINT_ID_R1_EP100, ENDPOINT_ID_R2_EP100]
 SERVICE_R1_R2_CONSTRAINTS  = [
-    json_constraint('latency_ms', 15.2),
-    json_constraint('jitter_us', 1.2),
+    json_constraint_custom('latency_ms', 15.2),
+    json_constraint_custom('jitter_us', 1.2),
 ]
 SERVICE_R1_R2_CONFIG_RULES = [
     json_config_rule_set(
diff --git a/src/service/tests/test_unitary_task_scheduler.py b/src/service/tests/test_unitary_task_scheduler.py
new file mode 100644
index 0000000000000000000000000000000000000000..020386d764ddc508d8fe6806ab1de6887620e33f
--- /dev/null
+++ b/src/service/tests/test_unitary_task_scheduler.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
+#from common.proto.context_pb2 import Connection, Service
+from common.proto.pathcomp_pb2 import PathCompReply
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
+from service.service.task_scheduler.TaskScheduler import TasksScheduler
+from .PrepareTestScenario import context_client # pylint: disable=unused-import
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def test_task_scheduler():
+    # test: add services and connections that depend on each other
+    #       then, check if they are properly resolved.
+    # - service MAIN, depends on connection PKT-1, TAPI, and PKT-2
+    # - connection PKT-1, depends on nothing
+    # - connection TAPI, depends on service TAPI-1 and TAPI-2
+    # - connection PKT-2, depends on nothing
+    # - service TAPI-1, depends on connection TAPI-1
+    # - service TAPI-2, depends on connection TAPI-2
+
+    pathcomp_reply = PathCompReply()
+
+    service_main = pathcomp_reply.services.add()
+    service_main.service_id.context_id.context_uuid.uuid = 'admin'
+    service_main.service_id.service_uuid.uuid = 'MAIN'
+
+    service_tapi1 = pathcomp_reply.services.add()
+    service_tapi1.service_id.context_id.context_uuid.uuid = 'admin'
+    service_tapi1.service_id.service_uuid.uuid = 'TAPI-1'
+
+    service_tapi2 = pathcomp_reply.services.add()
+    service_tapi2.service_id.context_id.context_uuid.uuid = 'admin'
+    service_tapi2.service_id.service_uuid.uuid = 'TAPI-2'
+
+    connection_pkt1 = pathcomp_reply.connections.add()
+    connection_pkt1.connection_id.connection_uuid.uuid = 'PKT-1'
+    connection_pkt1.service_id.CopyFrom(service_main.service_id)
+
+    connection_tapi = pathcomp_reply.connections.add()
+    connection_tapi.connection_id.connection_uuid.uuid = 'TAPI'
+    connection_tapi.service_id.CopyFrom(service_main.service_id)
+
+    connection_pkt2 = pathcomp_reply.connections.add()
+    connection_pkt2.connection_id.connection_uuid.uuid = 'PKT-2'
+    connection_pkt2.service_id.CopyFrom(service_main.service_id)
+
+    connection_tapi1 = pathcomp_reply.connections.add()
+    connection_tapi1.connection_id.connection_uuid.uuid = 'TAPI-1'
+    connection_tapi1.service_id.CopyFrom(service_tapi1.service_id)
+    connection_tapi.sub_service_ids.append(service_tapi1.service_id)
+
+    connection_tapi2 = pathcomp_reply.connections.add()
+    connection_tapi2.connection_id.connection_uuid.uuid = 'TAPI-2'
+    connection_tapi2.service_id.CopyFrom(service_tapi2.service_id)
+    connection_tapi.sub_service_ids.append(service_tapi2.service_id)
+
+    LOGGER.info('pathcomp_reply={:s}'.format(grpc_message_to_json_string(pathcomp_reply)))
+
+    service_handler_factory = ServiceHandlerFactory([])
+    task_scheduler = TasksScheduler(service_handler_factory)
+    task_scheduler.compose_from_pathcompreply(pathcomp_reply)
+    tasks_and_results = list(task_scheduler.execute_all(dry_run=True))
+
+    LOGGER.info('tasks_and_results={:s}'.format(str(tasks_and_results)))
+
+    CORRECT_ORDERED_TASK_KEYS = [
+        'service(admin/MAIN):set_status(SERVICESTATUS_PLANNED)',
+        'service(admin/TAPI-1):set_status(SERVICESTATUS_PLANNED)',
+        'service(admin/TAPI-2):set_status(SERVICESTATUS_PLANNED)',
+        'connection(PKT-1):configure',
+        'connection(PKT-2):configure',
+        'connection(TAPI-1):configure',
+        'connection(TAPI-2):configure',
+        'service(admin/TAPI-1):set_status(SERVICESTATUS_ACTIVE)',
+        'service(admin/TAPI-2):set_status(SERVICESTATUS_ACTIVE)',
+        'connection(TAPI):configure',
+        'service(admin/MAIN):set_status(SERVICESTATUS_ACTIVE)'
+    ]
+
+    for (task_key,_),correct_key in zip(tasks_and_results, CORRECT_ORDERED_TASK_KEYS):
+        assert task_key == correct_key
diff --git a/src/slice/_docs/ietf-network-slice-service_2022-07-11.yang b/src/slice/_docs/ietf-network-slice-service_2022-07-11.yang
new file mode 100644
index 0000000000000000000000000000000000000000..bff228d78f5277fe113d813414c5fd78bf54d98f
--- /dev/null
+++ b/src/slice/_docs/ietf-network-slice-service_2022-07-11.yang
@@ -0,0 +1,1180 @@
+module ietf-network-slice-service {
+  yang-version 1.1;
+  namespace
+    "urn:ietf:params:xml:ns:yang:ietf-network-slice-service";
+  prefix ietf-nss;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Types.";
+  }
+  import ietf-vpn-common {
+    prefix vpn-common;
+    reference
+      "RFC 9181: A Common YANG Data Model for Layer 2 and Layer 3
+                    VPNs.";
+  }
+  import ietf-te-types {
+    prefix te-types;
+    reference
+      "RFC 8776: Common YANG Data Types for Traffic Engineering.";
+  }
+  import ietf-te-packet-types {
+    prefix te-packet-types;
+    reference
+      "RFC 8776: Common YANG Data Types for Traffic Engineering.";
+  }
+
+  organization
+    "IETF Traffic Engineering Architecture and Signaling (TEAS)
+     Working Group";
+  contact
+    "WG Web:  <https://tools.ietf.org/wg/teas/>
+     WG List:  <mailto:teas@ietf.org>
+
+     Editor: Bo Wu
+          <lana.wubo@huawei.com>
+     Editor: Dhruv Dhody
+          <dhruv.ietf@gmail.com>
+     Editor: Reza Rokui
+          <reza.rokui@nokia.com>
+     Editor: Tarek Saad
+          <tsaad@juniper.net>
+     Author: Liuyan Han
+          <hanliuyan@chinamobile.com>";
+  description
+    "This module defines a model for the IETF Network Slice service.
+
+        Copyright (c) 2022 IETF Trust and the persons identified as
+        authors of the code.  All rights reserved.
+
+        Redistribution and use in source and binary forms, with or
+        without modification, is permitted pursuant to, and subject
+        to the license terms contained in, the Revised BSD License
+        set forth in Section 4.c of the IETF Trust's Legal Provisions
+        Relating to IETF Documents
+        (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see the
+     RFC itself for full legal notices.";
+
+  revision 2022-07-11 {
+    description
+      "initial version.";
+    reference
+      "RFC XXXX: A Yang Data Model for IETF Network Slice service
+       operation";
+  }
+  /* Features */
+  /* Identities */
+
+  identity service-tag-type {
+    description
+      "Base identity for IETF Network Slice service tag type.";
+  }
+
+  identity service-tag-customer {
+    base service-tag-type;
+    description
+      "The IETF Network Slice service customer ID tag type.";
+  }
+
+  identity service-tag-service {
+    base service-tag-type;
+    description
+      "The IETF Network Slice service tag type.";
+  }
+
+  identity service-tag-opaque {
+    base service-tag-type;
+    description
+      "The IETF Network Slice service opaque tag type.";
+  }
+
+  identity attachment-circuit-tag-type {
+    description
+      "Base identity for the attachment circuit tag type.";
+  }
+
+  identity attachment-circuit-tag-vlan-id {
+    base attachment-circuit-tag-type;
+    description
+      "The attachment circuit VLAN ID tag type.";
+  }
+
+  identity attachment-circuit-tag-ip-mask {
+    base attachment-circuit-tag-type;
+    description
+      "The attachment circuit tag IP mask.";
+  }
+
+  identity service-isolation-type {
+    description
+      "Base identity for IETF Network slice service isolation level.";
+  }
+
+  identity service-isolation-shared {
+    base service-isolation-type;
+    description
+      "Shared resources (e.g. queues) are associated with the
+       slice service traffic. Hence, the traffic can be impacted
+       by effects of other services traffic
+       sharing the same resources.";
+  }
+
+  identity service-isolation-dedicated {
+    base service-isolation-type;
+    description
+      "Dedicated resources (e.g. queues) are associated with the
+       Network Slice service traffic. Hence, the service traffic
+       is isolated from other servceis traffic
+       sharing the same resources.";
+  }
+
+  identity service-security-type {
+    description
+      "Base identity for for slice service security level.";
+  }
+
+  identity service-security-authenticate {
+    base service-security-type;
+    description
+      "Indicates the slice service requires authentication.";
+  }
+
+  identity service-security-integrity {
+    base service-security-type;
+    description
+      "Indicates the slice service requires data integrity.";
+  }
+
+  identity service-security-encryption {
+    base service-security-type;
+    description
+      "Indicates the slice service requires data encryption.";
+  }
+
+  identity point-to-point {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for point-to-point IETF Network Slice
+       service connectivity.";
+  }
+
+  identity point-to-multipoint {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for point-to-point IETF Network Slice
+       service connectivity.";
+  }
+
+  identity multipoint-to-multipoint {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for point-to-point IETF Network Slice
+       service connectivity.";
+  }
+
+  identity multipoint-to-point {
+    base vpn-common:vpn-topology;
+    description
+      "Identity for point-to-point IETF Network Slice
+       service connectivity.";
+  }
+
+  identity sender-role {
+    base vpn-common:role;
+    description
+      "A SDP is acting as a sender.";
+  }
+
+  identity receiver-role {
+    base vpn-common:role;
+    description
+      "A SDP is acting as a receiver.";
+  }
+
+  identity service-slo-metric-type {
+    description
+      "Base identity for IETF Network Slice service SLO metric type.";
+  }
+
+  identity service-slo-one-way-bandwidth {
+    base service-slo-metric-type;
+    description
+      "SLO bandwidth metric. Minimum guaranteed bandwidth between
+       two SDPs at any time and is measured unidirectionally.";
+  }
+
+  identity service-slo-two-way-bandwidth {
+    base service-slo-metric-type;
+    description
+      "SLO bandwidth metric. Minimum guaranteed bandwidth between
+       two SDPs at any time.";
+  }
+
+  identity service-slo-shared-bandwidth {
+    base service-slo-metric-type;
+    description
+      "The shared SLO bandwidth bound. It is the limit on the
+       bandwidth that can be shared amongst a group of
+       connectivity constructs of a slice service.";
+  }
+
+  identity service-slo-one-way-delay {
+    base service-slo-metric-type;
+    description
+      "SLO one-way-delay is the upper bound of network delay when
+       transmitting between two SDPs. The metric is defined in
+       RFC7679.";
+  }
+
+  identity service-slo-two-way-delay {
+    base service-slo-metric-type;
+    description
+      "SLO two-way delay is the upper bound of network delay when
+       transmitting between two SDPs. The metric is defined in
+       RFC2681.";
+  }
+
+  identity service-slo-one-way-delay-variation {
+    base service-slo-metric-type;
+    description
+      "SLO one-way delay variation is defined by RFC3393, is the
+       difference in the one-way delay between sequential packets
+       between two SDPs.";
+  }
+
+  identity service-slo-two-way-delay-variation {
+    base service-slo-metric-type;
+    description
+      "SLO two-way delay variation is defined by RFC5481, is the
+       difference in the round-trip delay between sequential packets
+       between two SDPs.";
+  }
+
+  identity service-slo-one-way-packet-loss {
+    base service-slo-metric-type;
+    description
+      "SLO loss metric. The ratio of packets dropped to packets
+       transmitted between two SDPs in one-way
+       over a period of time as specified in RFC7680.";
+  }
+
+  identity service-slo-two-way-packet-loss {
+    base service-slo-metric-type;
+    description
+      "SLO loss metric. The ratio of packets dropped to packets
+       transmitted between two SDPs in two-way
+       over a period of time as specified in RFC7680.";
+  }
+
+  identity service-slo-availability {
+    base service-slo-metric-type;
+    description
+      "SLO availability level.";
+  }
+
+  identity service-match-type {
+    description
+      "Base identity for IETF Network Slice service traffic
+       match type.";
+  }
+
+  identity service-phy-interface-match {
+    base service-match-type;
+    description
+      "Use the physical interface as match criteria for
+       slice service traffic.";
+  }
+
+  identity service-vlan-match {
+    base service-match-type;
+    description
+      "Use the VLAN ID as match criteria for the slice service
+       traffic.";
+  }
+
+  identity service-label-match {
+    base service-match-type;
+    description
+      "Use the MPLS label as match criteria for the slice service
+       traffic.";
+  }
+
+  identity service-source-ip-match {
+    base service-match-type;
+    description
+      "Use source ip-address in the packet header as match criteria
+       for the slice service traffic.";
+  }
+
+  identity service-destination-ip-match {
+    base service-match-type;
+    description
+      "Use destination ip-address in the packet header as
+       match criteria for the slice service traffic.";
+  }
+
+  identity service-dscp-match {
+    base service-match-type;
+    description
+      "Use DSCP in the IP packet header as match criteria
+       for the slice service traffic.";
+  }
+
+  identity service-any-match {
+    base service-match-type;
+    description
+      "Match all slice service traffic.";
+  }
+
+  identity peering-protocol-type {
+    description
+      "Base identity for SDP peering protocol type.";
+  }
+
+  identity peering-protocol-bgp {
+    base peering-protocol-type;
+    description
+      "Use BGP as protocol for SDP peering with customer device.";
+  }
+
+  identity peering-static-routing {
+    base peering-protocol-type;
+    description
+      "Use static routing for SDP peering with customer device.";
+  }
+
+  identity peering-attribute-type {
+    description
+      "Base identity for BGP peering";
+  }
+
+  identity remote-as {
+    base peering-attribute-type;
+    description
+      "Identity for remote-as attribute of BGP peering.";
+  }
+
+  identity neighbor {
+    base peering-attribute-type;
+    description
+      "Identity for neighbor attribute of BGP peering.";
+  }
+
+  identity local-as {
+    base peering-attribute-type;
+    description
+      "Identity for local-as attribute of BGP peering.";
+  }
+
+  /*
+   * Identity for availability-type
+   */
+
+  identity availability-type {
+    description
+      "Base identity from which specific availability types are
+       derived.";
+  }
+
+  identity level-1 {
+    base availability-type;
+    description
+      "level 1: 99.9999%";
+  }
+
+  identity level-2 {
+    base availability-type;
+    description
+      "level 2: 99.999%";
+  }
+
+  identity level-3 {
+    base availability-type;
+    description
+      "level 3: 99.99%";
+  }
+
+  identity level-4 {
+    base availability-type;
+    description
+      "level 4: 99.9%";
+  }
+
+  identity level-5 {
+    base availability-type;
+    description
+      "level 5: 99%";
+  }
+
+  /* grouping */
+
+  grouping service-match-criteria {
+    description
+      "A grouping for the slice service match definition.";
+    container service-match-criteria {
+      description
+        "Describes the slice service match criteria.";
+      list match-criterion {
+        key "index";
+        description
+          "List of the slice service traffic match criteria.";
+        leaf index {
+          type uint32;
+          description
+            "The entry index.";
+        }
+        leaf match-type {
+          type identityref {
+            base service-match-type;
+          }
+          mandatory true;
+          description
+            "Identifies an entry in the list of the slice service
+             match criteria.";
+        }
+        leaf-list value {
+          type string;
+          description
+            "Describes the slice service match criteria, e.g.
+             IP address, VLAN, etc.";
+        }
+        leaf target-connection-group-id {
+          type leafref {
+            path
+              "/ietf-nss:network-slice-services"
+            + "/ietf-nss:slice-service"
+            + "/ietf-nss:connection-groups/ietf-nss:connection-group"
+            + "/ietf-nss:connection-group-id";
+          }
+          mandatory true;
+          description
+            "Reference to the slice service connection group.";
+        }
+        leaf connection-group-sdp-role {
+          type identityref {
+            base vpn-common:role;
+          }
+          default "vpn-common:any-to-any-role";
+          description
+            "Indicates the role in the connection group when
+             a slice service has multiple multipoint-to-multipoint
+             connection groups, e.g., hub-spoke.";
+        }
+        leaf target-connectivity-construct-id {
+          type leafref {
+            path
+              "/ietf-nss:network-slice-services/slice-service"
+            + "/ietf-nss:connection-groups"
+            + "/ietf-nss:connection-group[connection-group-id"
+            + "=current()/../target-connection-group-id]"
+            + "/ietf-nss:connectivity-construct/ietf-nss:cc-id";
+          }
+          description
+            "Reference to a Network Slice connection construct.";
+        }
+      }
+    }
+  }
+
+  grouping service-sles {
+    description
+      "Indirectly Measurable Objectives of a slice service.";
+    leaf-list security {
+      type identityref {
+        base service-security-type;
+      }
+      description
+        "The slice service security SLE(s)";
+    }
+    leaf isolation {
+      type identityref {
+        base service-isolation-type;
+      }
+      default "service-isolation-shared";
+      description
+        "The slice service isolation SLE requirement.";
+    }
+    leaf max-occupancy-level {
+      type uint8 {
+        range "1..100";
+      }
+      description
+        "The maximal occupancy level specifies the number of flows to
+         be admitted.";
+    }
+    leaf mtu {
+      type uint16;
+      units "bytes";
+      description
+        "The MTU specifies the maximum length in octets of data
+         packets that can be transmitted by the slice service.
+         The value needs to be less than or equal to the
+         minimum MTU value of all 'attachment-circuits' in the SDPs.";
+    }
+    container steering-constraints {
+      description
+        "Container for the policy of steering constraints
+         applicable to the slice service.";
+      container path-constraints {
+        description
+          "Container for the policy of path constraints
+           applicable to the slice service.";
+      }
+      container service-function {
+        description
+          "Container for the policy of service function
+           applicable to the slice service.";
+      }
+    }
+  }
+
+  grouping service-metric-bounds {
+    description
+      "Slice service metric bounds grouping.";
+    container metric-bounds {
+      description
+        "Slice service metric bounds container.";
+      list metric-bound {
+        key "metric-type";
+        description
+          "List of slice service metric bounds.";
+        leaf metric-type {
+          type identityref {
+            base service-slo-metric-type;
+          }
+          description
+            "Identifies an entry in the list of metric type
+             bounds for the slice service.";
+        }
+        leaf metric-unit {
+          type string;
+          mandatory true;
+          description
+            "The metric unit of the parameter. For example,
+             s, ms, ns, and so on.";
+        }
+        leaf value-description {
+          type string;
+          description
+            "The description of previous value.";
+        }
+        leaf bound {
+          type uint64;
+          default "0";
+          description
+            "The Bound on the slice service connection metric.
+             A zero indicate an unbounded upper limit for the
+             specific metric-type.";
+        }
+      }
+    }
+  }
+
+  grouping sdp-peering {
+    description
+      "A grouping for the slice service SDP peering.";
+    container sdp-peering {
+      description
+        "Describes SDP peering attributes.";
+      list protocol {
+        key "protocol-type";
+        description
+          "List of the SDP peering protocol.";
+        leaf protocol-type {
+          type identityref {
+            base peering-protocol-type;
+          }
+          description
+            "Identifies an entry in the list of SDP peering
+             protocol type.";
+        }
+        list attribute {
+          key "attribute-type";
+          description
+            "list of protocol attributes";
+          leaf attribute-type {
+            type identityref {
+              base peering-attribute-type;
+            }
+            description
+              "identifies the attribute type";
+          }
+          leaf-list value {
+            type string;
+            description
+              "Describes the value of protocol attribute, e.g.
+               nexthop address, peer address, etc.";
+          }
+        }
+      }
+      list opaque {
+        key "attribute-name";
+        description
+          "List of protocol attributes.";
+        leaf attribute-name {
+          type string;
+          description
+            "The name of the attribute.";
+        }
+        leaf-list value {
+          type string;
+          description
+            "The value(s) of the attribute";
+        }
+      }
+    }
+  }
+
+  grouping sdp-attachment-circuits {
+    description
+      "Grouping for the SDP attachment circuit definition.";
+    container attachment-circuits {
+      description
+        "List of attachment circuit.";
+      list attachment-circuit {
+        key "ac-id";
+        description
+          "The IETF Network Slice service SDP attachment circuit
+           related parameters.";
+        leaf ac-id {
+          type string;
+          description
+            "Uniquely identifier a attachment circuit.";
+        }
+        leaf ac-description {
+          type string;
+          description
+            "The attachment circuit description.";
+        }
+        leaf ac-node-id {
+          type string;
+          description
+            "The attachment circuit node ID in the case of
+             multi-homing.";
+        }
+        leaf ac-tp-id {
+          type string;
+          description
+            "The termination port ID of the attachment circuit.";
+        }
+        leaf ac-ip-address {
+          type inet:ip-address;
+          description
+            "The IP address of the attachment circuit.";
+        }
+        leaf ac-ip-prefix-length {
+          type uint8;
+          description
+            "The subnet prefix length expressed in bits.";
+        }
+        leaf ac-qos-policy-name {
+          type string;
+          description
+            "The name of the QoS policy that is applied to the
+             attachment circuit. The name can reference a QoS
+             profile that is pre-provisioned on the device.";
+        }
+        leaf mtu {
+          type uint16;
+          units "bytes";
+          description
+            "Maximum size in octets of the slice service data packet
+             that can traverse a SDP.";
+        }
+        container ac-tags {
+          description
+            "Container for the attachment circuit tags.";
+          list ac-tags {
+            key "ac-tag-type";
+            description
+              "The attachment circuit tags list.";
+            leaf ac-tag-type {
+              type identityref {
+                base attachment-circuit-tag-type;
+              }
+              description
+                "The attachment circuit tag type.";
+            }
+            leaf-list value {
+              type string;
+              description
+                "The attachment circuit tag value.";
+            }
+          }
+          list ac-tag-opaque {
+            key "tag-name";
+            description
+              "The attachment circuit tag opaque list.";
+            leaf tag-name {
+              type string;
+              description
+                "The opaque tags name";
+            }
+            leaf-list value {
+              type string;
+              description
+                "The opaque tags value";
+            }
+          }
+        }
+        /* Per ac rate limits */
+        uses service-match-criteria;
+        uses sdp-peering;
+        uses service-rate-limit;
+      }
+    }
+  }
+
+  grouping sdp-monitoring-metrics {
+    description
+      "Grouping for the SDP monitoring metrics.";
+    container sdp-monitoring {
+      config false;
+      description
+        "Container for SDP monitoring metrics.";
+      leaf incoming-utilized-bandwidth {
+        type te-types:te-bandwidth;
+        description
+          "Incoming bandwidth utilization at a SDP.";
+      }
+      leaf incoming-bw-utilization {
+        type decimal64 {
+          fraction-digits 5;
+          range "0..100";
+        }
+        units "percent";
+        mandatory true;
+        description
+          "To be used to define the bandwidth utilization
+           as a percentage of the available bandwidth.";
+      }
+      leaf outgoing-utilized-bandwidth {
+        type te-types:te-bandwidth;
+        description
+          "Outoing service bandwidth utilization at a SDP.";
+      }
+      leaf outgoing-bw-utilization {
+        type decimal64 {
+          fraction-digits 5;
+          range "0..100";
+        }
+        units "percent";
+        mandatory true;
+        description
+          "To be used to define the service bandwidth utilization
+           as a percentage of the available bandwidth.";
+      }
+    }
+  }
+
+  grouping connectivity-construct-monitoring-metrics {
+    description
+      "Grouping for connectivity construct monitoring metrics.";
+    uses te-packet-types:one-way-performance-metrics-packet;
+    uses te-packet-types:two-way-performance-metrics-packet;
+  }
+
+  grouping geolocation-container {
+    description
+      "A grouping containing a GPS location.";
+    container location {
+      description
+        "A container containing a GPS location.";
+      leaf altitude {
+        type int64;
+        units "millimeter";
+        description
+          "Distance above the sea level.";
+      }
+      leaf latitude {
+        type decimal64 {
+          fraction-digits 8;
+          range "-90..90";
+        }
+        description
+          "Relative position north or south on the Earth's surface.";
+      }
+      leaf longitude {
+        type decimal64 {
+          fraction-digits 8;
+          range "-180..180";
+        }
+        description
+          "Angular distance east or west on the Earth's surface.";
+      }
+    }
+    // gps-location
+  }
+
+  // geolocation-container
+
+  grouping bw-rate-limits {
+    description
+      "Bandwidth rate limits grouping.";
+    reference
+      "RFC 7640: Traffic Management Benchmarking";
+    leaf cir {
+      type uint64;
+      units "bps";
+      description
+        "Committed Information Rate. The maximum number of bits
+         that a port can receive or send during one-second over an
+         interface.";
+    }
+    leaf cbs {
+      type uint64;
+      units "bytes";
+      description
+        "Committed Burst Size. CBS controls the bursty nature
+         of the traffic. Traffic that does not use the configured
+         CIR accumulates credits until the credits reach the
+         configured CBS.";
+    }
+    leaf eir {
+      type uint64;
+      units "bps";
+      description
+        "Excess Information Rate, i.e., excess frame delivery
+         allowed not subject to SLA. The traffic rate can be
+         limited by EIR.";
+    }
+    leaf ebs {
+      type uint64;
+      units "bytes";
+      description
+        "Excess Burst Size. The bandwidth available for burst
+         traffic from the EBS is subject to the amount of
+         bandwidth that is accumulated during periods when
+         traffic allocated by the EIR policy is not used.";
+    }
+    leaf pir {
+      type uint64;
+      units "bps";
+      description
+        "Peak Information Rate, i.e., maximum frame delivery
+         allowed. It is equal to or less than sum of CIR and EIR.";
+    }
+    leaf pbs {
+      type uint64;
+      units "bytes";
+      description
+        "Peak Burst Size.";
+    }
+  }
+
+  grouping service-rate-limit {
+    description
+      "The rate limits grouping.";
+    container incoming-rate-limits {
+      description
+        "Container for the asymmetric traffic control.";
+      uses bw-rate-limits;
+    }
+    container outgoing-rate-limits {
+      description
+        "The rate-limit imposed on outgoing traffic.";
+      uses bw-rate-limits;
+    }
+  }
+
+  grouping sdp {
+    description
+      "Slice service SDP related information";
+    leaf sdp-id {
+      type string;
+      description
+        "Unique identifier for the referred slice service SDP.";
+    }
+    leaf sdp-description {
+      type string;
+      description
+        "Give more description of the SDP.";
+    }
+    uses geolocation-container;
+    leaf node-id {
+      type string;
+      description
+        "Uniquely identifies an edge node of the SDP.";
+    }
+    leaf sdp-ip {
+      type inet:ip-address;
+      description
+        "The IP address of the SDP.";
+    }
+    uses service-match-criteria;
+    uses sdp-peering;
+    uses sdp-attachment-circuits;
+    uses service-rate-limit;
+    /* Per SDP rate limits */
+    uses vpn-common:service-status;
+    uses sdp-monitoring-metrics;
+  }
+
+  //service-sdp
+
+  grouping connectivity-construct {
+    description
+      "Grouping for slice service connectivity construct.";
+    list connectivity-construct {
+      key "cc-id";
+      description
+        "List of connectivity constructs.";
+      leaf cc-id {
+        type uint32;
+        description
+          "The connectivity construct identifier.";
+      }
+      choice connectivity-construct-type {
+        default "p2p";
+        description
+          "Choice for connectivity construct type.";
+        case p2p {
+          description
+            "P2P connectivity construct.";
+          leaf p2p-sender-sdp {
+            type leafref {
+              path "../../../../sdps/sdp/sdp-id";
+            }
+            description
+              "Reference to a sender SDP.";
+          }
+          leaf p2p-receiver-sdp {
+            type leafref {
+              path "../../../../sdps/sdp/sdp-id";
+            }
+            description
+              "Reference to a receiver SDP.";
+          }
+        }
+        case p2mp {
+          description
+            "P2MP connectivity construct.";
+          leaf p2mp-sender-sdp {
+            type leafref {
+              path "../../../../sdps/sdp/sdp-id";
+            }
+            description
+              "Reference to a sender SDP.";
+          }
+          leaf-list p2mp-receiver-sdp {
+            type leafref {
+              path "../../../../sdps/sdp/sdp-id";
+            }
+            description
+              "Reference to a receiver SDP.";
+          }
+        }
+        case a2a {
+          description
+            "A2A connectivity construct.";
+          list a2a-sdp {
+            key "sdp-id";
+            description
+              "List of included A2A SDPs.";
+            leaf sdp-id {
+              type leafref {
+                path "../../../../../sdps/sdp/sdp-id";
+              }
+              description
+                "Reference to a SDP.";
+            }
+            uses service-slo-sle-policy;
+          }
+        }
+      }
+      uses service-slo-sle-policy;
+      /* Per connectivity construct service-slo-sle-policy
+       * overrides the per slice service-slo-sle-policy.
+       */
+      container connectivity-construct-monitoring {
+        config false;
+        description
+          "SLO status per connectivity construct.";
+        uses connectivity-construct-monitoring-metrics;
+      }
+    }
+  }
+
+  //connectivity-construct
+
+  grouping connection-group {
+    description
+      "Grouping for slice service connection group.";
+    leaf connection-group-id {
+      type string;
+      description
+        "The connection group identifier.";
+    }
+    leaf connectivity-type {
+      type identityref {
+        base vpn-common:vpn-topology;
+      }
+      default "vpn-common:any-to-any";
+      description
+        "Connection group connectivity type.";
+    }
+    uses service-slo-sle-policy;
+    uses connectivity-construct;
+    /* Per connection group service-slo-sle-policy overrides
+     * the per slice service-slo-sle-policy.
+     */
+    container connection-group-monitoring {
+      config false;
+      description
+        "SLO status per connection group.";
+      uses connectivity-construct-monitoring-metrics;
+    }
+  }
+
+  //connection-group
+
+  grouping slice-service-template {
+    description
+      "Grouping for slice service templates.";
+    container slo-sle-templates {
+      description
+        "Contains a set of slice service templates.";
+      list slo-sle-template {
+        key "id";
+        leaf id {
+          type string;
+          description
+            "Identification of the Service Level Objective (SLO)
+             and Service Level Expectation (SLE) template to be used.
+             Local administration meaning.";
+        }
+        leaf template-description {
+          type string;
+          description
+            "Description of the SLO and SLE policy template.";
+        }
+        description
+          "List for SLO and SLE template identifiers.";
+      }
+    }
+  }
+
+  /* Configuration data nodes */
+
+  grouping service-slo-sle-policy {
+    description
+      "Slice service policy grouping.";
+    choice slo-sle-policy {
+      description
+        "Choice for SLO and SLE policy template.
+         Can be standard template or customized template.";
+      case standard {
+        description
+          "Standard SLO template.";
+        leaf slo-sle-template {
+          type leafref {
+            path "/ietf-nss:network-slice-services"
+               + "/ietf-nss:slo-sle-templates"
+               + "/ietf-nss:slo-sle-template/id";
+          }
+          description
+            "Standard SLO and SLE template to be used.";
+        }
+      }
+      case custom {
+        description
+          "Customized SLO and SLE template.";
+        container service-slo-sle-policy {
+          description
+            "Contains the SLO and SLE policy.";
+          leaf policy-description {
+            type string;
+            description
+              "Description of the SLO and SLE policy.";
+          }
+          uses service-metric-bounds;
+          uses service-sles;
+        }
+      }
+    }
+  }
+
+  container network-slice-services {
+    description
+      "Containes a list of IETF network slice services";
+    uses slice-service-template;
+    list slice-service {
+      key "service-id";
+      description
+        "A slice service is identified by a service-id.";
+      leaf service-id {
+        type string;
+        description
+          "A unique slice service identifier.";
+      }
+      leaf service-description {
+        type string;
+        description
+          "Textual description of the slice service.";
+      }
+      container service-tags {
+        description
+          "Container for the list of service tags.";
+        list tag-type {
+          key "tag-type";
+          description
+            "The service tag list.";
+          leaf tag-type {
+            type identityref {
+              base service-tag-type;
+            }
+            description
+              "Slice service tag type.";
+          }
+          leaf-list value {
+            type string;
+            description
+              "The tag value";
+          }
+        }
+        list tag-opaque {
+          key "tag-name";
+          description
+            "The service tag opaquelist.";
+          leaf tag-name {
+            type string;
+            description
+              "The opaque tag name";
+          }
+          leaf-list value {
+            type string;
+            description
+              "The opaque tag value";
+          }
+        }
+      }
+      uses service-slo-sle-policy;
+      uses vpn-common:service-status;
+      container sdps {
+        description
+          "Slice service SDPs.";
+        list sdp {
+          key "sdp-id";
+          uses sdp;
+          description
+            "List of SDPs in this slice service.";
+        }
+      }
+      container connection-groups {
+        description
+          "Contains connections group.";
+        list connection-group {
+          key "connection-group-id";
+          description
+            "List of connection groups.";
+          uses connection-group;
+        }
+      }
+    }
+    //ietf-network-slice-service list
+  }
+}
diff --git a/src/slice/requirements.in b/src/slice/requirements.in
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0a2c39895c9a1f642470bcc26cb67bd8dfb169b1 100644
--- a/src/slice/requirements.in
+++ b/src/slice/requirements.in
@@ -0,0 +1 @@
+#deepdiff==5.8.*
diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py
index 275a201148940df10afcf446b57ab42e6c6a528c..53875f0e6ae7c8e3e7d5ac9dad7501a2136844c4 100644
--- a/src/slice/service/SliceServiceServicerImpl.py
+++ b/src/slice/service/SliceServiceServicerImpl.py
@@ -12,11 +12,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, json, logging
+import grpc, json, logging #, deepdiff
 from common.proto.context_pb2 import (
-    ConfigActionEnum, Empty, Service, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum)
+    Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum)
 from common.proto.slice_pb2_grpc import SliceServiceServicer
 from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
+from common.tools.grpc.ConfigRules import copy_config_rules
+from common.tools.grpc.Constraints import copy_constraints
+from common.tools.grpc.EndPointIds import copy_endpoint_ids
+from common.tools.grpc.ServiceIds import update_service_ids
+from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from interdomain.client.InterdomainClient import InterdomainClient
 from service.client.ServiceClient import ServiceClient
@@ -34,66 +39,101 @@ class SliceServiceServicerImpl(SliceServiceServicer):
 
     def create_update(self, request : Slice) -> SliceId:
         context_client = ContextClient()
-
-        slice_id = context_client.SetSlice(request)
-        if len(request.slice_endpoint_ids) != 2: return slice_id
+        try:
+            _slice = context_client.GetSlice(request.slice_id)
+            #json_current_slice = grpc_message_to_json(_slice)
+        except:
+            #json_current_slice = {}
+            slice_request = Slice()
+            slice_request.slice_id.CopyFrom(request.slice_id)
+            slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
+            context_client.SetSlice(slice_request)
+            _slice = context_client.GetSlice(request.slice_id)
+        slice_request = Slice()
+        slice_request.CopyFrom(_slice)
+
+        #LOGGER.info('json_current_slice = {:s}'.format(str(json_current_slice)))
+        #json_updated_slice = grpc_message_to_json(request)
+        #LOGGER.info('json_updated_slice = {:s}'.format(str(json_updated_slice)))
+        #changes = deepdiff.DeepDiff(json_current_slice, json_updated_slice)
+        #LOGGER.info('changes = {:s}'.format(str(changes)))
 
         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])
+            device_parts = device_uuid.split('@')
+            domain_uuid = '' if len(device_parts) == 1 else device_parts[1]
+            domains.add(domain_uuid)
+        LOGGER.info('domains = {:s}'.format(str(domains)))
+        is_multi_domain = len(domains) > 1
+        LOGGER.info('is_multi_domain = {:s}'.format(str(is_multi_domain)))
 
-        is_multi_domain = len(domains) == 2
         if is_multi_domain:
             interdomain_client = InterdomainClient()
             slice_id = 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_id = ServiceId()
+            context_uuid = service_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid
+            slice_uuid = service_uuid = service_id.service_uuid.uuid = request.slice_id.slice_uuid.uuid
 
             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')
-
-            config_rule = service_request.service_config.config_rules.add()
-            config_rule.action = ConfigActionEnum.CONFIGACTION_SET
-            config_rule.custom.resource_key = '/settings'
-            config_rule.custom.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.custom.resource_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(
-                    device_uuid, endpoint_uuid)
-                config_rule.custom.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)
+            try:
+                _service = context_client.GetService(service_id)
+            except:
+                service_request = Service()
+                service_request.service_id.CopyFrom(service_id)
+                service_request.service_type = ServiceTypeEnum.SERVICETYPE_UNKNOWN
+                service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
+                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')
+                _service = context_client.GetService(service_id)
+            service_request = Service()
+            service_request.CopyFrom(_service)
+
+            copy_endpoint_ids(request.slice_endpoint_ids, service_request.service_endpoint_ids)
+            copy_constraints(request.slice_constraints, service_request.service_constraints)
+            copy_config_rules(request.slice_config.config_rules, service_request.service_config.config_rules)
+
+            service_request.service_type = ServiceTypeEnum.SERVICETYPE_UNKNOWN
+            for config_rule in request.slice_config.config_rules:
+                LOGGER.info('config_rule: {:s}'.format(grpc_message_to_json_string(config_rule)))
+                config_rule_kind = config_rule.WhichOneof('config_rule')
+                LOGGER.info('config_rule_kind: {:s}'.format(str(config_rule_kind)))
+                if config_rule_kind != 'custom': continue
+                custom = config_rule.custom
+                resource_key = custom.resource_key
+                LOGGER.info('resource_key: {:s}'.format(str(resource_key)))
+
+                # TODO: parse resource key with regular expression, e.g.:
+                #    m = re.match('\/device\[[^\]]\]\/endpoint\[[^\]]\]\/settings', s)
+                if not resource_key.startswith('/device'): continue
+                if not resource_key.endswith('/settings'): continue
+
+                resource_value = json.loads(custom.resource_value)
+                LOGGER.info('resource_value: {:s}'.format(str(resource_value)))
+
+                if service_request.service_type == ServiceTypeEnum.SERVICETYPE_UNKNOWN:
+                    if (resource_value.get('address_ip') is not None and \
+                        resource_value.get('address_prefix') is not None):
+                        service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
+                        LOGGER.info('is L3')
+                    else:
+                        service_request.service_type = ServiceTypeEnum.SERVICETYPE_L2NM
+                        LOGGER.info('is L2')
+                    break
 
             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')
 
-            reply = Slice()
-            reply.CopyFrom(request)
-            slice_service_id = reply.slice_service_ids.add()
-            slice_service_id.CopyFrom(service_reply)
-            context_client.SetSlice(reply)
-            slice_id = reply.slice_id
+            copy_endpoint_ids(request.slice_endpoint_ids, slice_request.slice_endpoint_ids)
+            copy_constraints(request.slice_constraints, slice_request.slice_constraints)
+            copy_config_rules(request.slice_config.config_rules, slice_request.slice_config.config_rules)
+
+            update_service_ids(slice_request.slice_service_ids, context_uuid, service_uuid)
+            context_client.SetSlice(slice_request)
+            slice_id = slice_request.slice_id
 
         slice_ = context_client.GetSlice(slice_id)
         slice_active = Slice()
@@ -132,4 +172,41 @@ class SliceServiceServicerImpl(SliceServiceServicer):
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty:
+        context_client = ContextClient()
+        try:
+            _slice = context_client.GetSlice(request)
+        except:
+            return Empty()
+
+        domains = set()
+        for slice_endpoint_id in _slice.slice_endpoint_ids:
+            device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
+            device_parts = device_uuid.split('@')
+            domain_uuid = '' if len(device_parts) == 1 else device_parts[1]
+            domains.add(domain_uuid)
+        LOGGER.info('domains = {:s}'.format(str(domains)))
+        is_multi_domain = len(domains) > 1
+        LOGGER.info('is_multi_domain = {:s}'.format(str(is_multi_domain)))
+
+        if is_multi_domain:
+            interdomain_client = InterdomainClient()
+            #slice_id = interdomain_client.DeleteSlice(request)
+            raise NotImplementedError('Delete inter-domain slice')
+        else:
+            current_slice = Slice()
+            current_slice.CopyFrom(_slice)
+            current_slice.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_DEINIT
+            context_client.SetSlice(current_slice)
+
+            service_client = ServiceClient()
+            for service_id in _slice.slice_service_ids:
+                current_slice = Slice()
+                current_slice.slice_id.CopyFrom(_slice.slice_id)
+                slice_service_id = current_slice.slice_service_ids.add()
+                slice_service_id.CopyFrom(service_id)
+                context_client.UnsetSlice(current_slice)
+
+                service_client.DeleteService(service_id)
+
+        context_client.RemoveSlice(request)
         return Empty()
diff --git a/src/slice/service/__main__.py b/src/slice/service/__main__.py
index f77d86bffe9b722f414be4f85adcaf0ef2cc4a8e..a59c54b4b1b56865871d331409c1a7f60629aec6 100644
--- a/src/slice/service/__main__.py
+++ b/src/slice/service/__main__.py
@@ -29,7 +29,7 @@ def main():
     global LOGGER # pylint: disable=global-statement
 
     log_level = get_log_level()
-    logging.basicConfig(level=log_level)
+    logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
diff --git a/src/tests/ecoc22/.gitignore b/src/tests/ecoc22/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0a3f4400d5c88b1af32c7667d69d2fdc12d5424e
--- /dev/null
+++ b/src/tests/ecoc22/.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/ecoc22/__init__.py b/src/tests/ecoc22/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/tests/ecoc22/__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/ecoc22/deploy_specs.sh b/src/tests/ecoc22/deploy_specs.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5e7a7cc3c26f710f87366fd1b194cdc970301e8e
--- /dev/null
+++ b/src/tests/ecoc22/deploy_specs.sh
@@ -0,0 +1,17 @@
+# Set the URL of your local Docker registry where the images will be uploaded to.
+export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
+
+# Set the list of components, separated by spaces, you want to build images for, and deploy.
+export TFS_COMPONENTS="context device service automation pathcomp slice compute webui"
+
+# Set the tag you want to use for your images.
+export TFS_IMAGE_TAG="dev"
+
+# Set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE="tfs"
+
+# Set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
+
+# Set the neew Grafana admin password
+export TFS_GRAFANA_PASSWORD="admin123+"
diff --git a/src/tests/ecoc22/descriptors_emulated-BigNet.json b/src/tests/ecoc22/descriptors_emulated-BigNet.json
new file mode 100644
index 0000000000000000000000000000000000000000..cd038269425755258cea9b0908478d66702ad9cc
--- /dev/null
+++ b/src/tests/ecoc22/descriptors_emulated-BigNet.json
@@ -0,0 +1,1299 @@
+{
+    "contexts": [
+        {
+            "context_id": {
+                "context_uuid": {
+                    "uuid": "admin"
+                }
+            },
+            "service_ids": [],
+            "topology_ids": []
+        }
+    ],
+    "devices": [
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CE1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CE2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CE3"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CE4"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "PE1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "PE2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "PE3"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "PE4"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB6"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/4\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/5\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/6\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB7"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB3"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB5"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "BB4"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        }
+    ],
+    "links": [
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CE1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CE1/1/1==CE1/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CE2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CE2/1/1==CE2/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CE3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CE3/1/1==CE3/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CE4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CE4/1/1==CE4/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE1/2/1==PE1/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE1/2/2==PE1/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE2/2/1==PE2/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE2/2/2==PE2/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB5"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE3/2/2==PE3/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE3/2/1==PE3/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB5"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE4/2/2==PE4/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "PE4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "PE4/2/1==PE4/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB1/2/1==BB1/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB2/2/1==BB2/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB3/2/1==BB3/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB5"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB4/2/1==BB4/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB5"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB6"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB5/2/1==BB5/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB6"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB6/2/1==BB6/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB7"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB1/2/3==BB1/2/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB7"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB2/2/3==BB2/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB7"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB3/2/3==BB3/2/3"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB7"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/4"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB4/2/3==BB4/2/4"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB5"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB7"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/5"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB5/2/3==BB5/2/5"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB6"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "BB7"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/6"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "BB6/2/3==BB6/2/6"
+                }
+            }
+        }
+    ],
+    "topologies": [
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ecoc22/descriptors_emulated-DC_CSGW_TN.json b/src/tests/ecoc22/descriptors_emulated-DC_CSGW_TN.json
new file mode 100644
index 0000000000000000000000000000000000000000..5f40edac2feef134c02a74b08fcad21d917aae07
--- /dev/null
+++ b/src/tests/ecoc22/descriptors_emulated-DC_CSGW_TN.json
@@ -0,0 +1,1005 @@
+{
+    "contexts": [
+        {
+            "context_id": {
+                "context_uuid": {
+                    "uuid": "admin"
+                }
+            },
+            "service_ids": [],
+            "topology_ids": []
+        }
+    ],
+    "devices": [
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"int\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "DC1-GW"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-datacenter"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"int\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "DC2-GW"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-datacenter"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS1-GW1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS1-GW2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS2-GW1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS2-GW2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R3"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/3\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R4"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        }
+    ],
+    "links": [
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC1-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC1-GW/eth1==CS1-GW1/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC1-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC1-GW/eth2==CS1-GW2/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC2-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC2-GW/eth1==CS2-GW1/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC2-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC2-GW/eth2==CS2-GW2/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW1/1/1==TN-R1/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW2/1/1==TN-R2/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW1/1/2==TN-R2/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW2/1/2==TN-R1/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW1/1/1==TN-R3/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW2/1/1==TN-R4/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW1/1/2==TN-R4/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW2/1/2==TN-R3/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R1/2/1==TN-R2/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R2/2/1==TN-R3/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R3/2/1==TN-R4/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R4/2/1==TN-R1/2/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R1/2/3==TN-R3/2/3"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/3"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R2/2/3==TN-R4/2/3"
+                }
+            }
+        }
+    ],
+    "topologies": [
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "DC1"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "DC2"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "CS1"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "CS2"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "TN"
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ecoc22/descriptors_emulated-DC_CSGW_TN_OLS.json b/src/tests/ecoc22/descriptors_emulated-DC_CSGW_TN_OLS.json
new file mode 100644
index 0000000000000000000000000000000000000000..8d8e6fde3d3c183688fdc6ec7c3e6498c0d6791a
--- /dev/null
+++ b/src/tests/ecoc22/descriptors_emulated-DC_CSGW_TN_OLS.json
@@ -0,0 +1,985 @@
+{
+    "contexts": [
+        {
+            "context_id": {
+                "context_uuid": {
+                    "uuid": "admin"
+                }
+            },
+            "service_ids": [],
+            "topology_ids": []
+        }
+    ],
+    "devices": [
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"int\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "DC1-GW"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-datacenter"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"eth2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"int\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "DC2-GW"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-datacenter"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS1-GW1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS1-GW2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS2-GW1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"10/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "CS2-GW2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R1"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R2"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R3"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/1\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"1/2\"}, {\"sample_types\": [], \"type\": \"copper\", \"uuid\": \"2/1\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-R4"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-packet-router"
+        },
+        {
+            "device_config": {
+                "config_rules": [
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/address",
+                            "resource_value": "127.0.0.1"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/port",
+                            "resource_value": "0"
+                        }
+                    },
+                    {
+                        "action": 1,
+                        "custom": {
+                            "resource_key": "_connect/settings",
+                            "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"a3adcbbcc03f\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"9329780033f5\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"e8a127ea3ed1\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"ef1c58823a49\"}]}"
+                        }
+                    }
+                ]
+            },
+            "device_drivers": [
+                0
+            ],
+            "device_endpoints": [],
+            "device_id": {
+                "device_uuid": {
+                    "uuid": "TN-OLS"
+                }
+            },
+            "device_operational_status": 1,
+            "device_type": "emu-open-line-system"
+        }
+    ],
+    "links": [
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC1-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC1-GW/eth1==CS1-GW1/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC1-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC1-GW/eth2==CS1-GW2/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC2-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC2-GW/eth1==CS2-GW1/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "DC2-GW"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "eth2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "10/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "DC2-GW/eth2==CS2-GW2/10/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW1/1/1==TN-R1/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW2/1/1==TN-R2/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW1/1/2==TN-R2/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS1-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS1-GW2/1/2==TN-R1/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW1/1/1==TN-R3/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW2/1/1==TN-R4/1/1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW1/1/2==TN-R4/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "CS2-GW2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "1/2"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "CS2-GW2/1/2==TN-R3/1/2"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R1"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-OLS"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "a3adcbbcc03f"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R1/2/1==TN-OLS/a3adcbbcc03f"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R2"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-OLS"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "9329780033f5"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R2/2/1==TN-OLS/9329780033f5"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R3"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-OLS"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "e8a127ea3ed1"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R3/2/1==TN-OLS/e8a127ea3ed1"
+                }
+            }
+        },
+        {
+            "link_endpoint_ids": [
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-R4"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "2/1"
+                    }
+                },
+                {
+                    "device_id": {
+                        "device_uuid": {
+                            "uuid": "TN-OLS"
+                        }
+                    },
+                    "endpoint_uuid": {
+                        "uuid": "ef1c58823a49"
+                    }
+                }
+            ],
+            "link_id": {
+                "link_uuid": {
+                    "uuid": "TN-R4/2/1==TN-OLS/ef1c58823a49"
+                }
+            }
+        }
+    ],
+    "topologies": [
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "admin"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "DC1"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "DC2"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "CS1"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "CS2"
+                }
+            }
+        },
+        {
+            "device_ids": [],
+            "link_ids": [],
+            "topology_id": {
+                "context_id": {
+                    "context_uuid": {
+                        "uuid": "admin"
+                    }
+                },
+                "topology_uuid": {
+                    "uuid": "TN"
+                }
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/tests/ecoc22/redeploy.sh b/src/tests/ecoc22/redeploy.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3f3986debb9aec57e7bc7f67b549b960679a987f
--- /dev/null
+++ b/src/tests/ecoc22/redeploy.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+source ecoc22/deploy_specs.sh
+./deploy.sh
+source tfs_runtime_env_vars.sh
diff --git a/src/tests/ecoc22/run_test_01_bootstrap.sh b/src/tests/ecoc22/run_test_01_bootstrap.sh
new file mode 100755
index 0000000000000000000000000000000000000000..819991d78a499c6d6e4a10e96f6439ee5b56ed8d
--- /dev/null
+++ b/src/tests/ecoc22/run_test_01_bootstrap.sh
@@ -0,0 +1,17 @@
+#!/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.
+
+source tfs_runtime_env_vars.sh
+pytest --verbose src/tests/ecoc22/tests/test_functional_bootstrap.py
diff --git a/src/tests/ecoc22/run_test_02_create_service.sh b/src/tests/ecoc22/run_test_02_create_service.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5a54d39d496e203ee669efda636067dcc1aa27a9
--- /dev/null
+++ b/src/tests/ecoc22/run_test_02_create_service.sh
@@ -0,0 +1,17 @@
+#!/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.
+
+source tfs_runtime_env_vars.sh
+pytest --verbose src/tests/ecoc22/tests/test_functional_create_service.py
diff --git a/src/tests/ecoc22/run_test_03_delete_service.sh b/src/tests/ecoc22/run_test_03_delete_service.sh
new file mode 100755
index 0000000000000000000000000000000000000000..900e09b658c1a73664dd28dc60ef6a50a9e68570
--- /dev/null
+++ b/src/tests/ecoc22/run_test_03_delete_service.sh
@@ -0,0 +1,17 @@
+#!/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.
+
+source tfs_runtime_env_vars.sh
+pytest --verbose src/tests/ecoc22/tests/test_functional_delete_service.py
diff --git a/src/tests/ecoc22/run_test_04_cleanup.sh b/src/tests/ecoc22/run_test_04_cleanup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4e0622e6b22d470d842d99bb4202e23e88b72982
--- /dev/null
+++ b/src/tests/ecoc22/run_test_04_cleanup.sh
@@ -0,0 +1,17 @@
+#!/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.
+
+source tfs_runtime_env_vars.sh
+pytest --verbose src/tests/ecoc22/tests/test_functional_cleanup.py
diff --git a/src/tests/ecoc22/run_tests_and_coverage.sh b/src/tests/ecoc22/run_tests_and_coverage.sh
new file mode 100755
index 0000000000000000000000000000000000000000..835867896020f2b94e0797bdf60c85af2228eda2
--- /dev/null
+++ b/src/tests/ecoc22/run_tests_and_coverage.sh
@@ -0,0 +1,43 @@
+#!/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
+
+# Force a flush of Context database
+kubectl --namespace $TFS_K8S_NAMESPACE exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL
+
+# Run functional tests and analyze code coverage at the same time
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/ecoc22/tests/test_functional_bootstrap.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/ecoc22/tests/test_functional_create_service.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/ecoc22/tests/test_functional_delete_service.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/ecoc22/tests/test_functional_cleanup.py
diff --git a/src/tests/ecoc22/tests/.gitignore b/src/tests/ecoc22/tests/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6b97d6fe3ad32f39097745229ab7f547f26ecb12
--- /dev/null
+++ b/src/tests/ecoc22/tests/.gitignore
@@ -0,0 +1 @@
+# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
diff --git a/src/tests/ecoc22/tests/BuildDescriptors.py b/src/tests/ecoc22/tests/BuildDescriptors.py
new file mode 100644
index 0000000000000000000000000000000000000000..b0075c0639c70092ed60bafd06c9f62b581faa33
--- /dev/null
+++ b/src/tests/ecoc22/tests/BuildDescriptors.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.
+
+# Execution:
+# $ cd src
+# $ python -m tests.ecoc22.tests.BuildDescriptors dc-csgw-tn
+# $ python -m tests.ecoc22.tests.BuildDescriptors dc-csgw-tn-ols
+# $ python -m tests.ecoc22.tests.BuildDescriptors bignet
+
+import copy, json, os, sys
+from enum import Enum
+from typing import Dict, Tuple
+
+class Scenario(Enum):
+    BIGNET         = 'bignet'
+    DC_CSGW_TN     = 'dc-csgw-tn'
+    DC_CSGW_TN_OLS = 'dc-csgw-tn-ols'
+
+scenario = None if len(sys.argv) < 2 else sys.argv[1].lower()
+
+if scenario == Scenario.BIGNET.value:
+    from .Objects_BigNet import CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+    FILENAME = 'tests/ecoc22/descriptors_emulated-BigNet.json'
+elif scenario == Scenario.DC_CSGW_TN.value:
+    os.environ['ADD_CONNECT_RULES_TO_DEVICES'] = 'TRUE'
+    from .Objects_DC_CSGW_TN import CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+    FILENAME = 'tests/ecoc22/descriptors_emulated-DC_CSGW_TN.json'
+elif scenario == Scenario.DC_CSGW_TN_OLS.value:
+    os.environ['ADD_CONNECT_RULES_TO_DEVICES'] = 'TRUE'
+    from .Objects_DC_CSGW_TN_OLS import CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+    FILENAME = 'tests/ecoc22/descriptors_emulated-DC_CSGW_TN_OLS.json'
+else:
+    scenarios = str([s.value for s in Scenario])
+    raise Exception('Unsupported Scenario({:s}), choices are: {:s}'.format(scenario, scenarios))
+
+def main():
+    with open(FILENAME, 'w', encoding='UTF-8') as f:
+        devices = []
+        for item in DEVICES:
+            if isinstance(item, Dict):
+                device = item
+            elif isinstance(item, Tuple) and len(item) == 2:
+                device,connect_rules = item
+            else:
+                raise Exception('Wrongly formatted item: {:s}'.format(str(item)))
+            device = copy.deepcopy(device)
+            if len(item) == 2:
+                device['device_config']['config_rules'].extend(connect_rules)
+            devices.append(device)
+
+        f.write(json.dumps({
+            'contexts': CONTEXTS,
+            'topologies': TOPOLOGIES,
+            'devices': devices,
+            'links': LINKS
+        }, sort_keys=True, indent=4))
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/tests/ecoc22/tests/Credentials.py b/src/tests/ecoc22/tests/Credentials.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/tests/ecoc22/tests/Fixtures.py b/src/tests/ecoc22/tests/Fixtures.py
new file mode 100644
index 0000000000000000000000000000000000000000..70b41bdcb159552daa3dcf0c041a3713e2d1c821
--- /dev/null
+++ b/src/tests/ecoc22/tests/Fixtures.py
@@ -0,0 +1,26 @@
+import pytest
+from common.Settings import get_setting
+from compute.tests.mock_osm.MockOSM import MockOSM
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+#from .Objects_BigNet import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME
+from .Objects_DC_CSGW_TN import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME
+#from .Objects_DC_CSGW_TN_OLS import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME
+
+@pytest.fixture(scope='session')
+def context_client():
+    _client = ContextClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def device_client():
+    _client = DeviceClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def osm_wim():
+    wim_url = 'http://{:s}:{:s}'.format(
+        get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP')))
+    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
diff --git a/src/tests/ecoc22/tests/LoadDescriptors.py b/src/tests/ecoc22/tests/LoadDescriptors.py
new file mode 100644
index 0000000000000000000000000000000000000000..bd7e48366795d47624f1b8e295cbe6fa105bf8c7
--- /dev/null
+++ b/src/tests/ecoc22/tests/LoadDescriptors.py
@@ -0,0 +1,38 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 common.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()
+    device_client  = DeviceClient()
+
+    with open('tests/ecoc22/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/ecoc22/tests/Objects_BigNet.py b/src/tests/ecoc22/tests/Objects_BigNet.py
new file mode 100644
index 0000000000000000000000000000000000000000..592376ff9dbaebbf4d8d02b04189e5d4f24584e3
--- /dev/null
+++ b/src/tests/ecoc22/tests/Objects_BigNet.py
@@ -0,0 +1,302 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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_datacenter_disabled,
+    json_device_emulated_packet_router_disabled, json_device_id)
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+from .Tools import compose_bearer, compose_service_endpoint_id, json_endpoint_ids, link
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+
+# ----- Topology -------------------------------------------------------------------------------------------------------
+TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID)
+TOPOLOGY    = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID)
+
+
+# ----- Customer Equipment (CE) Devices --------------------------------------------------------------------------------
+DEVICE_CE1_UUID          = 'CE1'
+DEVICE_CE1_ENDPOINT_DEFS = [('1/1', 'copper', [])]
+DEVICE_CE1_ID            = json_device_id(DEVICE_CE1_UUID)
+DEVICE_CE1_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_CE1_ID, DEVICE_CE1_ENDPOINT_DEFS)
+DEVICE_CE1               = json_device_emulated_packet_router_disabled(DEVICE_CE1_UUID)
+ENDPOINT_ID_CE1_1_1      = DEVICE_CE1_ENDPOINT_IDS[0]
+DEVICE_CE1_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_CE1_ENDPOINT_DEFS)
+
+DEVICE_CE2_UUID          = 'CE2'
+DEVICE_CE2_ENDPOINT_DEFS = [('1/1', 'copper', [])]
+DEVICE_CE2_ID            = json_device_id(DEVICE_CE2_UUID)
+DEVICE_CE2_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_CE2_ID, DEVICE_CE2_ENDPOINT_DEFS)
+DEVICE_CE2               = json_device_emulated_packet_router_disabled(DEVICE_CE2_UUID)
+ENDPOINT_ID_CE2_1_1      = DEVICE_CE2_ENDPOINT_IDS[0]
+DEVICE_CE2_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_CE2_ENDPOINT_DEFS)
+
+DEVICE_CE3_UUID          = 'CE3'
+DEVICE_CE3_ENDPOINT_DEFS = [('1/1', 'copper', [])]
+DEVICE_CE3_ID            = json_device_id(DEVICE_CE3_UUID)
+DEVICE_CE3_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_CE3_ID, DEVICE_CE3_ENDPOINT_DEFS)
+DEVICE_CE3               = json_device_emulated_packet_router_disabled(DEVICE_CE3_UUID)
+ENDPOINT_ID_CE3_1_1      = DEVICE_CE3_ENDPOINT_IDS[0]
+DEVICE_CE3_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_CE3_ENDPOINT_DEFS)
+
+DEVICE_CE4_UUID          = 'CE4'
+DEVICE_CE4_ENDPOINT_DEFS = [('1/1', 'copper', [])]
+DEVICE_CE4_ID            = json_device_id(DEVICE_CE4_UUID)
+DEVICE_CE4_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_CE4_ID, DEVICE_CE4_ENDPOINT_DEFS)
+DEVICE_CE4               = json_device_emulated_packet_router_disabled(DEVICE_CE4_UUID)
+ENDPOINT_ID_CE4_1_1      = DEVICE_CE4_ENDPOINT_IDS[0]
+DEVICE_CE4_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_CE4_ENDPOINT_DEFS)
+
+# ----- Provider Equipment (PE) Devices --------------------------------------------------------------------------------
+DEVICE_PE1_UUID          = 'PE1'
+DEVICE_PE1_ENDPOINT_DEFS = [('1/1', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', [])]
+DEVICE_PE1_ID            = json_device_id(DEVICE_PE1_UUID)
+DEVICE_PE1_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_PE1_ID, DEVICE_PE1_ENDPOINT_DEFS)
+DEVICE_PE1               = json_device_emulated_packet_router_disabled(DEVICE_PE1_UUID)
+ENDPOINT_ID_PE1_1_1      = DEVICE_PE1_ENDPOINT_IDS[0]
+ENDPOINT_ID_PE1_2_1      = DEVICE_PE1_ENDPOINT_IDS[1]
+ENDPOINT_ID_PE1_2_2      = DEVICE_PE1_ENDPOINT_IDS[2]
+DEVICE_PE1_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_PE1_ENDPOINT_DEFS)
+
+DEVICE_PE2_UUID          = 'PE2'
+DEVICE_PE2_ENDPOINT_DEFS = [('1/1', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', [])]
+DEVICE_PE2_ID            = json_device_id(DEVICE_PE2_UUID)
+DEVICE_PE2_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_PE2_ID, DEVICE_PE2_ENDPOINT_DEFS)
+DEVICE_PE2               = json_device_emulated_packet_router_disabled(DEVICE_PE2_UUID)
+ENDPOINT_ID_PE2_1_1      = DEVICE_PE2_ENDPOINT_IDS[0]
+ENDPOINT_ID_PE2_2_1      = DEVICE_PE2_ENDPOINT_IDS[1]
+ENDPOINT_ID_PE2_2_2      = DEVICE_PE2_ENDPOINT_IDS[2]
+DEVICE_PE2_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_PE2_ENDPOINT_DEFS)
+
+DEVICE_PE3_UUID          = 'PE3'
+DEVICE_PE3_ENDPOINT_DEFS = [('1/1', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', [])]
+DEVICE_PE3_ID            = json_device_id(DEVICE_PE3_UUID)
+DEVICE_PE3_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_PE3_ID, DEVICE_PE3_ENDPOINT_DEFS)
+DEVICE_PE3               = json_device_emulated_packet_router_disabled(DEVICE_PE3_UUID)
+ENDPOINT_ID_PE3_1_1      = DEVICE_PE3_ENDPOINT_IDS[0]
+ENDPOINT_ID_PE3_2_1      = DEVICE_PE3_ENDPOINT_IDS[1]
+ENDPOINT_ID_PE3_2_2      = DEVICE_PE3_ENDPOINT_IDS[2]
+DEVICE_PE3_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_PE3_ENDPOINT_DEFS)
+
+DEVICE_PE4_UUID          = 'PE4'
+DEVICE_PE4_ENDPOINT_DEFS = [('1/1', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', [])]
+DEVICE_PE4_ID            = json_device_id(DEVICE_PE4_UUID)
+DEVICE_PE4_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_PE4_ID, DEVICE_PE4_ENDPOINT_DEFS)
+DEVICE_PE4               = json_device_emulated_packet_router_disabled(DEVICE_PE4_UUID)
+ENDPOINT_ID_PE4_1_1      = DEVICE_PE4_ENDPOINT_IDS[0]
+ENDPOINT_ID_PE4_2_1      = DEVICE_PE4_ENDPOINT_IDS[1]
+ENDPOINT_ID_PE4_2_2      = DEVICE_PE4_ENDPOINT_IDS[2]
+DEVICE_PE4_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_PE4_ENDPOINT_DEFS)
+
+# ----- BackBone (BB) Devices ------------------------------------------------------------------------------------------
+DEVICE_BB1_UUID          = 'BB1'
+DEVICE_BB1_ENDPOINT_DEFS = [('1/1', 'copper', []), ('1/2', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', [])]
+DEVICE_BB1_ID            = json_device_id(DEVICE_BB1_UUID)
+DEVICE_BB1_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB1_ID, DEVICE_BB1_ENDPOINT_DEFS)
+DEVICE_BB1               = json_device_emulated_packet_router_disabled(DEVICE_BB1_UUID)
+ENDPOINT_ID_BB1_1_1      = DEVICE_BB1_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB1_1_2      = DEVICE_BB1_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB1_2_1      = DEVICE_BB1_ENDPOINT_IDS[2]
+ENDPOINT_ID_BB1_2_2      = DEVICE_BB1_ENDPOINT_IDS[3]
+ENDPOINT_ID_BB1_2_3      = DEVICE_BB1_ENDPOINT_IDS[4]
+DEVICE_BB1_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB1_ENDPOINT_DEFS)
+
+DEVICE_BB2_UUID          = 'BB2'
+DEVICE_BB2_ENDPOINT_DEFS = [('1/1', 'copper', []), ('1/2', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', [])]
+DEVICE_BB2_ID            = json_device_id(DEVICE_BB2_UUID)
+DEVICE_BB2_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB2_ID, DEVICE_BB2_ENDPOINT_DEFS)
+DEVICE_BB2               = json_device_emulated_packet_router_disabled(DEVICE_BB2_UUID)
+ENDPOINT_ID_BB2_1_1      = DEVICE_BB2_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB2_1_2      = DEVICE_BB2_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB2_2_1      = DEVICE_BB2_ENDPOINT_IDS[2]
+ENDPOINT_ID_BB2_2_2      = DEVICE_BB2_ENDPOINT_IDS[3]
+ENDPOINT_ID_BB2_2_3      = DEVICE_BB2_ENDPOINT_IDS[4]
+DEVICE_BB2_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB2_ENDPOINT_DEFS)
+
+DEVICE_BB3_UUID          = 'BB3'
+DEVICE_BB3_ENDPOINT_DEFS = [('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', [])]
+DEVICE_BB3_ID            = json_device_id(DEVICE_BB3_UUID)
+DEVICE_BB3_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB3_ID, DEVICE_BB3_ENDPOINT_DEFS)
+DEVICE_BB3               = json_device_emulated_packet_router_disabled(DEVICE_BB3_UUID)
+ENDPOINT_ID_BB3_2_1      = DEVICE_BB3_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB3_2_2      = DEVICE_BB3_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB3_2_3      = DEVICE_BB3_ENDPOINT_IDS[2]
+DEVICE_BB3_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB3_ENDPOINT_DEFS)
+
+DEVICE_BB4_UUID          = 'BB4'
+DEVICE_BB4_ENDPOINT_DEFS = [('1/1', 'copper', []), ('1/2', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', [])]
+DEVICE_BB4_ID            = json_device_id(DEVICE_BB4_UUID)
+DEVICE_BB4_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB4_ID, DEVICE_BB4_ENDPOINT_DEFS)
+DEVICE_BB4               = json_device_emulated_packet_router_disabled(DEVICE_BB4_UUID)
+ENDPOINT_ID_BB4_1_1      = DEVICE_BB4_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB4_1_2      = DEVICE_BB4_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB4_2_1      = DEVICE_BB4_ENDPOINT_IDS[2]
+ENDPOINT_ID_BB4_2_2      = DEVICE_BB4_ENDPOINT_IDS[3]
+ENDPOINT_ID_BB4_2_3      = DEVICE_BB4_ENDPOINT_IDS[4]
+DEVICE_BB4_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB4_ENDPOINT_DEFS)
+
+DEVICE_BB5_UUID          = 'BB5'
+DEVICE_BB5_ENDPOINT_DEFS = [('1/1', 'copper', []), ('1/2', 'copper', []),
+                            ('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', [])]
+DEVICE_BB5_ID            = json_device_id(DEVICE_BB5_UUID)
+DEVICE_BB5_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB5_ID, DEVICE_BB5_ENDPOINT_DEFS)
+DEVICE_BB5               = json_device_emulated_packet_router_disabled(DEVICE_BB5_UUID)
+ENDPOINT_ID_BB5_1_1      = DEVICE_BB5_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB5_1_2      = DEVICE_BB5_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB5_2_1      = DEVICE_BB5_ENDPOINT_IDS[2]
+ENDPOINT_ID_BB5_2_2      = DEVICE_BB5_ENDPOINT_IDS[3]
+ENDPOINT_ID_BB5_2_3      = DEVICE_BB5_ENDPOINT_IDS[4]
+DEVICE_BB5_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB5_ENDPOINT_DEFS)
+
+DEVICE_BB6_UUID          = 'BB6'
+DEVICE_BB6_ENDPOINT_DEFS = [('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', [])]
+DEVICE_BB6_ID            = json_device_id(DEVICE_BB6_UUID)
+DEVICE_BB6_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB6_ID, DEVICE_BB6_ENDPOINT_DEFS)
+DEVICE_BB6               = json_device_emulated_packet_router_disabled(DEVICE_BB6_UUID)
+ENDPOINT_ID_BB6_2_1      = DEVICE_BB6_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB6_2_2      = DEVICE_BB6_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB6_2_3      = DEVICE_BB6_ENDPOINT_IDS[2]
+DEVICE_BB6_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB6_ENDPOINT_DEFS)
+
+DEVICE_BB7_UUID          = 'BB7'
+DEVICE_BB7_ENDPOINT_DEFS = [('2/1', 'copper', []), ('2/2', 'copper', []), ('2/3', 'copper', []), ('2/4', 'copper', []),
+                            ('2/5', 'copper', []), ('2/6', 'copper', [])]
+DEVICE_BB7_ID            = json_device_id(DEVICE_BB7_UUID)
+DEVICE_BB7_ENDPOINT_IDS  = json_endpoint_ids(DEVICE_BB7_ID, DEVICE_BB7_ENDPOINT_DEFS)
+DEVICE_BB7               = json_device_emulated_packet_router_disabled(DEVICE_BB7_UUID)
+ENDPOINT_ID_BB7_2_1      = DEVICE_BB7_ENDPOINT_IDS[0]
+ENDPOINT_ID_BB7_2_2      = DEVICE_BB7_ENDPOINT_IDS[1]
+ENDPOINT_ID_BB7_2_3      = DEVICE_BB7_ENDPOINT_IDS[2]
+ENDPOINT_ID_BB7_2_4      = DEVICE_BB7_ENDPOINT_IDS[3]
+ENDPOINT_ID_BB7_2_5      = DEVICE_BB7_ENDPOINT_IDS[4]
+ENDPOINT_ID_BB7_2_6      = DEVICE_BB7_ENDPOINT_IDS[5]
+DEVICE_BB7_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_BB7_ENDPOINT_DEFS)
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+LINK_CE1_PE1_UUID, LINK_CE1_PE1_ID, LINK_CE1_PE1 = link(ENDPOINT_ID_CE1_1_1, ENDPOINT_ID_PE1_1_1)
+LINK_CE2_PE2_UUID, LINK_CE2_PE2_ID, LINK_CE2_PE2 = link(ENDPOINT_ID_CE2_1_1, ENDPOINT_ID_PE2_1_1)
+LINK_CE3_PE3_UUID, LINK_CE3_PE3_ID, LINK_CE3_PE3 = link(ENDPOINT_ID_CE3_1_1, ENDPOINT_ID_PE3_1_1)
+LINK_CE4_PE4_UUID, LINK_CE4_PE4_ID, LINK_CE4_PE4 = link(ENDPOINT_ID_CE4_1_1, ENDPOINT_ID_PE4_1_1)
+
+LINK_PE1_BB1_UUID, LINK_PE1_BB1_ID, LINK_PE1_BB1 = link(ENDPOINT_ID_PE1_2_1, ENDPOINT_ID_BB1_1_1)
+LINK_PE1_BB2_UUID, LINK_PE1_BB2_ID, LINK_PE1_BB2 = link(ENDPOINT_ID_PE1_2_2, ENDPOINT_ID_BB2_1_1)
+LINK_PE2_BB1_UUID, LINK_PE2_BB1_ID, LINK_PE2_BB1 = link(ENDPOINT_ID_PE2_2_1, ENDPOINT_ID_BB1_1_2)
+LINK_PE2_BB2_UUID, LINK_PE2_BB2_ID, LINK_PE2_BB2 = link(ENDPOINT_ID_PE2_2_2, ENDPOINT_ID_BB2_1_2)
+
+LINK_PE3_BB4_UUID, LINK_PE3_BB4_ID, LINK_PE3_BB4 = link(ENDPOINT_ID_PE3_2_1, ENDPOINT_ID_BB4_1_1)
+LINK_PE3_BB5_UUID, LINK_PE3_BB5_ID, LINK_PE3_BB5 = link(ENDPOINT_ID_PE3_2_2, ENDPOINT_ID_BB5_1_1)
+LINK_PE4_BB4_UUID, LINK_PE4_BB4_ID, LINK_PE4_BB4 = link(ENDPOINT_ID_PE4_2_1, ENDPOINT_ID_BB4_1_2)
+LINK_PE4_BB5_UUID, LINK_PE4_BB5_ID, LINK_PE4_BB5 = link(ENDPOINT_ID_PE4_2_2, ENDPOINT_ID_BB5_1_2)
+
+LINK_BB1_BB2_UUID, LINK_BB1_BB2_ID, LINK_BB1_BB2 = link(ENDPOINT_ID_BB1_2_1, ENDPOINT_ID_BB2_2_2)
+LINK_BB2_BB3_UUID, LINK_BB2_BB3_ID, LINK_BB2_BB3 = link(ENDPOINT_ID_BB2_2_1, ENDPOINT_ID_BB3_2_2)
+LINK_BB3_BB4_UUID, LINK_BB3_BB4_ID, LINK_BB3_BB4 = link(ENDPOINT_ID_BB3_2_1, ENDPOINT_ID_BB4_2_2)
+LINK_BB4_BB5_UUID, LINK_BB4_BB5_ID, LINK_BB4_BB5 = link(ENDPOINT_ID_BB4_2_1, ENDPOINT_ID_BB5_2_2)
+LINK_BB5_BB6_UUID, LINK_BB5_BB6_ID, LINK_BB5_BB6 = link(ENDPOINT_ID_BB5_2_1, ENDPOINT_ID_BB6_2_2)
+LINK_BB6_BB1_UUID, LINK_BB6_BB1_ID, LINK_BB6_BB1 = link(ENDPOINT_ID_BB6_2_1, ENDPOINT_ID_BB1_2_2)
+
+LINK_BB1_BB7_UUID, LINK_BB1_BB7_ID, LINK_BB1_BB7 = link(ENDPOINT_ID_BB1_2_3, ENDPOINT_ID_BB7_2_1)
+LINK_BB2_BB7_UUID, LINK_BB2_BB7_ID, LINK_BB2_BB7 = link(ENDPOINT_ID_BB2_2_3, ENDPOINT_ID_BB7_2_2)
+LINK_BB3_BB7_UUID, LINK_BB3_BB7_ID, LINK_BB3_BB7 = link(ENDPOINT_ID_BB3_2_3, ENDPOINT_ID_BB7_2_3)
+LINK_BB4_BB7_UUID, LINK_BB4_BB7_ID, LINK_BB4_BB7 = link(ENDPOINT_ID_BB4_2_3, ENDPOINT_ID_BB7_2_4)
+LINK_BB5_BB7_UUID, LINK_BB5_BB7_ID, LINK_BB5_BB7 = link(ENDPOINT_ID_BB5_2_3, ENDPOINT_ID_BB7_2_5)
+LINK_BB6_BB7_UUID, LINK_BB6_BB7_ID, LINK_BB6_BB7 = link(ENDPOINT_ID_BB6_2_3, ENDPOINT_ID_BB7_2_6)
+
+
+# ----- WIM Service Settings -------------------------------------------------------------------------------------------
+WIM_USERNAME = 'admin'
+WIM_PASSWORD = 'admin'
+
+def mapping(site_id, ce_endpoint_id, pe_device_id, priority=None, redundant=[]):
+    ce_device_uuid = ce_endpoint_id['device_id']['device_uuid']['uuid']
+    ce_endpoint_uuid = ce_endpoint_id['endpoint_uuid']['uuid']
+    pe_device_uuid = pe_device_id['device_uuid']['uuid']
+    service_endpoint_id = '{:s}-{:s}-{:s}'.format(site_id, ce_device_uuid, ce_endpoint_uuid)
+    bearer = '{:s}-{:s}'.format(ce_device_uuid, pe_device_uuid)
+    _mapping = {
+        'service_endpoint_id': service_endpoint_id,
+        'datacenter_id': site_id, 'device_id': ce_device_uuid, 'device_interface_id': ce_endpoint_uuid,
+        'service_mapping_info': {
+            'site-id': site_id,
+            'bearer': {'bearer-reference': bearer},
+        }
+    }
+    if priority is not None: _mapping['service_mapping_info']['priority'] = priority
+    if len(redundant) > 0: _mapping['service_mapping_info']['redundant'] = redundant
+    return service_endpoint_id, _mapping
+
+WIM_SEP_DC1_PRI, WIM_MAP_DC1_PRI = mapping('DC1', ENDPOINT_ID_CE1_1_1, DEVICE_PE1_ID, priority=10, redundant=['DC1-CE2-1/1'])
+WIM_SEP_DC1_SEC, WIM_MAP_DC1_SEC = mapping('DC1', ENDPOINT_ID_CE2_1_1, DEVICE_PE2_ID, priority=20)
+WIM_SEP_DC2_PRI, WIM_MAP_DC2_PRI = mapping('DC2', ENDPOINT_ID_CE3_1_1, DEVICE_PE3_ID, priority=10, redundant=['DC2-CE4-1/1'])
+WIM_SEP_DC2_SEC, WIM_MAP_DC2_SEC = mapping('DC2', ENDPOINT_ID_CE4_1_1, DEVICE_PE4_ID, priority=20)
+
+WIM_MAPPING  = [WIM_MAP_DC1_PRI, WIM_MAP_DC1_SEC, WIM_MAP_DC2_PRI, WIM_MAP_DC2_SEC]
+
+WIM_SRV_VLAN_ID = 300
+WIM_SERVICE_TYPE = 'ELAN'
+WIM_SERVICE_CONNECTION_POINTS = [
+    {'service_endpoint_id': WIM_SEP_DC1_PRI,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_VLAN_ID}},
+    {'service_endpoint_id': WIM_SEP_DC2_PRI,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_VLAN_ID}},
+]
+
+
+# ----- Object Collections ---------------------------------------------------------------------------------------------
+
+CONTEXTS = [CONTEXT]
+TOPOLOGIES = [TOPOLOGY]
+
+DEVICES = [
+    (DEVICE_CE1, DEVICE_CE1_CONNECT_RULES),
+    (DEVICE_CE2, DEVICE_CE2_CONNECT_RULES),
+    (DEVICE_CE3, DEVICE_CE3_CONNECT_RULES),
+    (DEVICE_CE4, DEVICE_CE4_CONNECT_RULES),
+
+    (DEVICE_PE1, DEVICE_PE1_CONNECT_RULES),
+    (DEVICE_PE2, DEVICE_PE2_CONNECT_RULES),
+    (DEVICE_PE3, DEVICE_PE3_CONNECT_RULES),
+    (DEVICE_PE4, DEVICE_PE4_CONNECT_RULES),
+
+    (DEVICE_BB1, DEVICE_BB1_CONNECT_RULES),
+    (DEVICE_BB2, DEVICE_BB2_CONNECT_RULES),
+    (DEVICE_BB6, DEVICE_BB6_CONNECT_RULES),
+    (DEVICE_BB7, DEVICE_BB7_CONNECT_RULES),
+    (DEVICE_BB3, DEVICE_BB3_CONNECT_RULES),
+    (DEVICE_BB5, DEVICE_BB5_CONNECT_RULES),
+    (DEVICE_BB4, DEVICE_BB4_CONNECT_RULES),
+]
+
+LINKS = [
+    LINK_CE1_PE1, LINK_CE2_PE2, LINK_CE3_PE3, LINK_CE4_PE4,
+    LINK_PE1_BB1, LINK_PE1_BB2, LINK_PE2_BB1, LINK_PE2_BB2,
+    LINK_PE3_BB5, LINK_PE3_BB4, LINK_PE4_BB5, LINK_PE4_BB4,
+    LINK_BB1_BB2, LINK_BB2_BB3, LINK_BB3_BB4, LINK_BB4_BB5, LINK_BB5_BB6, LINK_BB6_BB1,
+    LINK_BB1_BB7, LINK_BB2_BB7, LINK_BB3_BB7, LINK_BB4_BB7, LINK_BB5_BB7, LINK_BB6_BB7,
+]
diff --git a/src/tests/ecoc22/tests/Objects_DC_CSGW_TN.py b/src/tests/ecoc22/tests/Objects_DC_CSGW_TN.py
new file mode 100644
index 0000000000000000000000000000000000000000..229e3d5fe3cee54fb7295ac0049507ec4e348a04
--- /dev/null
+++ b/src/tests/ecoc22/tests/Objects_DC_CSGW_TN.py
@@ -0,0 +1,227 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 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_datacenter_disabled,
+    json_device_emulated_packet_router_disabled, json_device_id)
+from common.tools.object_factory.EndPoint import json_endpoints
+from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id
+from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+
+# if true, Device component is present and will infeer the endpoints from connect-rules
+# if false, Device component is not present and device objects must contain preconfigured endpoints
+ADD_CONNECT_RULES_TO_DEVICES = os.environ.get('ADD_CONNECT_RULES_TO_DEVICES', 'True')
+ADD_CONNECT_RULES_TO_DEVICES = ADD_CONNECT_RULES_TO_DEVICES.upper() in {'T', 'TRUE', '1', 'Y', 'YES'}
+
+def compose_router(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_packet_router_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_datacenter(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_datacenter_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_link(endpoint_a, endpoint_z):
+    link_uuid = get_link_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    link_id   = json_link_id(link_uuid)
+    link      = json_link(link_uuid, [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']])
+    return link_id, link
+
+def compose_service(endpoint_a, endpoint_z, constraints=[]):
+    service_uuid = get_service_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    endpoint_ids = [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']]
+    service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints)
+    return service
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+# ----- Domains --------------------------------------------------------------------------------------------------------
+# Overall network topology
+TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID
+TOPO_ADMIN_ID   = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+TOPO_ADMIN      = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #1 Network
+TOPO_DC1_UUID = 'DC1'
+TOPO_DC1_ID   = json_topology_id(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+TOPO_DC1      = json_topology(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #2 Network
+TOPO_DC2_UUID = 'DC2'
+TOPO_DC2_ID   = json_topology_id(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+TOPO_DC2      = json_topology(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+
+# CellSite #1 Network
+TOPO_CS1_UUID = 'CS1'
+TOPO_CS1_ID   = json_topology_id(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+TOPO_CS1      = json_topology(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+
+# CellSite #2 Network
+TOPO_CS2_UUID = 'CS2'
+TOPO_CS2_ID   = json_topology_id(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+TOPO_CS2      = json_topology(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+
+# Transport Network Network
+TOPO_TN_UUID = 'TN'
+TOPO_TN_ID   = json_topology_id(TOPO_TN_UUID, context_id=CONTEXT_ID)
+TOPO_TN      = json_topology(TOPO_TN_UUID, context_id=CONTEXT_ID)
+
+
+# ----- Devices --------------------------------------------------------------------------------------------------------
+# DataCenters
+DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_datacenter('DC1-GW', ['eth1', 'eth2', 'int'])
+DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_datacenter('DC2-GW', ['eth1', 'eth2', 'int'])
+
+# CellSites
+DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_router('CS1-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_router('CS1-GW2', ['10/1', '1/1', '1/2'])
+DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_router('CS2-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_router('CS2-GW2', ['10/1', '1/1', '1/2'])
+
+# Transport Network
+DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_router('TN-R1', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_router('TN-R2', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_router('TN-R3', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_router('TN-R4', ['1/1', '1/2', '2/1', '2/2', '2/3'])
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+# InterDomain DC-CSGW
+LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW1 = compose_link(DEV_DC1GW_EPS[0], DEV_CS1GW1_EPS[0])
+LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1GW2_EPS[0])
+LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0])
+LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0])
+
+# InterDomain CSGW-TN
+LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0])
+LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0])
+LINK_CS1GW1_TNR2_ID, LINK_CS1GW1_TNR2 = compose_link(DEV_CS1GW1_EPS[2], DEV_TNR2_EPS[1])
+LINK_CS1GW2_TNR1_ID, LINK_CS1GW2_TNR1 = compose_link(DEV_CS1GW2_EPS[2], DEV_TNR1_EPS[1])
+LINK_CS2GW1_TNR3_ID, LINK_CS2GW1_TNR3 = compose_link(DEV_CS2GW1_EPS[1], DEV_TNR3_EPS[0])
+LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4_EPS[0])
+LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1])
+LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1])
+
+# IntraDomain TN
+LINK_TNR1_TNR2_ID, LINK_TNR1_TNR2 = compose_link(DEV_TNR1_EPS[2], DEV_TNR2_EPS[3])
+LINK_TNR2_TNR3_ID, LINK_TNR2_TNR3 = compose_link(DEV_TNR2_EPS[2], DEV_TNR3_EPS[3])
+LINK_TNR3_TNR4_ID, LINK_TNR3_TNR4 = compose_link(DEV_TNR3_EPS[2], DEV_TNR4_EPS[3])
+LINK_TNR4_TNR1_ID, LINK_TNR4_TNR1 = compose_link(DEV_TNR4_EPS[2], DEV_TNR1_EPS[3])
+LINK_TNR1_TNR3_ID, LINK_TNR1_TNR3 = compose_link(DEV_TNR1_EPS[4], DEV_TNR3_EPS[4])
+LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4])
+
+
+# ----- WIM Service Settings -------------------------------------------------------------------------------------------
+WIM_USERNAME = 'admin'
+WIM_PASSWORD = 'admin'
+
+def mapping(site_id, ce_endpoint_id, pe_device_id, priority=None, redundant=[]):
+    ce_endpoint_id = ce_endpoint_id['endpoint_id']
+    ce_device_uuid = ce_endpoint_id['device_id']['device_uuid']['uuid']
+    ce_endpoint_uuid = ce_endpoint_id['endpoint_uuid']['uuid']
+    pe_device_uuid = pe_device_id['device_uuid']['uuid']
+    service_endpoint_id = '{:s}:{:s}:{:s}'.format(site_id, ce_device_uuid, ce_endpoint_uuid)
+    bearer = '{:s}:{:s}'.format(ce_device_uuid, pe_device_uuid)
+    _mapping = {
+        'service_endpoint_id': service_endpoint_id,
+        'datacenter_id': site_id, 'device_id': ce_device_uuid, 'device_interface_id': ce_endpoint_uuid,
+        'service_mapping_info': {
+            'site-id': site_id,
+            'bearer': {'bearer-reference': bearer},
+        }
+    }
+    if priority is not None: _mapping['service_mapping_info']['priority'] = priority
+    if len(redundant) > 0: _mapping['service_mapping_info']['redundant'] = redundant
+    return service_endpoint_id, _mapping
+
+WIM_SEP_DC1_PRI, WIM_MAP_DC1_PRI = mapping('DC1', DEV_DC1GW_EPS[0], DEV_CS1GW1_ID, priority=10, redundant=['DC1:DC1-GW:eth2'])
+WIM_SEP_DC1_SEC, WIM_MAP_DC1_SEC = mapping('DC1', DEV_DC1GW_EPS[1], DEV_CS1GW2_ID, priority=20, redundant=['DC1:DC1-GW:eth1'])
+WIM_SEP_DC2_PRI, WIM_MAP_DC2_PRI = mapping('DC2', DEV_DC2GW_EPS[0], DEV_CS2GW1_ID, priority=10, redundant=['DC2:DC2-GW:eth2'])
+WIM_SEP_DC2_SEC, WIM_MAP_DC2_SEC = mapping('DC2', DEV_DC2GW_EPS[1], DEV_CS2GW2_ID, priority=20, redundant=['DC2:DC2-GW:eth1'])
+
+WIM_MAPPING  = [WIM_MAP_DC1_PRI, WIM_MAP_DC1_SEC, WIM_MAP_DC2_PRI, WIM_MAP_DC2_SEC]
+
+WIM_SRV_VLAN_ID = 300
+WIM_SERVICE_TYPE = 'ELAN'
+WIM_SERVICE_CONNECTION_POINTS = [
+    {'service_endpoint_id': WIM_SEP_DC1_PRI,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_VLAN_ID}},
+    {'service_endpoint_id': WIM_SEP_DC2_PRI,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_VLAN_ID}},
+]
+
+
+# ----- Containers -----------------------------------------------------------------------------------------------------
+CONTEXTS   = [  CONTEXT ]
+TOPOLOGIES = [  TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN ]
+DEVICES    = [  DEV_DC1GW, DEV_DC2GW,
+                DEV_CS1GW1, DEV_CS1GW2, DEV_CS2GW1, DEV_CS2GW2,
+                DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4,
+            ]
+LINKS      = [  LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2,
+                LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1,
+                LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3,
+                LINK_TNR1_TNR2, LINK_TNR2_TNR3, LINK_TNR3_TNR4, LINK_TNR4_TNR1, LINK_TNR1_TNR3, LINK_TNR2_TNR4,
+            ]
+
+OBJECTS_PER_TOPOLOGY = [
+    (TOPO_ADMIN_ID,
+        [   DEV_DC1GW_ID, DEV_DC2GW_ID,
+            DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID,
+            DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+        ],
+        [   LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID,
+            LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID,
+            LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID,
+            LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
+            LINK_TNR2_TNR4_ID,
+        ],
+    ),
+    (TOPO_DC1_ID,
+        [DEV_DC1GW_ID],
+        []),
+    (TOPO_DC2_ID,
+        [DEV_DC2GW_ID],
+        []),
+    (TOPO_CS1_ID,
+        [DEV_CS1GW1_ID, DEV_CS1GW2_ID],
+        []),
+    (TOPO_CS2_ID,
+        [DEV_CS2GW1_ID, DEV_CS2GW2_ID],
+        []),
+    (TOPO_TN_ID,
+        [   DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+        ],
+        [   LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
+            LINK_TNR2_TNR4_ID,
+        ]),
+]
diff --git a/src/tests/ecoc22/tests/Objects_DC_CSGW_TN_OLS.py b/src/tests/ecoc22/tests/Objects_DC_CSGW_TN_OLS.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d67b1a41a16709e2e47bda9f9dc0e7e4bfdc1cf
--- /dev/null
+++ b/src/tests/ecoc22/tests/Objects_DC_CSGW_TN_OLS.py
@@ -0,0 +1,237 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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, uuid
+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_datacenter_disabled,
+    json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled, json_device_id)
+from common.tools.object_factory.EndPoint import json_endpoints
+from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id
+from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+
+# if true, Device component is present and will infeer the endpoints from connect-rules
+# if false, Device component is not present and device objects must contain preconfigured endpoints
+ADD_CONNECT_RULES_TO_DEVICES = os.environ.get('ADD_CONNECT_RULES_TO_DEVICES', 'False')
+ADD_CONNECT_RULES_TO_DEVICES = ADD_CONNECT_RULES_TO_DEVICES.upper() in {'T', 'TRUE', '1', 'Y', 'YES'}
+
+def compose_router(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_packet_router_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_ols(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'optical', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_tapi_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_datacenter(device_uuid, endpoint_uuids, topology_id=None):
+    device_id = json_device_id(device_uuid)
+    r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids]
+    config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else []
+    endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id)
+    j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints
+    device = json_device_emulated_datacenter_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints)
+    return device_id, endpoints, device
+
+def compose_link(endpoint_a, endpoint_z):
+    link_uuid = get_link_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    link_id   = json_link_id(link_uuid)
+    link      = json_link(link_uuid, [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']])
+    return link_id, link
+
+def compose_service(endpoint_a, endpoint_z, constraints=[]):
+    service_uuid = get_service_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id'])
+    endpoint_ids = [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']]
+    service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints)
+    return service
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+# ----- Domains --------------------------------------------------------------------------------------------------------
+# Overall network topology
+TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID
+TOPO_ADMIN_ID   = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+TOPO_ADMIN      = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #1 Network
+TOPO_DC1_UUID = 'DC1'
+TOPO_DC1_ID   = json_topology_id(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+TOPO_DC1      = json_topology(TOPO_DC1_UUID, context_id=CONTEXT_ID)
+
+# DataCenter #2 Network
+TOPO_DC2_UUID = 'DC2'
+TOPO_DC2_ID   = json_topology_id(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+TOPO_DC2      = json_topology(TOPO_DC2_UUID, context_id=CONTEXT_ID)
+
+# CellSite #1 Network
+TOPO_CS1_UUID = 'CS1'
+TOPO_CS1_ID   = json_topology_id(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+TOPO_CS1      = json_topology(TOPO_CS1_UUID, context_id=CONTEXT_ID)
+
+# CellSite #2 Network
+TOPO_CS2_UUID = 'CS2'
+TOPO_CS2_ID   = json_topology_id(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+TOPO_CS2      = json_topology(TOPO_CS2_UUID, context_id=CONTEXT_ID)
+
+# Transport Network Network
+TOPO_TN_UUID = 'TN'
+TOPO_TN_ID   = json_topology_id(TOPO_TN_UUID, context_id=CONTEXT_ID)
+TOPO_TN      = json_topology(TOPO_TN_UUID, context_id=CONTEXT_ID)
+
+
+# ----- Devices --------------------------------------------------------------------------------------------------------
+# DataCenters
+DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_datacenter('DC1-GW', ['eth1', 'eth2', 'int'])
+DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_datacenter('DC2-GW', ['eth1', 'eth2', 'int'])
+
+# CellSites
+DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_router('CS1-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_router('CS1-GW2', ['10/1', '1/1', '1/2'])
+DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_router('CS2-GW1', ['10/1', '1/1', '1/2'])
+DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_router('CS2-GW2', ['10/1', '1/1', '1/2'])
+
+# Transport Network
+DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_router('TN-R1', ['1/1', '1/2', '2/1'])
+DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_router('TN-R2', ['1/1', '1/2', '2/1'])
+DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_router('TN-R3', ['1/1', '1/2', '2/1'])
+DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_router('TN-R4', ['1/1', '1/2', '2/1'])
+tols_ep_uuids = [str(uuid.uuid4()).split('-')[-1] for _ in range(4)]
+DEV_TOLS_ID, DEV_TOLS_EPS, DEV_TOLS = compose_ols('TN-OLS', tols_ep_uuids)
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+# InterDomain DC-CSGW
+LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW1 = compose_link(DEV_DC1GW_EPS[0], DEV_CS1GW1_EPS[0])
+LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1GW2_EPS[0])
+LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0])
+LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0])
+
+# InterDomain CSGW-TN
+LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0])
+LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0])
+LINK_CS1GW1_TNR2_ID, LINK_CS1GW1_TNR2 = compose_link(DEV_CS1GW1_EPS[2], DEV_TNR2_EPS[1])
+LINK_CS1GW2_TNR1_ID, LINK_CS1GW2_TNR1 = compose_link(DEV_CS1GW2_EPS[2], DEV_TNR1_EPS[1])
+LINK_CS2GW1_TNR3_ID, LINK_CS2GW1_TNR3 = compose_link(DEV_CS2GW1_EPS[1], DEV_TNR3_EPS[0])
+LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4_EPS[0])
+LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1])
+LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1])
+
+# IntraDomain TN
+LINK_TNR1_TOLS_ID, LINK_TNR1_TOLS = compose_link(DEV_TNR1_EPS[2], DEV_TOLS_EPS[0])
+LINK_TNR2_TOLS_ID, LINK_TNR2_TOLS = compose_link(DEV_TNR2_EPS[2], DEV_TOLS_EPS[1])
+LINK_TNR3_TOLS_ID, LINK_TNR3_TOLS = compose_link(DEV_TNR3_EPS[2], DEV_TOLS_EPS[2])
+LINK_TNR4_TOLS_ID, LINK_TNR4_TOLS = compose_link(DEV_TNR4_EPS[2], DEV_TOLS_EPS[3])
+
+
+# ----- WIM Service Settings -------------------------------------------------------------------------------------------
+WIM_USERNAME = 'admin'
+WIM_PASSWORD = 'admin'
+
+def mapping(site_id, ce_endpoint_id, pe_device_id, priority=None, redundant=[]):
+    ce_endpoint_id = ce_endpoint_id['endpoint_id']
+    ce_device_uuid = ce_endpoint_id['device_id']['device_uuid']['uuid']
+    ce_endpoint_uuid = ce_endpoint_id['endpoint_uuid']['uuid']
+    pe_device_uuid = pe_device_id['device_uuid']['uuid']
+    service_endpoint_id = '{:s}:{:s}:{:s}'.format(site_id, ce_device_uuid, ce_endpoint_uuid)
+    bearer = '{:s}:{:s}'.format(ce_device_uuid, pe_device_uuid)
+    _mapping = {
+        'service_endpoint_id': service_endpoint_id,
+        'datacenter_id': site_id, 'device_id': ce_device_uuid, 'device_interface_id': ce_endpoint_uuid,
+        'service_mapping_info': {
+            'site-id': site_id,
+            'bearer': {'bearer-reference': bearer},
+        }
+    }
+    if priority is not None: _mapping['service_mapping_info']['priority'] = priority
+    if len(redundant) > 0: _mapping['service_mapping_info']['redundant'] = redundant
+    return service_endpoint_id, _mapping
+
+WIM_SEP_DC1_PRI, WIM_MAP_DC1_PRI = mapping('DC1', DEV_DC1GW_EPS[0], DEV_CS1GW1_ID, priority=10, redundant=['DC1:DC1-GW:eth2'])
+WIM_SEP_DC1_SEC, WIM_MAP_DC1_SEC = mapping('DC1', DEV_DC1GW_EPS[1], DEV_CS1GW2_ID, priority=20, redundant=['DC1:DC1-GW:eth1'])
+WIM_SEP_DC2_PRI, WIM_MAP_DC2_PRI = mapping('DC2', DEV_DC2GW_EPS[0], DEV_CS2GW1_ID, priority=10, redundant=['DC2:DC2-GW:eth2'])
+WIM_SEP_DC2_SEC, WIM_MAP_DC2_SEC = mapping('DC2', DEV_DC2GW_EPS[1], DEV_CS2GW2_ID, priority=20, redundant=['DC2:DC2-GW:eth1'])
+
+WIM_MAPPING  = [WIM_MAP_DC1_PRI, WIM_MAP_DC1_SEC, WIM_MAP_DC2_PRI, WIM_MAP_DC2_SEC]
+
+WIM_SRV_VLAN_ID = 300
+WIM_SERVICE_TYPE = 'ELAN'
+WIM_SERVICE_CONNECTION_POINTS = [
+    {'service_endpoint_id': WIM_SEP_DC1_PRI,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_VLAN_ID}},
+    {'service_endpoint_id': WIM_SEP_DC2_PRI,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_VLAN_ID}},
+]
+
+
+# ----- Containers -----------------------------------------------------------------------------------------------------
+CONTEXTS   = [  CONTEXT ]
+TOPOLOGIES = [  TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN ]
+DEVICES    = [  DEV_DC1GW, DEV_DC2GW,
+                DEV_CS1GW1, DEV_CS1GW2, DEV_CS2GW1, DEV_CS2GW2,
+                DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4,
+                DEV_TOLS,
+            ]
+LINKS      = [  LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2,
+                LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1,
+                LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3,
+                LINK_TNR1_TOLS, LINK_TNR2_TOLS, LINK_TNR3_TOLS, LINK_TNR4_TOLS,
+            ]
+
+OBJECTS_PER_TOPOLOGY = [
+    (TOPO_ADMIN_ID,
+        [   DEV_DC1GW_ID, DEV_DC2GW_ID,
+            DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID,
+            DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+            DEV_TOLS_ID,
+        ],
+        [   LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID,
+            LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID,
+            LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID,
+            LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID,
+        ],
+    ),
+    (TOPO_DC1_ID,
+        [DEV_DC1GW_ID],
+        []),
+    (TOPO_DC2_ID,
+        [DEV_DC2GW_ID],
+        []),
+    (TOPO_CS1_ID,
+        [DEV_CS1GW1_ID, DEV_CS1GW2_ID],
+        []),
+    (TOPO_CS2_ID,
+        [DEV_CS2GW1_ID, DEV_CS2GW2_ID],
+        []),
+    (TOPO_TN_ID,
+        [   DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
+            DEV_TOLS_ID,
+        ],
+        [   LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID,
+        ]),
+]
diff --git a/src/tests/ecoc22/tests/Tools.py b/src/tests/ecoc22/tests/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..33205da9baeb6c9fe93a389e9744053aea664b16
--- /dev/null
+++ b/src/tests/ecoc22/tests/Tools.py
@@ -0,0 +1,36 @@
+from typing import Dict, List, Tuple
+from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
+from common.tools.object_factory.Link import json_link, json_link_id
+
+def json_endpoint_ids(device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]]):
+    return [
+        json_endpoint_id(device_id, ep_uuid, topology_id=None)
+        for ep_uuid, _, _ in endpoint_descriptors
+    ]
+
+def json_endpoints(device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]]):
+    return [
+        json_endpoint(device_id, ep_uuid, ep_type, topology_id=None, kpi_sample_types=ep_sample_types)
+        for ep_uuid, ep_type, ep_sample_types 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 link(a_endpoint_id, z_endpoint_id) -> Tuple[str, Dict, Dict]:
+    link_uuid = get_link_uuid(a_endpoint_id, z_endpoint_id)
+    link_id   = json_link_id(link_uuid)
+    link_data = json_link(link_uuid, [a_endpoint_id, z_endpoint_id])
+    return link_uuid, link_id, link_data
+
+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/ecoc22/tests/__init__.py b/src/tests/ecoc22/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/tests/ecoc22/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/ecoc22/tests/test_functional_bootstrap.py b/src/tests/ecoc22/tests/test_functional_bootstrap.py
new file mode 100644
index 0000000000000000000000000000000000000000..210e53670d88030a69a3a14f36ec8e859cf681b8
--- /dev/null
+++ b/src/tests/ecoc22/tests/test_functional_bootstrap.py
@@ -0,0 +1,90 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+from common.proto.context_pb2 import Context, ContextId, Device, DeviceId, Empty, Link, LinkId, Topology, TopologyId
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from .Fixtures import context_client, device_client
+#from .Objects_BigNet import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+from .Objects_DC_CSGW_TN import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, OBJECTS_PER_TOPOLOGY
+#from .Objects_DC_CSGW_TN_OLS import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+
+def test_scenario_empty(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure database is empty -------------------------------------------------------------------
+    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
+
+
+def test_prepare_environment(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client : DeviceClient):  # pylint: disable=redefined-outer-name
+
+    for context  in CONTEXTS  : context_client.SetContext (Context (**context ))
+    for topology in TOPOLOGIES: context_client.SetTopology(Topology(**topology))
+
+    for device   in DEVICES   : device_client .AddDevice  (Device  (**device  ))
+    for topology_id, device_ids, _ in OBJECTS_PER_TOPOLOGY:
+        topology = Topology()
+        topology.CopyFrom(context_client.GetTopology(TopologyId(**topology_id)))
+
+        device_ids_in_topology = {device_id.device_uuid.uuid for device_id in topology.device_ids}
+        func_device_id_not_added = lambda device_id: device_id['device_uuid']['uuid'] not in device_ids_in_topology
+        func_device_id_json_to_grpc = lambda device_id: DeviceId(**device_id)
+        device_ids_to_add = list(map(func_device_id_json_to_grpc, filter(func_device_id_not_added, device_ids)))
+        topology.device_ids.extend(device_ids_to_add)
+
+        context_client.SetTopology(topology)
+
+    for link     in LINKS     : context_client.SetLink    (Link    (**link    ))
+    for topology_id, _, link_ids in OBJECTS_PER_TOPOLOGY:
+        topology = Topology()
+        topology.CopyFrom(context_client.GetTopology(TopologyId(**topology_id)))
+
+        link_ids_in_topology = {link_id.link_uuid.uuid for link_id in topology.link_ids}
+        func_link_id_not_added = lambda link_id: link_id['link_uuid']['uuid'] not in link_ids_in_topology
+        func_link_id_json_to_grpc = lambda link_id: LinkId(**link_id)
+        link_ids_to_add = list(map(func_link_id_json_to_grpc, filter(func_link_id_not_added, link_ids)))
+        topology.link_ids.extend(link_ids_to_add)
+
+        context_client.SetTopology(topology)
+
+
+def test_scenario_ready(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure scenario is ready -------------------------------------------------------------------
+    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
diff --git a/src/tests/ecoc22/tests/test_functional_cleanup.py b/src/tests/ecoc22/tests/test_functional_cleanup.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a8439555b58f681fc24bebb9bc9858a9c61458c
--- /dev/null
+++ b/src/tests/ecoc22/tests/test_functional_cleanup.py
@@ -0,0 +1,66 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+from common.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from .Fixtures import context_client, device_client
+#from .Objects_BigNet import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+from .Objects_DC_CSGW_TN import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+#from .Objects_DC_CSGW_TN_OLS import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+
+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
+
+    for link     in LINKS     : context_client.RemoveLink    (LinkId    (**link    ['link_id'    ]))
+    for device   in DEVICES   : device_client .DeleteDevice  (DeviceId  (**device  ['device_id'  ]))
+    for topology in TOPOLOGIES: context_client.RemoveTopology(TopologyId(**topology['topology_id']))
+    for context  in CONTEXTS  : context_client.RemoveContext (ContextId (**context ['context_id' ]))
+
+
+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/ecoc22/tests/test_functional_create_service.py b/src/tests/ecoc22/tests/test_functional_create_service.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e830bdbe1cb5adaf1559314a07b826ac73c32d1
--- /dev/null
+++ b/src/tests/ecoc22/tests/test_functional_create_service.py
@@ -0,0 +1,78 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+from common.proto.context_pb2 import ContextId, Empty
+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 .Fixtures import context_client, osm_wim
+#from .Objects_BigNet import (
+#    CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE)
+from .Objects_DC_CSGW_TN import (
+    CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE)
+#from .Objects_DC_CSGW_TN_OLS import (
+#    CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+
+def test_scenario_is_correct(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure links are created -------------------------------------------------------------------
+    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_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
+    # ----- Create Service ---------------------------------------------------------------------------------------------
+    service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
+    osm_wim.get_connectivity_service_status(service_uuid)
+
+
+def test_scenario_service_created(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure service is created ------------------------------------------------------------------
+    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))
+    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+    assert len(response.services) == 1 # L2NM
+    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) == 2 # 2 connections per service (primary + backup)
diff --git a/src/tests/ecoc22/tests/test_functional_delete_service.py b/src/tests/ecoc22/tests/test_functional_delete_service.py
new file mode 100644
index 0000000000000000000000000000000000000000..4bc322a0b0ac125896063eac0a066e8363d7c070
--- /dev/null
+++ b/src/tests/ecoc22/tests/test_functional_delete_service.py
@@ -0,0 +1,98 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum
+from common.tests.EventTools import EVENT_REMOVE, EVENT_UPDATE, check_events
+from common.tools.object_factory.Connection import json_connection_id
+from common.tools.object_factory.Device import json_device_id
+from common.tools.object_factory.Service import json_service_id
+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 .Fixtures import context_client, osm_wim
+#from .Objects_BigNet import (
+#    CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE)
+from .Objects_DC_CSGW_TN import (
+    CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE)
+#from .Objects_DC_CSGW_TN_OLS import (
+#    CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DEVTYPE_EMU_PR  = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
+
+def test_scenario_is_correct(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure service is created ------------------------------------------------------------------
+    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))
+    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+    assert len(response.services) == 1 # L2NM
+    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) == 2 # 2 connections per service
+
+
+def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
+    # ----- Delete Service ---------------------------------------------------------------------------------------------
+    response = context_client.ListServices(ContextId(**CONTEXT_ID))
+    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+    service_uuids = set()
+    for service in response.services:
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_L2NM: continue
+        service_uuid = service.service_id.service_uuid.uuid
+        if service_uuid.endswith(':optical'): continue
+        service_uuids.add(service_uuid)
+        osm_wim.conn_info[service_uuid] = {}
+
+    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_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
diff --git a/src/tests/oeccpsc22/tests/Tools.py b/src/tests/oeccpsc22/tests/Tools.py
index a782b6bb3e541e4331f5f95164e69def5640f556..d26c8ae11468f05dc48cb55dc202b9f0efc1d3b6 100644
--- a/src/tests/oeccpsc22/tests/Tools.py
+++ b/src/tests/oeccpsc22/tests/Tools.py
@@ -12,7 +12,7 @@ def json_endpoint_ids(device_id : Dict, endpoint_descriptors : List[Tuple[str, s
 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'])
+        z_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']
diff --git a/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py b/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
index e6f6ccbc96152eb7e3a33317293261e28c89d713..b31e868741a7996494d1f7763a3f7e237ca216a1 100644
--- a/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
+++ b/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
@@ -27,7 +27,7 @@ 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
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
 
 
 @pytest.fixture(scope='session')
diff --git a/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py b/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py
index 40a954868620564aef7d60c5ec0023ea0a32337b..45296d107bcdb14472f05c677ba0c75113fd94cc 100644
--- a/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py
+++ b/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py
@@ -27,7 +27,7 @@ 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
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
 
 
 @pytest.fixture(scope='session')
diff --git a/src/tests/ofc22/deploy_specs.sh b/src/tests/ofc22/deploy_specs.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b486474e2afad7305409bf410c7b8885b0afe2a8
--- /dev/null
+++ b/src/tests/ofc22/deploy_specs.sh
@@ -0,0 +1,17 @@
+# Set the URL of your local Docker registry where the images will be uploaded to.
+export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
+
+# Set the list of components, separated by spaces, you want to build images for, and deploy.
+export TFS_COMPONENTS="context device automation service compute monitoring webui"
+
+# Set the tag you want to use for your images.
+export TFS_IMAGE_TAG="dev"
+
+# Set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE="tfs"
+
+# Set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
+
+# Set the neew Grafana admin password
+export TFS_GRAFANA_PASSWORD="admin123+"
diff --git a/src/tests/ofc22/descriptors_emulated.json b/src/tests/ofc22/descriptors_emulated.json
index eb22506238e03a161f0e2b8aaeadf5fd31cf547b..83f9c39e2ac7154b088ccdd0a1519ea32c1aee1d 100644
--- a/src/tests/ofc22/descriptors_emulated.json
+++ b/src/tests/ofc22/descriptors_emulated.json
@@ -64,7 +64,7 @@
         },
         {
             "device_id": {"device_uuid": {"uuid": "O1-OLS"}},
-            "device_type": "emu-optical-line-system",
+            "device_type": "emu-open-line-system",
             "device_config": {"config_rules": [
                 {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
                 {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
@@ -105,4 +105,4 @@
             ]
         }
     ]
-}
+}
\ No newline at end of file
diff --git a/src/tests/ofc22/run_test_01_bootstrap.sh b/src/tests/ofc22/run_test_01_bootstrap.sh
index be30b15189786de3fd2f593a1584c73890e9e4fe..bb740707321b24fc960299f2eac91cc2d9775b64 100755
--- a/src/tests/ofc22/run_test_01_bootstrap.sh
+++ b/src/tests/ofc22/run_test_01_bootstrap.sh
@@ -13,4 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# make sure to source the following scripts:
+# - my_deploy.sh
+# - tfs_runtime_env_vars.sh
+
+source tfs_runtime_env_vars.sh
 pytest --verbose src/tests/ofc22/tests/test_functional_bootstrap.py
diff --git a/src/tests/ofc22/run_test_02_create_service.sh b/src/tests/ofc22/run_test_02_create_service.sh
index 20fc3db65dd57ae8697253443050b1767d9b77a1..8b6c8658df759bdcb777f83c6c7846d0ea7b48ed 100755
--- a/src/tests/ofc22/run_test_02_create_service.sh
+++ b/src/tests/ofc22/run_test_02_create_service.sh
@@ -13,4 +13,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+source tfs_runtime_env_vars.sh
 pytest --verbose src/tests/ofc22/tests/test_functional_create_service.py
diff --git a/src/tests/ofc22/run_test_03_delete_service.sh b/src/tests/ofc22/run_test_03_delete_service.sh
index 98073013d84e9d64e56dd9022ac163b6321ce389..51df41aee216e141b0d2e2f55a0398ecd9cdf35f 100755
--- a/src/tests/ofc22/run_test_03_delete_service.sh
+++ b/src/tests/ofc22/run_test_03_delete_service.sh
@@ -13,4 +13,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+source tfs_runtime_env_vars.sh
 pytest --verbose src/tests/ofc22/tests/test_functional_delete_service.py
diff --git a/src/tests/ofc22/run_test_04_cleanup.sh b/src/tests/ofc22/run_test_04_cleanup.sh
index f7c0aad8da0b0446d188ec1fad3f0fc0e7dc2b4a..2ba91684f9eb49075dd68877e54976f989811ae9 100755
--- a/src/tests/ofc22/run_test_04_cleanup.sh
+++ b/src/tests/ofc22/run_test_04_cleanup.sh
@@ -13,4 +13,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+source tfs_runtime_env_vars.sh
 pytest --verbose src/tests/ofc22/tests/test_functional_cleanup.py
diff --git a/src/tests/ofc22/run_tests_and_coverage.sh b/src/tests/ofc22/run_tests_and_coverage.sh
index fa5026db2310c8753d8e4476707ce46a38ecb0f2..bafc920c71a640d083497e1cd6ae025d0ea7cef5 100755
--- a/src/tests/ofc22/run_tests_and_coverage.sh
+++ b/src/tests/ofc22/run_tests_and_coverage.sh
@@ -29,6 +29,8 @@ rm -f $COVERAGEFILE
 # Force a flush of Context database
 kubectl --namespace $TFS_K8S_NAMESPACE exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL
 
+source tfs_runtime_env_vars.sh
+
 # Run functional tests and analyze code coverage at the same time
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
     tests/ofc22/tests/test_functional_bootstrap.py
diff --git a/src/tests/ofc22/tests/LoadDescriptors.py b/src/tests/ofc22/tests/LoadDescriptors.py
index 4d3af78f5c9a3fd9b09d94f24bb8aaec48af6b7a..33bc699af933601e4c6d4b8dbc7b0c51206241ef 100644
--- a/src/tests/ofc22/tests/LoadDescriptors.py
+++ b/src/tests/ofc22/tests/LoadDescriptors.py
@@ -15,7 +15,7 @@
 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 common.proto.context_pb2 import Context, Device, Link, Topology
 from device.client.DeviceClient import DeviceClient
 
 LOGGER = logging.getLogger(__name__)
diff --git a/src/tests/ofc22/tests/Objects.py b/src/tests/ofc22/tests/Objects.py
index bda08d7761ab3ad794246e6f94932c147a787993..d2fb32ebb20b7bcdda9ac12b7a7390c46e6fb1d1 100644
--- a/src/tests/ofc22/tests/Objects.py
+++ b/src/tests/ofc22/tests/Objects.py
@@ -21,7 +21,7 @@ from common.tools.object_factory.Device import (
 from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_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 context.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.proto.kpi_sample_types_pb2 import KpiSampleType
 
 # ----- Context --------------------------------------------------------------------------------------------------------
 CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
@@ -228,4 +228,4 @@ DEVICES = [
     (DEVICE_O1, DEVICE_O1_CONNECT_RULES),
 ]
 
-LINKS = [LINK_R1_O1, LINK_R2_O1, LINK_R3_O1, LINK_R4_O1]
+LINKS = [LINK_R1_O1, LINK_R2_O1, LINK_R3_O1, LINK_R4_O1]
\ No newline at end of file
diff --git a/src/tests/ofc22/tests/ObjectsXr.py b/src/tests/ofc22/tests/ObjectsXr.py
index e1ca0450b59eda995d4b1959caf73d58cbacfb4c..0cb223de2ede509443275496ba9ca57158335036 100644
--- a/src/tests/ofc22/tests/ObjectsXr.py
+++ b/src/tests/ofc22/tests/ObjectsXr.py
@@ -21,7 +21,7 @@ from common.tools.object_factory.Device import (
 from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_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 context.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.proto.kpi_sample_types_pb2 import KpiSampleType
 
 # ----- Context --------------------------------------------------------------------------------------------------------
 CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
diff --git a/src/tests/ofc22/tests/test_functional_bootstrap.py b/src/tests/ofc22/tests/test_functional_bootstrap.py
index 334d7894babedfed2ffb30e4682a1d56e4261cb9..3ea9393c5e7f575b24a7fd0ec2f5de929900d066 100644
--- a/src/tests/ofc22/tests/test_functional_bootstrap.py
+++ b/src/tests/ofc22/tests/test_functional_bootstrap.py
@@ -21,7 +21,7 @@ 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 Context, ContextId, Device, Empty, Link, Topology
+from common.proto.context_pb2 import Context, ContextId, Device, Empty, Link, Topology
 from device.client.DeviceClient import DeviceClient
 from .Objects import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
 
@@ -59,10 +59,10 @@ def test_scenario_empty(context_client : ContextClient):  # pylint: disable=rede
 def test_prepare_scenario(context_client : ContextClient):  # pylint: disable=redefined-outer-name
 
     # ----- Start the EventsCollector ----------------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
-    events_collector.start()
+    #events_collector = EventsCollector(context_client)
+    #events_collector.start()
 
-    expected_events = []
+    #expected_events = []
 
     # ----- Create Contexts and Topologies -----------------------------------------------------------------------------
     for context in CONTEXTS:
@@ -70,7 +70,7 @@ def test_prepare_scenario(context_client : ContextClient):  # pylint: disable=re
         LOGGER.info('Adding Context {:s}'.format(context_uuid))
         response = context_client.SetContext(Context(**context))
         assert response.context_uuid.uuid == context_uuid
-        expected_events.append(('ContextEvent', EVENT_CREATE, json_context_id(context_uuid)))
+        #expected_events.append(('ContextEvent', EVENT_CREATE, json_context_id(context_uuid)))
 
     for topology in TOPOLOGIES:
         context_uuid = topology['topology_id']['context_id']['context_uuid']['uuid']
@@ -80,13 +80,13 @@ def test_prepare_scenario(context_client : ContextClient):  # pylint: disable=re
         assert response.context_id.context_uuid.uuid == context_uuid
         assert response.topology_uuid.uuid == topology_uuid
         context_id = json_context_id(context_uuid)
-        expected_events.append(('TopologyEvent', EVENT_CREATE, json_topology_id(topology_uuid, context_id=context_id)))
+        #expected_events.append(('TopologyEvent', EVENT_CREATE, json_topology_id(topology_uuid, context_id=context_id)))
 
     # ----- Validate Collected Events ----------------------------------------------------------------------------------
-    check_events(events_collector, expected_events)
+    #check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    #events_collector.stop()
 
 
 def test_scenario_ready(context_client : ContextClient):  # pylint: disable=redefined-outer-name
@@ -111,10 +111,10 @@ def test_devices_bootstraping(
     context_client : ContextClient, device_client : DeviceClient):  # pylint: disable=redefined-outer-name
 
     # ----- Start the EventsCollector ----------------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client, log_events_received=True)
-    events_collector.start()
+    #events_collector = EventsCollector(context_client, log_events_received=True)
+    #events_collector.start()
 
-    expected_events = []
+    #expected_events = []
 
     # ----- Create Devices and Validate Collected Events ---------------------------------------------------------------
     for device, connect_rules in DEVICES:
@@ -126,11 +126,11 @@ def test_devices_bootstraping(
         response = device_client.AddDevice(Device(**device_with_connect_rules))
         assert response.device_uuid.uuid == device_uuid
 
-        expected_events.extend([
-            # Device creation, update for automation to start the device
-            ('DeviceEvent', EVENT_CREATE, json_device_id(device_uuid)),
-            #('DeviceEvent', EVENT_UPDATE, json_device_id(device_uuid)),
-        ])
+        #expected_events.extend([
+        #    # Device creation, update for automation to start the device
+        #    ('DeviceEvent', EVENT_CREATE, json_device_id(device_uuid)),
+        #    #('DeviceEvent', EVENT_UPDATE, json_device_id(device_uuid)),
+        #])
 
         #response = context_client.GetDevice(response)
         #for endpoint in response.device_endpoints:
@@ -139,10 +139,10 @@ def test_devices_bootstraping(
         #        expected_events.append(('DeviceEvent', EVENT_UPDATE, json_device_id(device_uuid)))
 
     # ----- Validate Collected Events ----------------------------------------------------------------------------------
-    check_events(events_collector, expected_events)
+    #check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    #events_collector.stop()
 
 
 def test_devices_bootstrapped(context_client : ContextClient):  # pylint: disable=redefined-outer-name
@@ -166,10 +166,10 @@ def test_devices_bootstrapped(context_client : ContextClient):  # pylint: disabl
 def test_links_creation(context_client : ContextClient):  # pylint: disable=redefined-outer-name
 
     # ----- Start the EventsCollector ----------------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
-    events_collector.start()
+    #events_collector = EventsCollector(context_client)
+    #events_collector.start()
 
-    expected_events = []
+    #expected_events = []
 
     # ----- Create Links and Validate Collected Events -----------------------------------------------------------------
     for link in LINKS:
@@ -177,13 +177,13 @@ def test_links_creation(context_client : ContextClient):  # pylint: disable=rede
         LOGGER.info('Adding Link {:s}'.format(link_uuid))
         response = context_client.SetLink(Link(**link))
         assert response.link_uuid.uuid == link_uuid
-        expected_events.append(('LinkEvent', EVENT_CREATE, json_link_id(link_uuid)))
+        #expected_events.append(('LinkEvent', EVENT_CREATE, json_link_id(link_uuid)))
 
     # ----- Validate Collected Events ----------------------------------------------------------------------------------
-    check_events(events_collector, expected_events)
+    #check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    #events_collector.stop()
 
 
 def test_links_created(context_client : ContextClient):  # pylint: disable=redefined-outer-name
diff --git a/src/tests/ofc22/tests/test_functional_cleanup.py b/src/tests/ofc22/tests/test_functional_cleanup.py
index eb78a585079e3ee757a836433bf23423a3ad899d..60bb86b50853680e0699906dcb28ebd2e8777bb4 100644
--- a/src/tests/ofc22/tests/test_functional_cleanup.py
+++ b/src/tests/ofc22/tests/test_functional_cleanup.py
@@ -21,7 +21,7 @@ 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 common.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId
 from device.client.DeviceClient import DeviceClient
 from .Objects import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
 
@@ -65,10 +65,10 @@ 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()
+    #events_collector = EventsCollector(context_client)
+    #events_collector.start()
 
-    expected_events = []
+    #expected_events = []
 
     # ----- Delete Links and Validate Collected Events -----------------------------------------------------------------
     for link in LINKS:
@@ -76,7 +76,7 @@ def test_scenario_cleanup(
         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)))
+        #expected_events.append(('LinkEvent', EVENT_REMOVE, json_link_id(link_uuid)))
 
     # ----- Delete Devices and Validate Collected Events ---------------------------------------------------------------
     for device, _ in DEVICES:
@@ -84,7 +84,7 @@ def test_scenario_cleanup(
         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)))
+        #expected_events.append(('DeviceEvent', EVENT_REMOVE, json_device_id(device_uuid)))
 
     # ----- Delete Topologies and Validate Collected Events ------------------------------------------------------------
     for topology in TOPOLOGIES:
@@ -94,7 +94,7 @@ def test_scenario_cleanup(
         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)))
+        #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:
@@ -102,13 +102,13 @@ def test_scenario_cleanup(
         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)))
+        #expected_events.append(('ContextEvent', EVENT_REMOVE, json_context_id(context_uuid)))
 
     # ----- Validate Collected Events ----------------------------------------------------------------------------------
-    check_events(events_collector, expected_events)
+    #check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    #events_collector.stop()
 
 
 def test_scenario_empty_again(context_client : ContextClient):  # pylint: disable=redefined-outer-name
diff --git a/src/tests/ofc22/tests/test_functional_create_service.py b/src/tests/ofc22/tests/test_functional_create_service.py
index f3389fdbfce4e9262ffddbad876bb86f9b300551..1f5b80cbf250a7b58321fcae693acf078b6b0a67 100644
--- a/src/tests/ofc22/tests/test_functional_create_service.py
+++ b/src/tests/ofc22/tests/test_functional_create_service.py
@@ -23,7 +23,7 @@ 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.client.EventsCollector import EventsCollector
-from context.proto.context_pb2 import ContextId, Empty
+from common.proto.context_pb2 import ContextId, Empty
 from .Objects import (
     CONTEXT_ID, CONTEXTS, DEVICE_O1_UUID, DEVICE_R1_UUID, DEVICE_R3_UUID, DEVICES, LINKS, TOPOLOGIES,
     WIM_MAPPING, WIM_PASSWORD, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE, WIM_USERNAME)
@@ -32,7 +32,7 @@ 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
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
 
 
 @pytest.fixture(scope='session')
@@ -69,8 +69,8 @@ def test_scenario_is_correct(context_client : ContextClient):  # pylint: disable
 
 def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
     # ----- Start the EventsCollector ----------------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client, log_events_received=True)
-    events_collector.start()
+    #events_collector = EventsCollector(context_client, log_events_received=True)
+    #events_collector.start()
 
     # ----- Create Service ---------------------------------------------------------------------------------------------
     service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
@@ -78,30 +78,30 @@ def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): #
 
     # ----- Validate collected events ----------------------------------------------------------------------------------
 
-    packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
-    optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_EMU_OLS)
-    optical_service_uuid = '{:s}:optical'.format(service_uuid)
-
-    expected_events = [
-        # Create packet service and add first endpoint
-        ('ServiceEvent',    EVENT_CREATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-        ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-
-        # Configure OLS controller, create optical service, create optical connection
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_O1_UUID)),
-        ('ServiceEvent',    EVENT_CREATE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
-        ('ConnectionEvent', EVENT_CREATE, json_connection_id(optical_connection_uuid)),
-
-        # Configure endpoint packet devices, add second endpoint to service, create connection
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
-        ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-        ('ConnectionEvent', EVENT_CREATE, json_connection_id(packet_connection_uuid)),
-    ]
-    check_events(events_collector, expected_events)
+    #packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
+    #optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_EMU_OLS)
+    #optical_service_uuid = '{:s}:optical'.format(service_uuid)
+
+    #expected_events = [
+    #    # Create packet service and add first endpoint
+    #    ('ServiceEvent',    EVENT_CREATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #    ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #
+    #    # Configure OLS controller, create optical service, create optical connection
+    #    ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_O1_UUID)),
+    #    ('ServiceEvent',    EVENT_CREATE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
+    #    ('ConnectionEvent', EVENT_CREATE, json_connection_id(optical_connection_uuid)),
+    #
+    #    # Configure endpoint packet devices, add second endpoint to service, create connection
+    #    ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
+    #    ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
+    #    ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #    ('ConnectionEvent', EVENT_CREATE, json_connection_id(packet_connection_uuid)),
+    #]
+    #check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    #events_collector.stop()
 
 
 def test_scenario_service_created(context_client : ContextClient):  # pylint: disable=redefined-outer-name
diff --git a/src/tests/ofc22/tests/test_functional_create_service_xr.py b/src/tests/ofc22/tests/test_functional_create_service_xr.py
index 7913aa9d73c5af0103b0490bfe89ff20eeb6fc35..bb78abc1efe7701308448ad4b83ef2a6e32079c4 100644
--- a/src/tests/ofc22/tests/test_functional_create_service_xr.py
+++ b/src/tests/ofc22/tests/test_functional_create_service_xr.py
@@ -23,7 +23,7 @@ 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.client.EventsCollector import EventsCollector
-from context.proto.context_pb2 import ContextId, Empty
+from common.proto.context_pb2 import ContextId, Empty
 from .ObjectsXr import (
     CONTEXT_ID, CONTEXTS, DEVICE_X1_UUID, DEVICE_R1_UUID, DEVICE_R3_UUID, DEVICES, LINKS, TOPOLOGIES,
     WIM_MAPPING, WIM_PASSWORD, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE, WIM_USERNAME)
@@ -69,8 +69,8 @@ def test_scenario_is_correct(context_client : ContextClient):  # pylint: disable
 
 def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
     # ----- Start the EventsCollector ----------------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client, log_events_received=True)
-    events_collector.start()
+    # events_collector = EventsCollector(context_client, log_events_received=True)
+    # events_collector.start()
 
     # ----- Create Service ---------------------------------------------------------------------------------------------
     service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
@@ -78,30 +78,30 @@ def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): #
 
     # ----- Validate collected events ----------------------------------------------------------------------------------
 
-    packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
-    optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_XR_CONSTELLATION)
-    optical_service_uuid = '{:s}:optical'.format(service_uuid)
+    # packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
+    # optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_XR_CONSTELLATION)
+    # optical_service_uuid = '{:s}:optical'.format(service_uuid)
 
-    expected_events = [
-        # Create packet service and add first endpoint
-        ('ServiceEvent',    EVENT_CREATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-        ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    # expected_events = [
+    #     # Create packet service and add first endpoint
+    #     ('ServiceEvent',    EVENT_CREATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #     ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
 
-        # Configure OLS controller, create optical service, create optical connection
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_X1_UUID)),
-        ('ServiceEvent',    EVENT_CREATE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
-        ('ConnectionEvent', EVENT_CREATE, json_connection_id(optical_connection_uuid)),
+    #     # Configure OLS controller, create optical service, create optical connection
+    #     ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_X1_UUID)),
+    #     ('ServiceEvent',    EVENT_CREATE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
+    #     ('ConnectionEvent', EVENT_CREATE, json_connection_id(optical_connection_uuid)),
 
-        # Configure endpoint packet devices, add second endpoint to service, create connection
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
-        ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-        ('ConnectionEvent', EVENT_CREATE, json_connection_id(packet_connection_uuid)),
-    ]
-    check_events(events_collector, expected_events)
+    #     # Configure endpoint packet devices, add second endpoint to service, create connection
+    #     ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
+    #     ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
+    #     ('ServiceEvent',    EVENT_UPDATE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #     ('ConnectionEvent', EVENT_CREATE, json_connection_id(packet_connection_uuid)),
+    # ]
+    # check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    # events_collector.stop()
 
 
 def test_scenario_service_created(context_client : ContextClient):  # pylint: disable=redefined-outer-name
diff --git a/src/tests/ofc22/tests/test_functional_delete_service.py b/src/tests/ofc22/tests/test_functional_delete_service.py
index 51e91a5967e1696fa2fdfe7dd06d2efb46642248..f0cc916cf9da794ec32550a609e4f45962370cfc 100644
--- a/src/tests/ofc22/tests/test_functional_delete_service.py
+++ b/src/tests/ofc22/tests/test_functional_delete_service.py
@@ -23,7 +23,7 @@ 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.client.EventsCollector import EventsCollector
-from context.proto.context_pb2 import ContextId, Empty
+from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum
 from .Objects import (
     CONTEXT_ID, CONTEXTS, DEVICE_O1_UUID, DEVICE_R1_UUID, DEVICE_R3_UUID, DEVICES, LINKS, TOPOLOGIES, WIM_MAPPING,
     WIM_PASSWORD, WIM_USERNAME)
@@ -33,7 +33,7 @@ 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
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
 
 
 @pytest.fixture(scope='session')
@@ -77,43 +77,43 @@ def test_scenario_is_correct(context_client : ContextClient):  # pylint: disable
 
 def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
     # ----- Start the EventsCollector ----------------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client, log_events_received=True)
-    events_collector.start()
+    #events_collector = EventsCollector(context_client, log_events_received=True)
+    #events_collector.start()
 
     # ----- Delete Service ---------------------------------------------------------------------------------------------
-    response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
-    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.service_ids), grpc_message_to_json_string(response)))
-    assert len(response.service_ids) == 2 # L3NM + TAPI
+    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) == 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
+    for service in response.services:
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_L3NM: continue
+        service_uuid = service.service_id.service_uuid.uuid
         service_uuids.add(service_uuid)
         osm_wim.conn_info[service_uuid] = {}
 
-    assert len(service_uuids) == 1  # assume a single service has been created
+    assert len(service_uuids) == 1  # assume a single L3NM service has been created
     service_uuid = set(service_uuids).pop()
 
     osm_wim.delete_connectivity_service(service_uuid)
 
     # ----- Validate collected events ----------------------------------------------------------------------------------
-    packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
-    optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_EMU_OLS)
-    optical_service_uuid = '{:s}:optical'.format(service_uuid)
-
-    expected_events = [
-        ('ConnectionEvent', EVENT_REMOVE, json_connection_id(packet_connection_uuid)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
-        ('ServiceEvent',    EVENT_REMOVE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-        ('ConnectionEvent', EVENT_REMOVE, json_connection_id(optical_connection_uuid)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_O1_UUID)),
-        ('ServiceEvent',    EVENT_REMOVE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
-    ]
-    check_events(events_collector, expected_events)
+    #packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
+    #optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_EMU_OLS)
+    #optical_service_uuid = '{:s}:optical'.format(service_uuid)
+
+    #expected_events = [
+    #    ('ConnectionEvent', EVENT_REMOVE, json_connection_id(packet_connection_uuid)),
+    #    ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
+    #    ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
+    #    ('ServiceEvent',    EVENT_REMOVE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #    ('ConnectionEvent', EVENT_REMOVE, json_connection_id(optical_connection_uuid)),
+    #    ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_O1_UUID)),
+    #    ('ServiceEvent',    EVENT_REMOVE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
+    #]
+    #check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    #events_collector.stop()
 
 
 def test_services_removed(context_client : ContextClient):  # pylint: disable=redefined-outer-name
diff --git a/src/tests/ofc22/tests/test_functional_delete_service_xr.py b/src/tests/ofc22/tests/test_functional_delete_service_xr.py
index efef7484a9a9691e3d17d7073c298ab05e953bd9..f28828be056e755058a0f6b15bd8ea3e9acbbdeb 100644
--- a/src/tests/ofc22/tests/test_functional_delete_service_xr.py
+++ b/src/tests/ofc22/tests/test_functional_delete_service_xr.py
@@ -23,7 +23,7 @@ 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.client.EventsCollector import EventsCollector
-from context.proto.context_pb2 import ContextId, Empty
+from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum
 from .ObjectsXr import (
     CONTEXT_ID, CONTEXTS, DEVICE_X1_UUID, DEVICE_R1_UUID, DEVICE_R3_UUID, DEVICES, LINKS, TOPOLOGIES, WIM_MAPPING,
     WIM_PASSWORD, WIM_USERNAME)
@@ -80,13 +80,13 @@ def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # p
     events_collector.start()
 
     # ----- Delete Service ---------------------------------------------------------------------------------------------
-    response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
-    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.service_ids), grpc_message_to_json_string(response)))
-    assert len(response.service_ids) == 2 # L3NM + TAPI
+    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) == 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
+    for service in response.services:
+        if service.service_type != ServiceTypeEnum.SERVICETYPE_L3NM: continue
+        service_uuid = service.service_id.service_uuid.uuid
         service_uuids.add(service_uuid)
         osm_wim.conn_info[service_uuid] = {}
 
@@ -96,23 +96,23 @@ def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # p
     osm_wim.delete_connectivity_service(service_uuid)
 
     # ----- Validate collected events ----------------------------------------------------------------------------------
-    packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
-    optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_XR_CONSTELLATION)
-    optical_service_uuid = '{:s}:optical'.format(service_uuid)
-
-    expected_events = [
-        ('ConnectionEvent', EVENT_REMOVE, json_connection_id(packet_connection_uuid)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
-        ('ServiceEvent',    EVENT_REMOVE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
-        ('ConnectionEvent', EVENT_REMOVE, json_connection_id(optical_connection_uuid)),
-        ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_X1_UUID)),
-        ('ServiceEvent',    EVENT_REMOVE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
-    ]
-    check_events(events_collector, expected_events)
+    # packet_connection_uuid = '{:s}:{:s}'.format(service_uuid, DEVTYPE_EMU_PR)
+    # optical_connection_uuid = '{:s}:optical:{:s}'.format(service_uuid, DEVTYPE_XR_CONSTELLATION)
+    # optical_service_uuid = '{:s}:optical'.format(service_uuid)
+
+    # expected_events = [
+    #     ('ConnectionEvent', EVENT_REMOVE, json_connection_id(packet_connection_uuid)),
+    #     ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R1_UUID)),
+    #     ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_R3_UUID)),
+    #     ('ServiceEvent',    EVENT_REMOVE, json_service_id(service_uuid, context_id=CONTEXT_ID)),
+    #     ('ConnectionEvent', EVENT_REMOVE, json_connection_id(optical_connection_uuid)),
+    #     ('DeviceEvent',     EVENT_UPDATE, json_device_id(DEVICE_X1_UUID)),
+    #     ('ServiceEvent',    EVENT_REMOVE, json_service_id(optical_service_uuid, context_id=CONTEXT_ID)),
+    # ]
+    # check_events(events_collector, expected_events)
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
-    events_collector.stop()
+    # events_collector.stop()
 
 
 def test_services_removed(context_client : ContextClient):  # pylint: disable=redefined-outer-name
diff --git a/src/webui/Dockerfile b/src/webui/Dockerfile
index 7760416be32b893ed5f2408b70e874fb89721e17..a17d2bd9aea9c6948262dcf17776f75c0be351b8 100644
--- a/src/webui/Dockerfile
+++ b/src/webui/Dockerfile
@@ -79,6 +79,8 @@ COPY --chown=webui:webui src/device/__init__.py device/__init__.py
 COPY --chown=webui:webui src/device/client/. device/client/
 COPY --chown=webui:webui src/service/__init__.py service/__init__.py
 COPY --chown=webui:webui src/service/client/. service/client/
+COPY --chown=webui:webui src/slice/__init__.py slice/__init__.py
+COPY --chown=webui:webui src/slice/client/. slice/client/
 COPY --chown=webui:webui src/webui/. webui/
 
 # Start the service
diff --git a/src/webui/grafana_backup_dashboard.json b/src/webui/grafana_backup_dashboard.json
new file mode 100644
index 0000000000000000000000000000000000000000..58a856a6c50de422b1f6bde1e2799d53762db916
--- /dev/null
+++ b/src/webui/grafana_backup_dashboard.json
@@ -0,0 +1,320 @@
+{
+    "annotations": {
+      "list": [
+        {
+          "builtIn": 1,
+          "datasource": "-- Grafana --",
+          "enable": true,
+          "hide": true,
+          "iconColor": "rgba(0, 211, 255, 1)",
+          "name": "Annotations & Alerts",
+          "target": {
+            "limit": 100,
+            "matchAny": false,
+            "tags": [],
+            "type": "dashboard"
+          },
+          "type": "dashboard"
+        }
+      ]
+    },
+    "editable": true,
+    "fiscalYearStartMonth": 0,
+    "gnetId": null,
+    "graphTooltip": 0,
+    "id": 1,
+    "iteration": 1664282779131,
+    "links": [],
+    "liveNow": false,
+    "panels": [
+      {
+        "datasource": null,
+        "fieldConfig": {
+          "defaults": {
+            "color": {
+              "mode": "palette-classic"
+            },
+            "custom": {
+              "axisLabel": "",
+              "axisPlacement": "auto",
+              "barAlignment": 0,
+              "drawStyle": "line",
+              "fillOpacity": 0,
+              "gradientMode": "none",
+              "hideFrom": {
+                "legend": false,
+                "tooltip": false,
+                "viz": false
+              },
+              "lineInterpolation": "smooth",
+              "lineWidth": 1,
+              "pointSize": 5,
+              "scaleDistribution": {
+                "type": "linear"
+              },
+              "showPoints": "never",
+              "spanNulls": false,
+              "stacking": {
+                "group": "A",
+                "mode": "none"
+              },
+              "thresholdsStyle": {
+                "mode": "off"
+              }
+            },
+            "mappings": [],
+            "thresholds": {
+              "mode": "absolute",
+              "steps": [
+                {
+                  "color": "green",
+                  "value": null
+                },
+                {
+                  "color": "red",
+                  "value": 80
+                }
+              ]
+            }
+          },
+          "overrides": [
+            {
+              "matcher": {
+                "id": "byRegexp",
+                "options": ".* PACKETS_.*"
+              },
+              "properties": [
+                {
+                  "id": "custom.axisPlacement",
+                  "value": "left"
+                },
+                {
+                  "id": "unit",
+                  "value": "pps"
+                },
+                {
+                  "id": "custom.axisLabel",
+                  "value": "Packets / sec"
+                },
+                {
+                  "id": "custom.axisSoftMin",
+                  "value": 0
+                }
+              ]
+            },
+            {
+              "matcher": {
+                "id": "byRegexp",
+                "options": ".* BYTES_.*"
+              },
+              "properties": [
+                {
+                  "id": "custom.axisPlacement",
+                  "value": "right"
+                },
+                {
+                  "id": "unit",
+                  "value": "Bps"
+                },
+                {
+                  "id": "custom.axisLabel",
+                  "value": "Bytes / sec"
+                },
+                {
+                  "id": "custom.axisSoftMin",
+                  "value": 0
+                }
+              ]
+            }
+          ]
+        },
+        "gridPos": {
+          "h": 19,
+          "w": 24,
+          "x": 0,
+          "y": 0
+        },
+        "id": 2,
+        "options": {
+          "legend": {
+            "calcs": [
+              "first",
+              "min",
+              "mean",
+              "max",
+              "lastNotNull"
+            ],
+            "displayMode": "table",
+            "placement": "right"
+          },
+          "tooltip": {
+            "mode": "multi"
+          }
+        },
+        "targets": [
+          {
+            "format": "time_series",
+            "group": [],
+            "hide": false,
+            "metricColumn": "kpi_value",
+            "rawQuery": false,
+            "rawSql": "SELECT\n  timestamp AS \"time\",\n  kpi_value AS metric,\n  kpi_value AS \"kpi_value\"\nFROM monitoring\nWHERE\n  $__timeFilter(timestamp) AND\n  device_id = $device_id AND\n  endpoint_id = $endpoint_id\nORDER BY 1,2",
+            "refId": "A",
+            "select": [
+              [
+                {
+                  "params": [
+                    "kpi_value"
+                  ],
+                  "type": "column"
+                },
+                {
+                  "params": [
+                    "avg"
+                  ],
+                  "type": "aggregate"
+                },
+                {
+                  "params": [
+                    "kpi_value"
+                  ],
+                  "type": "alias"
+                }
+              ]
+            ],
+            "table": "monitoring",
+            "timeColumn": "timestamp",
+            "where": [
+              {
+                "name": "$__timeFilter",
+                "params": [],
+                "type": "macro"
+              },
+              {
+                "name": "",
+                "params": [
+                  "device_id",
+                  "=",
+                  "$device_id"
+                ],
+                "type": "expression"
+              },
+              {
+                "name": "",
+                "params": [
+                  "endpoint_id",
+                  "=",
+                  "$endpoint_id"
+                ],
+                "type": "expression"
+              }
+            ]
+          }
+        ],
+        "title": "L3 Monitoring Packets/Bytes Received/Sent",
+        "transformations": [],
+        "type": "timeseries"
+      }
+    ],
+    "refresh": "",
+    "schemaVersion": 32,
+    "style": "dark",
+    "tags": [],
+    "templating": {
+      "list": [
+        {
+          "allValue": null,
+          "current": {
+            "selected": true,
+            "text": [
+              "R1-EMU"
+            ],
+            "value": [
+              "R1-EMU"
+            ]
+          },
+          "datasource": null,
+          "definition": "SELECT DISTINCT device_id FROM monitoring;",
+          "description": null,
+          "error": null,
+          "hide": 0,
+          "includeAll": true,
+          "label": "Device",
+          "multi": true,
+          "name": "device_id",
+          "options": [],
+          "query": "SELECT DISTINCT device_id FROM monitoring;",
+          "refresh": 2,
+          "regex": "",
+          "skipUrlSync": false,
+          "sort": 0,
+          "type": "query"
+        },
+        {
+          "allValue": null,
+          "current": {
+            "selected": true,
+            "text": [
+              "13/1/2"
+            ],
+            "value": [
+              "13/1/2"
+            ]
+          },
+          "datasource": null,
+          "definition": "SELECT DISTINCT endpoint_id FROM monitoring WHERE device_id IN (${device_id})",
+          "description": null,
+          "error": null,
+          "hide": 0,
+          "includeAll": true,
+          "label": "EndPoint",
+          "multi": true,
+          "name": "endpoint_id",
+          "options": [],
+          "query": "SELECT DISTINCT endpoint_id FROM monitoring WHERE device_id IN (${device_id})",
+          "refresh": 2,
+          "regex": "",
+          "skipUrlSync": false,
+          "sort": 0,
+          "type": "query"
+        },
+        {
+          "allValue": null,
+          "current": {
+            "selected": true,
+            "text": [
+              "All"
+            ],
+            "value": [
+              "$__all"
+            ]
+          },
+          "datasource": null,
+          "definition": "SELECT DISTINCT kpi_sample_type FROM monitoring;",
+          "description": null,
+          "error": null,
+          "hide": 0,
+          "includeAll": true,
+          "label": "Kpi Sample Type",
+          "multi": true,
+          "name": "kpi_sample_type",
+          "options": [],
+          "query": "SELECT DISTINCT kpi_sample_type FROM monitoring;",
+          "refresh": 2,
+          "regex": "",
+          "skipUrlSync": false,
+          "sort": 0,
+          "type": "query"
+        }
+      ]
+    },
+    "time": {
+      "from": "now-5m",
+      "to": "now"
+    },
+    "timepicker": {},
+    "timezone": "",
+    "title": "L3 Monitoring",
+    "uid": "tf-l3-monit",
+    "version": 3
+  }
\ No newline at end of file
diff --git a/src/webui/grafana_dashboard.json b/src/webui/grafana_dashboard.json
index a845ac20c7861b86fd1931452b7802b3f1e57aa8..49148825a973aecca5901ffac2249fed6057f4d0 100644
--- a/src/webui/grafana_dashboard.json
+++ b/src/webui/grafana_dashboard.json
@@ -193,19 +193,19 @@
             "tags": [
               {
                 "key": "device_id",
-                "operator": "=~",
+                "operator": "=",
                 "value": "/^$device_id$/"
               },
               {
                 "condition": "AND",
                 "key": "endpoint_id",
-                "operator": "=~",
+                "operator": "=",
                 "value": "/^$endpoint_id$/"
               },
               {
                 "condition": "AND",
                 "key": "kpi_sample_type",
-                "operator": "=~",
+                "operator": "=",
                 "value": "/^$kpi_sample_type$/"
               }
             ]
@@ -236,7 +236,7 @@
             ]
           },
           "datasource": null,
-          "definition": "SHOW TAG VALUES FROM samples WITH KEY=\"device_id\"",
+          "definition": "SELECT DISTINCT device_id FROM monitoring;",
           "description": null,
           "error": null,
           "hide": 0,
@@ -245,7 +245,7 @@
           "multi": true,
           "name": "device_id",
           "options": [],
-          "query": "SHOW TAG VALUES FROM samples WITH KEY=\"device_id\"",
+          "query": "SELECT DISTINCT device_id FROM monitoring;",
           "refresh": 2,
           "regex": "",
           "skipUrlSync": false,
@@ -264,7 +264,7 @@
             ]
           },
           "datasource": null,
-          "definition": "SHOW TAG VALUES FROM samples WITH KEY=\"endpoint_id\" WHERE \"device_id\"=~/^$device_id$/",
+          "definition": "SELECT DISTINCT endpoint_id FROM monitoring WHERE device_id IN (${device_id})",
           "description": null,
           "error": null,
           "hide": 0,
@@ -273,7 +273,7 @@
           "multi": true,
           "name": "endpoint_id",
           "options": [],
-          "query": "SHOW TAG VALUES FROM samples WITH KEY=\"endpoint_id\" WHERE \"device_id\"=~/^$device_id$/",
+          "query": "SELECT DISTINCT endpoint_id FROM monitoring WHERE device_id IN (${device_id})",
           "refresh": 2,
           "regex": "",
           "skipUrlSync": false,
@@ -292,7 +292,7 @@
             ]
           },
           "datasource": null,
-          "definition": "SHOW TAG VALUES FROM samples WITH KEY=\"kpi_sample_type\"",
+          "definition": "SELECT DISTINCT kpi_sample_type FROM monitoring;",
           "description": null,
           "error": null,
           "hide": 0,
@@ -301,7 +301,7 @@
           "multi": true,
           "name": "kpi_sample_type",
           "options": [],
-          "query": "SHOW TAG VALUES FROM samples WITH KEY=\"kpi_sample_type\"",
+          "query": "SELECT DISTINCT kpi_sample_type FROM monitoring;",
           "refresh": 2,
           "regex": "",
           "skipUrlSync": false,
diff --git a/src/webui/service/__init__.py b/src/webui/service/__init__.py
index 9187d90e76acd256bcac752ce7e7be025889e133..75e1036420d0bc88a790fb7b65f4f4900abaaadd 100644
--- a/src/webui/service/__init__.py
+++ b/src/webui/service/__init__.py
@@ -72,11 +72,15 @@ def create_app(use_config=None, web_app_root=None):
     from webui.service.service.routes import service
     app.register_blueprint(service)
 
+    from webui.service.slice.routes import slice
+    app.register_blueprint(slice)
+
     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
     
diff --git a/src/webui/service/link/routes.py b/src/webui/service/link/routes.py
index 04c4b1de59283832b17c92c91727fa716a2c0fea..51e903d9ec28c5aaac20cd49e2f97dd7044e12bf 100644
--- a/src/webui/service/link/routes.py
+++ b/src/webui/service/link/routes.py
@@ -12,10 +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, url_for
-from common.proto.context_pb2 import Empty, LinkList
+
+from flask import current_app, render_template, Blueprint, flash, session, redirect, url_for
+from common.proto.context_pb2 import Empty, Link, LinkEvent, LinkId, LinkIdList, LinkList, DeviceId
 from context.client.ContextClient import ContextClient
 
+
 link = Blueprint('link', __name__, url_prefix='/link')
 context_client = ContextClient()
 
@@ -32,4 +34,13 @@ def home():
     return render_template(
         "link/home.html",
         links=response.links,
-    )
\ No newline at end of file
+    )
+
+@link.route('detail/<path:link_uuid>', methods=('GET', 'POST'))
+def detail(link_uuid: str):
+    request = LinkId()
+    request.link_uuid.uuid = link_uuid
+    context_client.connect()
+    response = context_client.GetLink(request)
+    context_client.close()
+    return render_template('link/detail.html',link=response)
diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py
index 85d3aeeb7c6f23ab4123412173cdfda4d27b23a4..e9545ade40949a1ad772b35b669e02a1fa39d64d 100644
--- a/src/webui/service/main/routes.py
+++ b/src/webui/service/main/routes.py
@@ -12,53 +12,137 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json, logging
+import copy, json, logging
 from flask import jsonify, redirect, render_template, Blueprint, flash, session, url_for, request
-from common.proto.context_pb2 import Context, Device, Empty, Link, Topology, ContextIdList
+from common.proto.context_pb2 import Connection, Context, Device, Empty, Link, Service, Slice, Topology, ContextIdList
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from slice.client.SliceClient import SliceClient
 from webui.service.main.forms import ContextForm, DescriptorForm
 
 main = Blueprint('main', __name__)
 
 context_client = ContextClient()
 device_client = DeviceClient()
+service_client = ServiceClient()
+slice_client = SliceClient()
 
 logger = logging.getLogger(__name__)
 
-def process_descriptor(item_name_singluar, item_name_plural, grpc_method, grpc_class, items):
+ENTITY_TO_TEXT = {
+    # name   => singular,    plural
+    'context'   : ('Context',    'Contexts'   ),
+    'topology'  : ('Topology',   'Topologies' ),
+    'device'    : ('Device',     'Devices'    ),
+    'link'      : ('Link',       'Links'      ),
+    'service'   : ('Service',    'Services'   ),
+    'slice'     : ('Slice',      'Slices'     ),
+    'connection': ('Connection', 'Connections'),
+}
+
+ACTION_TO_TEXT = {
+    # action => infinitive, past
+    'add'     : ('Add',    'Added'),
+    'update'  : ('Update', 'Updated'),
+}
+
+def process_descriptor(entity_name, action_name, grpc_method, grpc_class, entities):
+    entity_name_singluar,entity_name_plural = ENTITY_TO_TEXT[entity_name]
+    action_infinitive, action_past = ACTION_TO_TEXT[action_name]
     num_ok, num_err = 0, 0
-    for item in items:
+    for entity in entities:
         try:
-            grpc_method(grpc_class(**item))
+            grpc_method(grpc_class(**entity))
             num_ok += 1
         except Exception as e: # pylint: disable=broad-except
-            flash(f'Unable to add {item_name_singluar} {str(item)}: {str(e)}', 'error')
+            flash(f'Unable to {action_infinitive} {entity_name_singluar} {str(entity)}: {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')
+    if num_ok : flash(f'{str(num_ok)} {entity_name_plural} {action_past}', 'success')
+    if num_err: flash(f'{str(num_err)} {entity_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
 
+    dummy_mode  = descriptors.get('dummy_mode' , False)
+    contexts    = descriptors.get('contexts'   , [])
+    topologies  = descriptors.get('topologies' , [])
+    devices     = descriptors.get('devices'    , [])
+    links       = descriptors.get('links'      , [])
+    services    = descriptors.get('services'   , [])
+    slices      = descriptors.get('slices'     , [])
+    connections = descriptors.get('connections', [])
+
+    if dummy_mode:
+        # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks.
+        context_client.connect()
+
+        contexts_add = copy.deepcopy(contexts)
+        for context in contexts_add:
+            context['topology_ids'] = []
+            context['service_ids'] = []
+
+        topologies_add = copy.deepcopy(topologies)
+        for topology in topologies_add:
+            topology['device_ids'] = []
+            topology['link_ids'] = []
+
+        process_descriptor('context',     'add',    context_client.SetContext,    Context,    contexts_add  )
+        process_descriptor('topology',    'add',    context_client.SetTopology,   Topology,   topologies_add)
+        process_descriptor('device',      'add',    context_client.SetDevice,     Device,     devices       )
+        process_descriptor('link',        'add',    context_client.SetLink,       Link,       links         )
+        process_descriptor('service',     'add',    context_client.SetService,    Service,    services      )
+        process_descriptor('context',     'update', context_client.SetContext,    Context,    contexts      )
+        process_descriptor('topology',    'update', context_client.SetTopology,   Topology,   topologies    )
+        process_descriptor('slice',       'add',    context_client.SetSlice,      Slice,      slices        )
+        process_descriptor('connection', 'add',    context_client.SetConnection, Connection, connections   )
+        context_client.close()
+        return
+
+    # Normal mode: follows the automated workflows in the different components
+
+    # in normal mode, connections should not be set
+    assert len(connections) == 0
+
+    services_add = []
+    for service in services:
+        service_copy = copy.deepcopy(service)
+        service_copy['service_endpoint_ids'] = []
+        service_copy['service_constraints'] = []
+        service_copy['service_config'] = {'config_rules': []}
+        services_add.append(service_copy)
+
+    slices_add = []
+    for slice in slices:
+        slice_copy = copy.deepcopy(slice)
+        slice_copy['slice_endpoint_ids'] = []
+        slice_copy['slice_constraints'] = []
+        slice_copy['slice_config'] = {'config_rules': []}
+        slices_add.append(slice_copy)
+
     context_client.connect()
     device_client.connect()
-    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'     ])
+    service_client.connect()
+    slice_client.connect()
+
+    process_descriptor('context',  'add',    context_client.SetContext,    Context,  contexts    )
+    process_descriptor('topology', 'add',    context_client.SetTopology,   Topology, topologies  )
+    process_descriptor('device',   'add',    device_client .AddDevice,     Device,   devices     )
+    process_descriptor('link',     'add',    context_client.SetLink,       Link,     links       )
+    process_descriptor('service',  'add',    service_client.CreateService, Service,  services_add)
+    process_descriptor('service',  'update', service_client.UpdateService, Service,  services    )
+    process_descriptor('slice',    'add',    slice_client.CreateSlice,     Slice,    slices_add  )
+    process_descriptor('slice',    'update', slice_client.UpdateSlice,     Slice,    slices      )
+
+    slice_client.close()
+    service_client.close()
     device_client.close()
     context_client.close()
 
@@ -69,14 +153,18 @@ def home():
     response: ContextIdList = context_client.ListContextIds(Empty())
     context_form: ContextForm = ContextForm()
     context_form.context.choices.append(('', 'Select...'))
+
     for context in response.context_ids:
         context_form.context.choices.append((context.context_uuid.uuid, context.context_uuid))
+
     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():
@@ -88,6 +176,7 @@ def home():
     finally:
         context_client.close()
         device_client.close()
+
     return render_template('main/home.html', context_form=context_form, descriptor_form=descriptor_form)
 
 @main.route('/topology', methods=['GET'])
@@ -102,11 +191,17 @@ def topology():
         } 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]
+        links = []
+        for link in response.links:
+            if len(link.link_endpoint_ids) != 2:
+                str_link = grpc_message_to_json_string(link)
+                logger.warning('Unexpected link with len(endpoints) != 2: {:s}'.format(str_link))
+                continue
+            links.append({
+                '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,
+            })
 
         return jsonify({'devices': devices, 'links': links})
     except:
diff --git a/src/webui/service/service/routes.py b/src/webui/service/service/routes.py
index 81031490ef840ff63262444a5487932a4e72c111..bc05daee3e4ff8795c26bed9e0707b9a3ab2be7c 100644
--- a/src/webui/service/service/routes.py
+++ b/src/webui/service/service/routes.py
@@ -14,7 +14,7 @@
 
 import grpc
 from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for
-from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceList, ServiceTypeEnum, ServiceStatusEnum
+from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceList, ServiceTypeEnum, ServiceStatusEnum, Connection
 from context.client.ContextClient import ContextClient
 from service.client.ServiceClient import ServiceClient
 
@@ -73,12 +73,14 @@ def detail(service_uuid: str):
     try:
         context_client.connect()
         response: Service = context_client.GetService(request)
+        connections: Connection = context_client.ListConnections(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)
+    return render_template('service/detail.html', service=response, connections=connections,ste=ServiceTypeEnum,
+                                                sse=ServiceStatusEnum)
 
 
 @service.get('<path:service_uuid>/delete')
@@ -100,4 +102,4 @@ def delete(service_uuid: str):
     except Exception as e:
         flash('Problem deleting service "{:s}": {:s}'.format(service_uuid, str(e.details())), 'danger')
         current_app.logger.exception(e)
-    return redirect(url_for('service.home'))
+    return redirect(url_for('service.home'))
\ No newline at end of file
diff --git a/src/webui/service/slice/__init__.py b/src/webui/service/slice/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..70a33251242c51f49140e596b8208a19dd5245f7
--- /dev/null
+++ b/src/webui/service/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/webui/service/slice/routes.py b/src/webui/service/slice/routes.py
new file mode 100644
index 0000000000000000000000000000000000000000..c5287501362db88edaf334426ca6e6d0e3331ef2
--- /dev/null
+++ b/src/webui/service/slice/routes.py
@@ -0,0 +1,103 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 flask import current_app, redirect, render_template, Blueprint, flash, session, url_for
+from common.proto.context_pb2 import ContextId, Slice, SliceId, SliceList, Connection, SliceStatusEnum
+from context.client.ContextClient import ContextClient
+#from slice.client.SliceClient import SliceClient
+
+
+
+slice = Blueprint('slice', __name__, url_prefix='/slice')
+
+context_client = ContextClient()
+#slice_client = SliceClient()
+
+@slice.get('/')
+def home():
+    # flash('This is an info message', 'info')
+    # 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()
+    request.context_uuid.uuid = context_uuid
+    context_client.connect()
+    try:
+        slice_list = context_client.ListSlices(request)
+        # print(slice_list)
+        slices = slice_list.slices
+        context_not_found = False
+    except grpc.RpcError as e:
+        if e.code() != grpc.StatusCode.NOT_FOUND: raise
+        if e.details() != 'Context({:s}) not found'.format(context_uuid): raise
+        slices = []
+        context_not_found = True
+    context_client.close()
+    return render_template('slice/home.html',slices=slices, context_not_found=context_not_found, sse=SliceStatusEnum)
+
+#
+#@slice.route('add', methods=['GET', 'POST'])
+#def add():
+#    flash('Add slice route called', 'danger')
+#    raise NotImplementedError()
+#    return render_template('slice/home.html')
+#
+#
+@slice.get('<path:slice_uuid>/detail')
+def detail(slice_uuid: str):
+    context_uuid = session.get('context_uuid', '-')
+    if context_uuid == "-":
+        flash("Please select a context!", "warning")
+        return redirect(url_for("main.home"))
+    
+    request: SliceId = SliceId()
+    request.slice_uuid.uuid = slice_uuid
+    request.context_id.context_uuid.uuid = context_uuid
+    req = ContextId()
+    req.context_uuid.uuid = context_uuid
+    try:
+        context_client.connect()
+        response: Slice = context_client.GetSlice(request)
+        services = context_client.ListServices(req)
+        context_client.close()
+    except Exception as e:
+        flash('The system encountered an error and cannot show the details of this slice.', 'warning')
+        current_app.logger.exception(e)
+        return redirect(url_for('slice.home'))
+    return render_template('slice/detail.html', slice=response, sse=SliceStatusEnum, services=services)
+#
+#@slice.get('<path:slice_uuid>/delete')
+#def delete(slice_uuid: str):
+#    context_uuid = session.get('context_uuid', '-')
+#    if context_uuid == "-":
+#        flash("Please select a context!", "warning")
+#        return redirect(url_for("main.home"))
+#
+#    try:
+#        request = SliceId()
+#        request.slice_uuid.uuid = slice_uuid
+#        request.context_id.context_uuid.uuid = context_uuid
+#        slice_client.connect()
+#        response = slice_client.DeleteSlice(request)
+#        slice_client.close()
+#
+#        flash('Slice "{:s}" deleted successfully!'.format(slice_uuid), 'success')
+#    except Exception as e:
+#        flash('Problem deleting slice "{:s}": {:s}'.format(slice_uuid, str(e.details())), 'danger')
+#        current_app.logger.exception(e) 
+#    return redirect(url_for('slice.home'))
\ No newline at end of file
diff --git a/src/webui/service/static/TeraFlow SDN Logo ScreenColour with Slogan.png b/src/webui/service/static/TeraFlow SDN Logo ScreenColour with Slogan.png
new file mode 100644
index 0000000000000000000000000000000000000000..218cc713c0a2704f96371fdd2916ef16b44cf667
Binary files /dev/null and b/src/webui/service/static/TeraFlow SDN Logo ScreenColour with Slogan.png differ
diff --git a/src/webui/service/static/topology_icons/Acknowledgements.txt b/src/webui/service/static/topology_icons/Acknowledgements.txt
index c646efdec0d79148f9bd066116d6ca3985f6f909..5daab200f87c29f18706e9e07023a45047739df7 100644
--- a/src/webui/service/static/topology_icons/Acknowledgements.txt
+++ b/src/webui/service/static/topology_icons/Acknowledgements.txt
@@ -8,5 +8,8 @@ https://symbols.getvecta.com/stencil_241/45_atm-switch.6a7362c1df.png => emu-pac
 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
+https://symbols.getvecta.com/stencil_240/269_virtual-layer-switch.ed10fdede6.png => open-line-system.png
+https://symbols.getvecta.com/stencil_241/281_virtual-layer-switch.29420aff2f.png => emu-open-line-system.png
+
+https://symbols.getvecta.com/stencil_240/102_ibm-tower.2cc133f3d0.png => datacenter.png
+https://symbols.getvecta.com/stencil_241/133_ibm-tower.995c44696c.png => emu-datacenter.png
diff --git a/src/webui/service/static/topology_icons/datacenter.png b/src/webui/service/static/topology_icons/datacenter.png
new file mode 100644
index 0000000000000000000000000000000000000000..33818cf87e0f47fb6fd45b45c46f368f62ab78d2
Binary files /dev/null and b/src/webui/service/static/topology_icons/datacenter.png differ
diff --git a/src/webui/service/static/topology_icons/emu-datacenter.png b/src/webui/service/static/topology_icons/emu-datacenter.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed2cc7376b481815edb48fb6faaa025289cfc3ca
Binary files /dev/null and b/src/webui/service/static/topology_icons/emu-datacenter.png differ
diff --git a/src/webui/service/static/topology_icons/emu-optical-line-system.png b/src/webui/service/static/topology_icons/emu-open-line-system.png
similarity index 100%
rename from src/webui/service/static/topology_icons/emu-optical-line-system.png
rename to src/webui/service/static/topology_icons/emu-open-line-system.png
diff --git a/src/webui/service/static/topology_icons/optical-line-system.png b/src/webui/service/static/topology_icons/open-line-system.png
similarity index 100%
rename from src/webui/service/static/topology_icons/optical-line-system.png
rename to src/webui/service/static/topology_icons/open-line-system.png
diff --git a/src/webui/service/templates/base.html b/src/webui/service/templates/base.html
index d314acb3d5cbe607e82474be7e66302f3d620d6a..9804e4afd1c1b7c889c2f3e0d627471ee13b5c68 100644
--- a/src/webui/service/templates/base.html
+++ b/src/webui/service/templates/base.html
@@ -1,160 +1,167 @@
-<!doctype html>
-<!--
- Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<html lang="en">
-  <head>
-    <!-- Required meta tags -->
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-
-    <link rel="shortcut icon" href="https://teraflow-h2020.eu/sites/teraflow/files/public/favicon.png" type="image/png" />
-
-    <!-- Bootstrap CSS -->
-    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous">
-    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
-
-    <title>TeraFlow OFC 2022 Demo</title>
-  </head>
-  <body>
-      <div id="teraflow-branding" style="width: 260px; margin: 7px;">
-        <a href="{{ url_for('main.home') }}" title="Home" rel="home" id="main-logo" class="site-logo site-logo-pages">
-            <svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 436.3 132.1"><defs><style>.cls-1{fill:#36a9e1;}.cls-2{fill:#1d71b8;}.cls-3{fill:none;stroke-width:2.52px;}.cls-10,.cls-3,.cls-4,.cls-5,.cls-7,.cls-8,.cls-9{stroke:#0f77b6;}.cls-3,.cls-4,.cls-8{stroke-miterlimit:10;}.cls-10,.cls-4,.cls-5,.cls-7,.cls-8,.cls-9{fill:#fff;}.cls-4{stroke-width:0.73px;}.cls-5,.cls-7{stroke-miterlimit:10;}.cls-5{stroke-width:0.75px;}.cls-6{fill:#0f77b6;}.cls-7{stroke-width:0.72px;}.cls-8{stroke-width:0.7px;}.cls-9{stroke-miterlimit:10;stroke-width:0.69px;}.cls-10{stroke-miterlimit:10;stroke-width:0.7px;}</style></defs><path class="cls-1" d="M96,57V51.3h44.1V57H121v52.3h-5.9V57Z"></path><path class="cls-1" d="M168.9,95.1l4.7,2.4a26,26,0,0,1-5.3,7.3,22.27,22.27,0,0,1-6.7,4.2,22.64,22.64,0,0,1-8.5,1.4c-7,0-12.5-2.3-16.4-6.9a23.53,23.53,0,0,1-5.9-15.6,23,23,0,0,1,5-14.5c4.2-5.4,9.9-8.1,17-8.1,7.3,0,13.2,2.8,17.5,8.3,3.1,3.9,4.7,8.8,4.7,14.7H136.4a17.48,17.48,0,0,0,4.8,12.3,15.26,15.26,0,0,0,11.4,4.8,20,20,0,0,0,6.4-1.1,19.3,19.3,0,0,0,5.3-3A33.07,33.07,0,0,0,168.9,95.1Zm0-11.6a18.66,18.66,0,0,0-3.2-7.1,15.25,15.25,0,0,0-5.6-4.3,16.87,16.87,0,0,0-7.3-1.6,16.06,16.06,0,0,0-10.9,4.1,18.15,18.15,0,0,0-5,8.9Z"></path><path class="cls-1" d="M182,66.4h5.6v6.3a20,20,0,0,1,5.3-5.5,10.67,10.67,0,0,1,5.8-1.8,9.87,9.87,0,0,1,4.9,1.5l-2.9,4.7a7.52,7.52,0,0,0-2.9-.7,8.09,8.09,0,0,0-5.3,2.3,14.64,14.64,0,0,0-3.9,7c-.7,2.4-1,7.4-1,14.8v14.5H182Z"></path><path class="cls-1" d="M246.2,66.4v42.9h-5.4V102a23.11,23.11,0,0,1-7.8,6.3,21.23,21.23,0,0,1-9.4,2.1,21,21,0,0,1-15.6-6.6,23.07,23.07,0,0,1,.1-32,21.23,21.23,0,0,1,15.7-6.6,20,20,0,0,1,17.1,8.9V66.2h5.3Zm-22.1,4.2a16.67,16.67,0,0,0-8.5,2.3,15.93,15.93,0,0,0-6.2,6.4,17.68,17.68,0,0,0-2.3,8.7,18.26,18.26,0,0,0,2.3,8.7,15.93,15.93,0,0,0,6.2,6.4,16.58,16.58,0,0,0,8.4,2.3,17.59,17.59,0,0,0,8.6-2.3,15.42,15.42,0,0,0,6.2-6.2,17.17,17.17,0,0,0,2.2-8.8,16.73,16.73,0,0,0-4.9-12.4A15.8,15.8,0,0,0,224.1,70.6Z"></path><path class="cls-2" d="M259.5,51.3h29.1V57H265.3V75.2h23.3v5.7H265.3v28.5h-5.8V51.3Z"></path><path class="cls-2" d="M296.9,49.9h5.5v59.5h-5.5Z"></path><path class="cls-2" d="M330.5,65.3a21.1,21.1,0,0,1,16.4,7.2A22.55,22.55,0,0,1,352.8,88a22.24,22.24,0,0,1-6.3,15.7c-4.2,4.5-9.5,6.7-16.1,6.7s-12-2.2-16.1-6.7A22.24,22.24,0,0,1,308,88a22.73,22.73,0,0,1,5.9-15.5A21.81,21.81,0,0,1,330.5,65.3Zm0,5.4a15.83,15.83,0,0,0-11.8,5.1,17,17,0,0,0-4.9,12.3,17.68,17.68,0,0,0,2.3,8.7,15.19,15.19,0,0,0,6.1,6.2,16.48,16.48,0,0,0,8.4,2.2A16,16,0,0,0,339,103a15.82,15.82,0,0,0,6.1-6.2,17.68,17.68,0,0,0,2.3-8.7,17.07,17.07,0,0,0-5-12.3A16.2,16.2,0,0,0,330.5,70.7Z"></path><path class="cls-2" d="M351.2,66.4h5.7L370,97.6l13.7-31.1h1l13.8,31.1,13.4-31.1h5.7L399,109.3h-1L384.3,78.6l-13.7,30.7h-1Z"></path><polyline class="cls-3" points="51 105 51 41.2 27 41.2"></polyline><polyline class="cls-3" points="38.1 33.8 56.4 33.8 56.4 93"></polyline><polyline class="cls-3" points="79.9 33.8 61.5 33.8 61.5 79.2"></polyline><polyline class="cls-3" points="90.7 41.2 66.7 41.2 66.7 105"></polyline><line class="cls-3" x1="83.1" y1="62.6" x2="66.7" y2="62.6"></line><circle class="cls-4" cx="27" cy="41.2" r="5.3"></circle><path class="cls-1" d="M23.3,41.2a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,23.3,41.2Z"></path><circle class="cls-5" cx="51" cy="105" r="5.4"></circle><path class="cls-1" d="M47.3,105a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,47.3,105Z"></path><circle class="cls-6" cx="56.36" cy="93.02" r="3.4"></circle><circle class="cls-6" cx="61.5" cy="79.2" r="2.8"></circle><circle class="cls-7" cx="66.7" cy="105.01" r="5.3"></circle><path class="cls-1" d="M63,105a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,63,105Z"></path><circle class="cls-8" cx="90.7" cy="41.2" r="5.1"></circle><path class="cls-1" d="M87,41.2a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,87,41.2Z"></path><circle class="cls-8" cx="84.7" cy="62.6" r="5.1"></circle><path class="cls-1" d="M81,62.6a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,81,62.6Z"></path><line class="cls-3" x1="34.8" y1="62.6" x2="51.1" y2="62.6"></line><circle class="cls-8" cx="33.1" cy="62.6" r="5.1"></circle><path class="cls-1" d="M36.9,62.6a3.8,3.8,0,1,1-3.8-3.8A3.8,3.8,0,0,1,36.9,62.6Z"></path><line class="cls-3" x1="23.7" y1="26.7" x2="94.1" y2="26.7"></line><circle class="cls-9" cx="94.09" cy="26.67" r="5"></circle><path class="cls-1" d="M90.3,26.7a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,90.3,26.7Z"></path><circle class="cls-6" cx="78" cy="33.8" r="3.8"></circle><circle class="cls-6" cx="40" cy="33.8" r="3.8"></circle><circle class="cls-10" cx="23.71" cy="26.71" r="5.1"></circle><path class="cls-1" d="M20,26.7a3.8,3.8,0,1,0,3.8-3.8A3.8,3.8,0,0,0,20,26.7Z"></path></svg>
-          </a>
-      </div>
-
-    <nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="margin-bottom: 10px;">
-        <div class="container-fluid">
-          <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
+  <!doctype html>
+  <!--
+   Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+  
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+  
+        http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  -->
+  
+  <html lang="en">
+    <head>
+      <!-- Required meta tags -->
+      <meta charset="utf-8">
+      <meta name="viewport" content="width=device-width, initial-scale=1">
+  
+      <link rel="shortcut icon" href="https://tfs.etsi.org/images/logos/tfs_logo_small.png" type="image/png" />
+  
+      <!-- Bootstrap CSS -->
+      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous">
+      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
+  
+      <title>ETSI TeraFlowSDN Controller</title>
+    </head>
+    <body>
+        <div id="teraflow-branding">
+          <a href="{{ url_for('main.home') }}" title="Home" rel="home" id="main-logo" class="site-logo site-logo-pages">
+            <img src="{{ url_for('static', filename='TeraFlow SDN Logo ScreenColour with Slogan.png') }}" width="400" type="image/png"> 
           </a>
-          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
-            <span class="navbar-toggler-icon"></span>
-          </button>
-          <div class="collapse navbar-collapse" id="navbarColor02">
-            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
-              <li class="nav-item">
-                {% if request.path == '/' %}
-                <a class="nav-link active" aria-current="page" href="{{ url_for('main.home') }}">Home</a>
-                {% else %}
-                <a class="nav-link" href="{{ url_for('main.home') }}">Home</a>
-                {% endif %}
-              </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>
-                {% else %}
-                <a class="nav-link" href="{{ url_for('device.home') }}">Device</a>
-                {% endif %}
-              </li>
-              <li class="nav-item">
-                {% 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('link.home') }}">Link</a>
-                {% 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>
-                {% else %}
-                <a class="nav-link" href="{{ url_for('service.home') }}">Service</a>
-                {% endif %}
-              </li>
-
-              <li class="nav-item">
-                <a class="nav-link" href="/grafana" id="grafana_link" target="grafana">Grafana</a>
-              </li>
-
-              <li class="nav-item">
-                <a class="nav-link" href="{{ url_for('main.debug') }}">Debug</a>
-              </li>
-
-              <!-- <li class="nav-item">
-                <a class="nav-link" href="#">Context</a>
-              </li>
-              
-              <li class="nav-item">
-                <a class="nav-link" href="#">Monitoring</a>
-              </li> -->
-              <li class="nav-item">
-                <a class="nav-link" href="{{ url_for('main.about') }}">About</a>
-              </li>
-            </ul>
-            <span class="navbar-text" style="color: #fff;">
-              Current context: <b>{{ get_working_context() }}</b>
-            </span>
-          </div>
         </div>
-      </nav>
-
-      <main class="container">
-        <div class="row">
-          <div class="col-md-12">
-            {% with messages = get_flashed_messages(with_categories=true) %}
-              {% if messages %}
-                {% for category, message in messages %}
-                  <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
-                    {{ message }}
-                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
-                  </div>
-      
-                {% endfor %}
-              {% endif %}
-            {% endwith %}
-          </div>
-        </div>
-        <div class="row">
-          <div class="col-xxl-12">
-          {% block content %}{% endblock %}
+  
+      <nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="margin-bottom: 10px;">
+          <div class="container-fluid">
+            <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>
+            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
+              <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="navbarColor02">
+              <ul class="navbar-nav me-auto mb-2 mb-lg-0">
+                <li class="nav-item">
+                  {% if request.path == '/' %}
+                  <a class="nav-link active" aria-current="page" href="{{ url_for('main.home') }}">Home</a>
+                  {% else %}
+                  <a class="nav-link" href="{{ url_for('main.home') }}">Home</a>
+                  {% endif %}
+                </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>
+                  {% else %}
+                  <a class="nav-link" href="{{ url_for('device.home') }}">Device</a>
+                  {% endif %}
+                </li>
+                <li class="nav-item">
+                  {% 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('link.home') }}">Link</a>
+                  {% 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>
+                  {% else %}
+                  <a class="nav-link" href="{{ url_for('service.home') }}">Service</a>
+                  {% endif %}
+                </li>
+                <li class="nav-item">
+                  {% if '/slice/' in request.path %}
+                  <a class="nav-link active" aria-current="page" href="{{ url_for('slice.home') }}">Slice</a>
+                  {% else %}
+                  <a class="nav-link" href="{{ url_for('slice.home') }}">Slice</a>
+                  {% endif %}
+                </li>
+                <!--<li class="nav-item">
+                  <a class="nav-link" href="/grafana" id="grafana_link" target="grafana">Grafana</a>
+                </li>-->
+  
+                <li class="nav-item">
+                  <a class="nav-link" href="{{ url_for('main.debug') }}">Debug</a>
+                </li>
+  
+                <!-- <li class="nav-item">
+                  <a class="nav-link" href="#">Context</a>
+                </li>
+                
+                <li class="nav-item">
+                  <a class="nav-link" href="#">Monitoring</a>
+                </li> -->
+                <li class="nav-item">
+                  <a class="nav-link" href="{{ url_for('main.about') }}">About</a>
+                </li>
+              </ul>
+              <span class="navbar-text" style="color: #fff;">
+                Current context: <b>{{ get_working_context() }}</b>
+              </span>
+            </div>
           </div>
-        </div>
-      </main>
-
-      <footer class="footer" style="background-color: darkgrey; margin-top: 30px; padding-top: 20px;">
-        <div class="container">
+        </nav>
+  
+        <main class="container">
           <div class="row">
             <div class="col-md-12">
-              <p class="text-center" style="color: white;">&copy; 2021-2023</p>
+              {% with messages = get_flashed_messages(with_categories=true) %}
+                {% if messages %}
+                  {% for category, message in messages %}
+                    <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
+                      {{ message }}
+                      <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
+                    </div>
+        
+                  {% endfor %}
+                {% endif %}
+              {% endwith %}
             </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 class="col-xxl-12">
+            {% block content %}{% endblock %}
+            </div>
+          </div>
+        </main>
+  
+        <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="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 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>
-        </div>
-      </footer>
-
-    <!-- Optional JavaScript; choose one of the two! -->
-
-    <!-- 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>
-    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.min.js" integrity="sha384-PsUw7Xwds7x08Ew3exXhqzbhuEYmA2xnwc8BuD6SEr+UmEHlX8/MCltYEodzWA4u" crossorigin="anonymous"></script>
-    -->
-  </body>
-</html>
\ No newline at end of file
+        </footer>
+  
+      <!-- Optional JavaScript; choose one of the two! -->
+  
+      <!-- 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>
+      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.min.js" integrity="sha384-PsUw7Xwds7x08Ew3exXhqzbhuEYmA2xnwc8BuD6SEr+UmEHlX8/MCltYEodzWA4u" crossorigin="anonymous"></script>
+      -->
+    </body>
+  </html>
\ 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 b4cf6b715250d3e96b5026c3e19758a2be9a9607..f2cdc581553bbd8d45f237fd99d2b746ab0ad61b 100644
--- a/src/webui/service/templates/device/detail.html
+++ b/src/webui/service/templates/device/detail.html
@@ -1,111 +1,129 @@
 <!--
- Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.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.
+   -->
+   
+   {% extends 'base.html' %}
+   
+   {% block content %}
+       <h1>Device {{ device.device_id.device_uuid.uuid }}</h1>
+   
+       <div class="row mb-3">
+           <div class="col-sm-3">
+               <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('device.home') }}'">
+                   <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>
+           </div>
+           <div class="col-sm-3">
+               <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete device</button> -->
+               <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
+                   <i class="bi bi-x-square"></i>Delete device
+                 </button>
+           </div>
+       </div>
 
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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>Device {{ device.device_id.device_uuid.uuid }}</h1>
-
-    <div class="row mb-3">
-        <div class="col-sm-3">
-            <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('device.home') }}'">
-                <i class="bi bi-box-arrow-in-left"></i>
-                Back to device list
-            </button>
+       <br>
+       <div class="row mb-3">
+            <div class="col-sm-4">
+                <b>UUID: </b>{{ device.device_id.device_uuid.uuid }}<br><br>
+                <b>Type: </b>{{ device.device_type }}<br><br>
+                <b>Drivers: </b>
+                <ul>
+                    {% for driver in device.device_drivers %}
+                    <li>{{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}</li>
+                    {% endfor %}
+                </ul>
+            </div>
+            <div class="col-sm-8">
+                    <table class="table table-striped table-hover">
+                        <thead>
+                            <tr>
+                                <th scope="col">Endpoints</th>
+                                <th scope="col">Type</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            {% for endpoint in device.device_endpoints %}
+                            <tr>
+                                <td>
+                                    {{ endpoint.endpoint_id.endpoint_uuid.uuid }}
+                                </td>
+                                <td>
+                                    {{ endpoint.endpoint_type }}
+                                </td>
+                            </tr>
+                            {% endfor %}
+                        </tbody>
+                    </table>
+                </div> 
+            </div>
         </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 device</button> -->
-            <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
-                <i class="bi bi-x-square"></i>Delete device
-              </button>
-        </div>
-    </div>
 
-    <div class="row mb-3">
-        <div class="col-sm-1"><b>UUID:</b></div>
-        <div class="col-sm-5">
-            {{ device.device_id.device_uuid.uuid }}
-        </div>
-        <div class="col-sm-1"><b>Type:</b></div>
-        <div class="col-sm-5">
-            {{ device.device_type }}
-        </div>
-    </div>
-    <div class="row mb-3">
-        <div class="col-sm-1"><b>Drivers:</b></div>
-        <div class="col-sm-11">
-            <ul>
-                {% for driver in device.device_drivers %}
-                <li>{{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}</li>
-                {% endfor %}
-            </ul>
-        </div>
-    </div>
-    <div class="row mb-3">
-        <b>Endpoints:</b>
-        <div class="col-sm-10">
-            <ul>
-            {% for endpoint in device.device_endpoints %}
-                <li>{{ endpoint.endpoint_id.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 device.device_config.config_rules %}
+        <table class="table table-striped table-hover">
+            <thead>
+                <tr>
+                    <th scope="col">Key</th>
+                    <th scope="col">Value</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for config in device.device_config.config_rules %}
                 {% if config.WhichOneof('config_rule') == 'custom' %}
-                <li>{{ config.custom.resource_key }}:
-                    <ul>
-                        {% for key, value in (config.custom.resource_value | from_json).items() %}
-                        <li><b>{{ key }}:</b> {{ value }}</li>
-                        {% endfor %}
-                    </ul>
-                </li>
+                <tr>
+                    <td>
+                        {{ config.custom.resource_key }}
+                    </td>
+                    <td>
+                        <ul>
+                            {% for key, value in (config.custom.resource_value | from_json).items() %}
+                            <li><b>{{ key }}:</b> {{ value }}</li>
+                            {% endfor %}
+                        </ul>
+                    </td>
+                </tr>
                 {% endif %}
-            {% endfor %}
-            </ul>
-        </div>
-    </div>
+                {% endfor %}
+            </tbody>
+        </table>
 
-    <!-- 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 device?</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 device "{{ device.device_id.device_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('device.delete', device_uuid=device.device_id.device_uuid.uuid) }}"><i class="bi bi-exclamation-diamond"></i>Yes</a>
-        </div>
-      </div>
-    </div>
-  </div>
 
-{% endblock %}
\ No newline at end of file
+       <!-- 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 device?</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 device "{{ device.device_id.device_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('device.delete', device_uuid=device.device_id.device_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/js/topology.js b/src/webui/service/templates/js/topology.js
index 05216fb98808d5b574d613344c63a7e19cb2c472..69de0445dac24bf2f7f16ec21da4a6d35133e9da 100644
--- a/src/webui/service/templates/js/topology.js
+++ b/src/webui/service/templates/js/topology.js
@@ -15,6 +15,15 @@
 // Based on:
 //   https://www.d3-graph-gallery.com/graph/network_basic.html
 //   https://bl.ocks.org/steveharoz/8c3e2524079a8c440df60c1ab72b5d03
+//   https://www.d3indepth.com/zoom-and-pan/
+
+// Pan & Zoom does not work; to be reviewed
+//<button onclick="zoomIn()">Zoom in</button>
+//<button onclick="zoomOut()">Zoom out</button>
+//<button onclick="resetZoom()">Reset zoom</button>
+//<button onclick="panLeft()">Pan left</button>
+//<button onclick="panRight()">Pan right</button>
+//<button onclick="center()">Center</button>
 
 // set the dimensions and margins of the graph
 const margin = {top: 5, right: 5, bottom: 5, left: 5};
@@ -22,16 +31,24 @@ 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;
+width = 1000 - margin.left - margin.right;
+height = 600 - margin.top - margin.bottom;
+
+//function handleZoom(e) {
+//    console.dir(e);
+//    d3.select('svg g').attr('transform', e.transform);
+//}
+//let zoom = d3.zoom().scaleExtent([0.01, 10]).translateExtent([[0, 0], [width, height]]).on('zoom', handleZoom);
 
 // 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)
+        //.call(zoom)
     .append('g')
-        .attr('transform', `translate(${margin.left}, ${margin.top})`);
+        .attr('transform', `translate(${margin.left}, ${margin.top})`)
+        ;
 
 // svg objects
 var link, node;
@@ -148,3 +165,25 @@ d3.select(window).on("resize", function(){
     height = +svg.node().getBoundingClientRect().height;
     simulation.alpha(1).restart();
 });
+
+///******************** UI ACTIONS *******************/
+//
+//function resetZoom() {
+//    d3.select('svg').transition().call(zoom.scaleTo, 1.0);
+//}
+//function zoomIn()    {
+//    d3.select('svg').transition().call(zoom.scaleBy, 2.0);
+//}
+//function zoomOut()   {
+//    d3.select('svg').transition().call(zoom.scaleBy, 0.5);
+//}
+//
+//function center()    {
+//    d3.select('svg').transition().call(zoom.translateTo, 0.5 * width, 0.5 * height);
+//}
+//function panLeft()   {
+//    d3.select('svg').transition().call(zoom.translateBy, -50, 0);
+//}
+//function panRight()  {
+//    d3.select('svg').transition().call(zoom.translateBy,  50, 0);
+//}
diff --git a/src/webui/service/templates/link/detail.html b/src/webui/service/templates/link/detail.html
new file mode 100644
index 0000000000000000000000000000000000000000..7df9ddce6bdddd511f3b50313cafa1374990b99e
--- /dev/null
+++ b/src/webui/service/templates/link/detail.html
@@ -0,0 +1,65 @@
+<!--
+    Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+   
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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>Link {{ link.link_id.link_uuid.uuid }}</h1>
+    <div class="row mb-3">
+          <div class="col-sm-3">
+               <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('link.home') }}'">
+                    <i class="bi bi-box-arrow-in-left"></i>
+                    Back to link list
+               </button>
+          </div>
+     </div>
+
+     <br>
+       <div class="row mb-3">
+            <div class="col-sm-4">
+                <b>UUID: </b>{{ link.link_id.link_uuid.uuid }}<br><br>
+            </div>
+            <div class="col-sm-8">
+                    <table class="table table-striped table-hover">
+                        <thead>
+                            <tr>
+                                <th scope="col">Endpoints</th>
+                                <th scope="col">Device</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                              {% for end_point in link.link_endpoint_ids %}
+                              <tr>
+                                   <td>
+                                        {{ end_point.endpoint_uuid.uuid }} 
+                                   </td>
+                                   <td>
+                                        <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>
+                                   </td>
+                              </tr>
+                              {% endfor %}
+                        </tbody>
+                    </table>
+            </div>
+        </div>
+
+   {% endblock %}
+   
\ No newline at end of file
diff --git a/src/webui/service/templates/link/home.html b/src/webui/service/templates/link/home.html
index d0c122f6aafd0de8e2937be056d1c2e787c91710..77d00d34185ac45ada0ed6d8e9915c0b2f3ad9c0 100644
--- a/src/webui/service/templates/link/home.html
+++ b/src/webui/service/templates/link/home.html
@@ -1,96 +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
+    Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+   
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="{{ url_for('link.detail', link_uuid=link.link_id.link_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>
+                   </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 4ba3a5845b0e8e70b029d4ec459733468899698b..80d61891ce95ff096308ed903da294bbf23c5070 100644
--- a/src/webui/service/templates/main/about.html
+++ b/src/webui/service/templates/main/about.html
@@ -16,10 +16,10 @@
 
 {% extends 'base.html' %}
 {% block content %}
-    <h1>TeraFlow OS</h1>
+    <h1>ETSI TeraFlowSDN Controller</h1>
 
-    <p>For more information, visit the <a href="https://teraflow-h2020.eu/" target="_newtf">TeraFlow H2020 webpage</a>.</p>
+    <p>For more information, visit the <a href="https://tfs.etsi.org/" target="_newtf">ETSI Open Source Group for TeraFlowSDN</a>.</p>
 
-    <img alt="Consortium" class="img-fluid" 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 3cc9fbcffce6cfbb6ebb40dec9d3359f59df5a15..db390939ff926b5bbfbfc6507b0f4e79695f3693 100644
--- a/src/webui/service/templates/main/home.html
+++ b/src/webui/service/templates/main/home.html
@@ -17,7 +17,7 @@
 {% extends 'base.html' %}
 
 {% block content %}
-    <h1>TeraFlow OS SDN Controller</h1>
+    <h2>ETSI TeraFlowSDN Controller</h2>
 
     {% for field, message in context_form.errors.items() %}
         <div class="alert alert-dismissible fade show" role="alert">
diff --git a/src/webui/service/templates/service/detail.html b/src/webui/service/templates/service/detail.html
index 1e58b9eaad3155524808f60b49840edab7f17739..94581019e3be34511b43630759dc237780db0f41 100644
--- a/src/webui/service/templates/service/detail.html
+++ b/src/webui/service/templates/service/detail.html
@@ -17,85 +17,224 @@
 {% extends 'base.html' %}
 
 {% block content %}
-    <h1>Service {{ service.service_id.service_uuid.uuid }}</h1>
+<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='{{ url_for('service.home') }}'">
-                <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 class="row mb-3">
+    <div class="col-sm-3">
+        <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('service.home') }}'">
+            <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 class="row mb-3">
+    <div class="col-sm-4">
+        <b>UUID: </b> {{ service.service_id.service_uuid.uuid }}<br><br>
+        <b>Type: </b> {{ ste.Name(service.service_type).replace('SERVICETYPE_', '') }}<br><br>
+        <b>Status: </b> {{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }}<br><br>
     </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 class="col-sm-8">
+        <table class="table table-striped table-hover">
+            <thead>
+                <tr>
+                    <th scope="col">Endpoints</th>
+                    <th scope="col">Device</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for endpoint in service.service_endpoint_ids %}
+                <tr>
+                    <td>
+                        {{ endpoint.endpoint_uuid.uuid }}
+                    </td>
+                    <td>
+                        <a href="{{ url_for('device.detail', device_uuid=endpoint.device_id.device_uuid.uuid) }}">
+                            {{ endpoint.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>
+                    </td>
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
     </div>
-    <div class="row mb-3">
-        <b>Configurations:</b>
-        <div class="col-sm-10">
-            <ul>
-            {% for config in service.service_config.config_rules %}
-                {% if config.WhichOneof('config_rule') == 'custom' %}
-                <li>{{ config.custom.resource_key }}:
-                    <ul>
-                        {% for key, value in (config.custom.resource_value | from_json).items() %}
-                        <li><b>{{ key }}:</b> {{ value }}</li>
-                        {% endfor %}
-                    </ul>
-                </li>
+</div>
+<b>Constraints:</b>
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Kind</th>
+            <th scope="col">Type</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for constraint in service.service_constraints %}
+        {% if constraint.WhichOneof('constraint')=='custom' %}
+        <tr>
+            <td>Custom</td>
+            <td>{{ constraint.custom.constraint_type }}</td>
+            <td>{{ constraint.custom.constraint_value }}</td>
+        </tr>
+        {% elif constraint.WhichOneof('constraint')=='endpoint_location' %}
+        <tr>
+            <td>Endpoint Location</td>
+            <td>
+                {{ constraint.endpoint_location.endpoint_id.device_id.device_uuid.uuid }} / {{
+                constraint.endpoint_location.endpoint_id.endpoint_uuid.uuid }}
+            </td>
+            <td>
+                {% if constraint.endpoint_location.location.WhichOneof('location')=='region' %}
+                    Region: {{ constraint.endpoint_location.location.region }}
+                {% elif constraint.endpoint_location.location.WhichOneof('location')=='gps_position' %}
+                    Position (lat/long):
+                    {{ constraint.endpoint_location.location.gps_position.latitude }} /
+                    {{ constraint.endpoint_location.location.gps_position.longitude }}
                 {% endif %}
-            {% 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">
+            </td>
+        </tr>
+        {% elif constraint.WhichOneof('constraint')=='endpoint_priority' %}
+        <tr>
+            <td>Endpoint Priority</td>
+            <td>
+                {{ constraint.endpoint_priority.endpoint_id.device_id.device_uuid.uuid }} / {{
+                constraint.endpoint_priority.endpoint_id.endpoint_uuid.uuid }}
+            </td>
+            <td>{{ constraint.endpoint_priority.priority }}</td>
+        </tr>
+        {% elif constraint.WhichOneof('constraint')=='sla_availability' %}
+        <tr>
+            <td>SLA Availability</td>
+            <td>-</td>
+            <td>
+                {{ constraint.sla_availability.num_disjoint_paths }} disjoint paths;
+                {% if constraint.sla_availability.all_active %}all{% else %}single{% endif %}active
+            </td>
+        </tr>
+        {% else %}
+        <tr>
+            <td>-</td>
+            <td>-</td>
+            <td>{{ constraint }}</td>
+        </tr>
+        {% endif %}
+        {% endfor %}
+    </tbody>
+</table>
+<b>Configurations:</b>
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Key</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for config in service.service_config.config_rules %}
+        {% if config.WhichOneof('config_rule') == 'custom' %}
+        <tr>
+            <td>
+                {{ config.custom.resource_key }}
+            </td>
+            <td>
+                <ul>
+                    {% for key, value in (config.custom.resource_value | from_json).items() %}
+                    <li><b>{{ key }}:</b> {{ value }}</li>
+                    {% endfor %}
+                </ul>
+            </td>
+        </tr>
+        {% endif %}
+        {% endfor %}
+    </tbody>
+</table>
+<!-- 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 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>
-  </div>
+</div>
+
+
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Connection Id</th>
+            <th scope="col">Sub-service</th>
+            <th scope="col">Path</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for connection in connections.connections %}
+        <tr>
+            <td>
+                {{ connection.connection_id.connection_uuid.uuid }}
+            </td>
+            <td>
+                <ul>
+                {% for sub_service_id in connection.sub_service_ids %}
+                    <li>
+                        <a href="{{ url_for('service.detail', service_uuid=sub_service_id.service_uuid.uuid) }}">
+                            {{ sub_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>
+                    </li>
+                {% endfor %}
+                </ul>
+            </td>
+
+            {% for i in range(connection.path_hops_endpoint_ids|length) %}
+            <td>
+                {{ connection.path_hops_endpoint_ids[i].device_id.device_uuid.uuid }} / {{
+                connection.path_hops_endpoint_ids[i].endpoint_uuid.uuid }}
+            </td>
+            {% endfor %}
+        </tr>
+        {% endfor %}
+    </tbody>
+</table>
+
+
+
+
 
 {% 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 0e152006c149df35d477ecfb81bb4fcc0b562d9a..c0a01839bb519074526a4ed34669ebfdd3d8b8e4 100644
--- a/src/webui/service/templates/service/home.html
+++ b/src/webui/service/templates/service/home.html
@@ -46,7 +46,6 @@
             <th scope="col">#</th>
             <th scope="col">Type</th>
             <th scope="col">End points</th>
-            <th scope="col">Constraints</th>
             <th scope="col">Status</th>
             <th scope="col"></th>
           </tr>
@@ -70,14 +69,7 @@
                             {% endfor %}
                         </ul>
                     </td>
-                    <td>
-                        <ul>
-                            {% for constraint in service.service_constraints %}
-                            <li>{{ constraint.constraint_type }}: {{ constraint.constraint_value }}</li>
-                            {% endfor %}
-                        </ul>
-                    </td>
-                    <td>{{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }}</td>
+                    <td>{{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }} </td>
                     <td>
                         <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">
diff --git a/src/webui/service/templates/slice/detail.html b/src/webui/service/templates/slice/detail.html
new file mode 100644
index 0000000000000000000000000000000000000000..936b0f08fb1b7def156e11f16bf552b8d60018be
--- /dev/null
+++ b/src/webui/service/templates/slice/detail.html
@@ -0,0 +1,221 @@
+<!--
+ Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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>Slice {{ slice.slice_id.slice_uuid.uuid }} </h1>
+
+<div class="row mb-3">
+    <div class="col-sm-3">
+        <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('slice.home') }}'">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Back to slice 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 slice</button> -->
+        <!--<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
+            <i class="bi bi-x-square"></i>Delete slice
+        </button>
+    </div>
+    -->
+</div>
+
+<div class="row mb-3">
+    <div class="col-sm-4">
+        <b>UUID: </b> {{ slice.slice_id.slice_uuid.uuid }}<br><br>
+        <b>Status: </b> {{ sse.Name(slice.slice_status.slice_status).replace('SLICESTATUS_', '') }}<br><br>
+    </div>
+    <div class="col-sm-8">
+        <table class="table table-striped table-hover">
+            <thead>
+                <tr>
+                    <th scope="col">Endpoints</th>
+                    <th scope="col">Device</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for endpoint in slice.slice_endpoint_ids %}
+                <tr>
+                    <td>
+                        {{ endpoint.endpoint_uuid.uuid }}
+                    </td>
+                    <td>
+                        <a href="{{ url_for('device.detail', device_uuid=endpoint.device_id.device_uuid.uuid) }}">
+                            {{ endpoint.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>
+                    </td>
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+<b>Constraints:</b>
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Kind</th>
+            <th scope="col">Type</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for constraint in slice.slice_constraints %}
+        {% if constraint.WhichOneof('constraint')=='custom' %}
+        <tr>
+            <td>Custom</td>
+            <td>{{ constraint.custom.constraint_type }}</td>
+            <td>{{ constraint.custom.constraint_value }}</td>
+        </tr>
+        {% elif constraint.WhichOneof('constraint')=='endpoint_location' %}
+        <tr>
+            <td>Endpoint Location</td>
+            <td>
+                {{ constraint.endpoint_location.endpoint_id.device_id.device_uuid.uuid }} / {{
+                constraint.endpoint_location.endpoint_id.endpoint_uuid.uuid }}
+            </td>
+            <td>
+                {% if constraint.endpoint_location.location.WhichOneof('location')=='region' %}
+                    Region: {{ constraint.endpoint_location.location.region }}
+                {% elif constraint.endpoint_location.location.WhichOneof('location')=='gps_position' %}
+                    Position (lat/long):
+                    {{ constraint.endpoint_location.location.gps_position.latitude }} /
+                    {{ constraint.endpoint_location.location.gps_position.longitude }}
+                {% endif %}
+            </td>
+        </tr>
+        {% elif constraint.WhichOneof('constraint')=='endpoint_priority' %}
+        <tr>
+            <td>Endpoint Priority</td>
+            <td>
+                {{ constraint.endpoint_priority.endpoint_id.device_id.device_uuid.uuid }} / {{
+                constraint.endpoint_priority.endpoint_id.endpoint_uuid.uuid }}
+            </td>
+            <td>{{ constraint.endpoint_priority.priority }}</td>
+        </tr>
+        {% elif constraint.WhichOneof('constraint')=='sla_availability' %}
+        <tr>
+            <td>SLA Availability</td>
+            <td>-</td>
+            <td>
+                {{ constraint.sla_availability.num_disjoint_paths }} disjoint paths;
+                {% if constraint.sla_availability.all_active %}all{% else %}single{% endif %}active
+            </td>
+        </tr>
+        {% else %}
+        <tr>
+            <td>-</td>
+            <td>-</td>
+            <td>{{ constraint }}</td>
+        </tr>
+        {% endif %}
+        {% endfor %}
+    </tbody>
+</table>
+<b>Configurations:</b>
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Key</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for config in slice.slice_config.config_rules %}
+        {% if config.WhichOneof('config_rule') == 'custom' %}
+        <tr>
+            <td>
+                {{ config.custom.resource_key }}
+            </td>
+            <td>
+                <ul>
+                    {% for key, value in (config.custom.resource_value | from_json).items() %}
+                    <li><b>{{ key }}:</b> {{ value }}</li>
+                    {% endfor %}
+                </ul>
+            </td>
+        </tr>
+        {% endif %}
+        {% endfor %}
+    </tbody>
+</table>
+<div class="row mb-2">
+    <div class="col-sm-6">
+        <table class="table table-striped table-hover">
+            <thead>
+                <tr>
+                    <th scope="col">Service Id</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for service_id in slice.slice_service_ids %}
+                <tr>
+                    <td>
+                        <a href="{{ url_for('service.detail', service_uuid=service_id.service_uuid.uuid) }}">
+                            {{ 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>
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+    <div class="col-sm-6">
+        <table class="table table-striped table-hover">
+            <thead>
+                <tr>
+                    <th scope="col">Sub-slices</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for subslice_id in slice.slice_subslice_ids %}
+                <tr>
+                    <td>
+                        <a href="{{ url_for('slice.detail', slice_uuid=subslice_id.slice_uuid.uuid) }}">
+                            {{ subslice_id.slice_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>
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/src/webui/service/templates/slice/home.html b/src/webui/service/templates/slice/home.html
new file mode 100644
index 0000000000000000000000000000000000000000..46a2b4f1a5b4aceb5e432b7b69563d20258fc152
--- /dev/null
+++ b/src/webui/service/templates/slice/home.html
@@ -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.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+    <h1>Slice</h1>
+
+    <div class="row">
+
+        <div class="col">
+            {{ slices | length }} slices found in context <i>{{ session['context_uuid'] }}</i>
+        </div>
+
+    </div>
+
+    
+    <table class="table table-striped table-hover">
+        <thead>
+          <tr>
+            <th scope="col">#</th>
+            <th scope="col">End points</th>
+            <th scope="col">Status</th>
+            <th scope="col"></th>
+            
+          </tr>
+        </thead>
+        <tbody>
+            {% if slices %}
+                {% for slice in slices %}
+                <tr>
+                    <td>
+                        {{ slice.slice_id.slice_uuid.uuid }}
+                    </td>
+                    <td>
+                        <ul>
+                        {% for i in range(slice.slice_endpoint_ids|length) %}
+                            <li> {{ slice.slice_endpoint_ids[i].device_id.device_uuid.uuid }} / {{ slice.slice_endpoint_ids[i].endpoint_uuid.uuid }} </li>
+                        {% endfor %}
+                        </ul>
+                    </td>
+                    <td>
+                        {{ sse.Name(slice.slice_status.slice_status).replace('SLICESTATUS_', '') }}
+                    </td>
+                    <td>
+                        <a href="{{ url_for('slice.detail', slice_uuid=slice.slice_id.slice_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>
+                </tr>
+                {% endfor %}
+                {% else %}
+                <tr>
+                    <td colspan="7">No slices found</td>
+                </tr> 
+            
+            {% endif %}
+        </tbody>
+    </table>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/webui/tests/test_unitary.py b/src/webui/tests/test_unitary.py
index 945a60186e04cc1bd3ee7678b340e9321646df97..11cc77a460a94707c6226cdfc4ca747563e95f45 100644
--- a/src/webui/tests/test_unitary.py
+++ b/src/webui/tests/test_unitary.py
@@ -68,6 +68,7 @@ class TestWebUI(ClientTestCase):
         with self.app.app_context():
             url_for('main.home')
             url_for('service.home')
+            url_for('slice.home')
             url_for('device.home')
             url_for('link.home')
             #url_for('main.debug')
diff --git a/tutorial/1-1-1-create-vm-oracle-virtualbox.md b/tutorial/1-1-1-create-vm-oracle-virtualbox.md
index c53601e145d4ad0ca41c55803c27d55309070231..ea0da6cabfa46ba2c16166b07cc8c6e345da2246 100644
--- a/tutorial/1-1-1-create-vm-oracle-virtualbox.md
+++ b/tutorial/1-1-1-create-vm-oracle-virtualbox.md
@@ -26,7 +26,8 @@ __Note__: IP address 10.0.2.10 is the one that will be assigned to the VM.
 - RAM: 8 GB
 - Disk: 40 GB, Virtual Disk Image (VDI), Dynamically allocated
 - Optical Drive ISO Image: "ubuntu-20.04.4-live-server-amd64.iso"
-  (from [Ubuntu Server 20.04 LTS](https://releases.ubuntu.com/20.04/))
+  - Download the file "ubuntu-20.04.4-live-server-amd64.iso" from [Ubuntu 20.04 LTS](https://releases.ubuntu.com/20.04/).
+  - __Note__: use Ubuntu Server image instead of Ubuntu Desktop to create a lightweight VM.
 - Network Adapter 1 (*): enabled, attached to NAT Network "TFS-NAT-Net"
 - Minor adjustments (*):
   - Audio: disabled
diff --git a/tutorial/1-2-install-microk8s.md b/tutorial/1-2-install-microk8s.md
index 09e0b41a36a9b6c88883377be6c0737157f7afba..327c6af9e477b4edd9b769371f79b32933746af6 100644
--- a/tutorial/1-2-install-microk8s.md
+++ b/tutorial/1-2-install-microk8s.md
@@ -70,7 +70,16 @@ sudo ufw default allow routed
 ```bash
 sudo usermod -a -G docker $USER
 sudo usermod -a -G microk8s $USER
-sudo chown -f -R $USER ~/.kube
+sudo chown -f -R $USER $HOME/.kube
+sudo reboot
+```
+
+In case that the .kube file is not automatically provisioned into your home folder, you may follow the steps below:
+
+```bash
+mkdir -p $HOME/.kube
+sudo chown -f -R $USER $HOME/.kube
+microk8s config > $HOME/.kube/config
 sudo reboot
 ```
 
diff --git a/tutorial/1-3-deploy-tfs.md b/tutorial/1-3-deploy-tfs.md
index 07c79d7ab34f12b9042a38489752b28bd4fd474e..9b2da4fc1734fc08d0bb24621aadd067d7a29b97 100644
--- a/tutorial/1-3-deploy-tfs.md
+++ b/tutorial/1-3-deploy-tfs.md
@@ -58,7 +58,7 @@ password to be set for the Grafana `admin` user.
 cd ~/tfs-ctrl
 tee my_deploy.sh >/dev/null <<EOF
 export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
-export TFS_COMPONENTS="context device automation service compute monitoring webui"
+export TFS_COMPONENTS="context device automation pathcomp service slice compute monitoring webui"
 export TFS_IMAGE_TAG="dev"
 export TFS_K8S_NAMESPACE="tfs"
 export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
diff --git a/tutorial/2-0-run-experiments.md b/tutorial/2-0-run-experiments.md
index f87d00e98a66449f5fa6d267c527565b145722b2..82f6a56bf0481a4edeaf71251510f74c51138096 100644
--- a/tutorial/2-0-run-experiments.md
+++ b/tutorial/2-0-run-experiments.md
@@ -8,5 +8,5 @@ commands you might need, configuring the network topology, and executing differe
 - [2.1. Configure the Python environment](./2-1-python-environment.md)
 - [2.2. OFC'22 Demo - Bootstrap devices, Monitor device Endpoints, Manage L3VPN Services](./2-2-ofc22.md)
 - [2.3. OECC/PSC'22 Demo (WORK IN PROGRESS)](./2-3-oeccpsc22.md)
-- [2.4. ECOC'22 Demo (PENDING)](./2-4-ecoc22.md)
+- [2.4. ECOC'22 Demo - Disjoint DC-2-DC L3VPN Service (WORK IN PROGRESS)](./2-4-ecoc22.md)
 - [2.5. NFV-SDN'22 Demo (PENDING)](./2-5-nfvsdn22.md)
diff --git a/tutorial/2-1-python-environment.md b/tutorial/2-1-python-environment.md
index 4a818e9e7c0a2d4b4ef21ed48d04c84b339046fc..e03e3daff118f8c1f1268d85a215527aab0358b4 100644
--- a/tutorial/2-1-python-environment.md
+++ b/tutorial/2-1-python-environment.md
@@ -32,6 +32,13 @@ eval "$(pyenv init -)"
 eval "$(pyenv virtualenv-init -)"
 ```
 
+In case .bashrc is not linked properly to your profile, you may need to append the following line into your local .profile file:
+
+```bash
+# Open ~/.profile and append this line:
++source "$HOME"/.bashrc
+```
+
 
 ## 2.1.4. Restart the VM
 Restart the VM for all the changes to take effect.
@@ -58,6 +65,13 @@ pyenv virtualenv 3.9.13 tfs
 pyenv local 3.9.13/envs/tfs
 ```
 
+In case that the correct pyenv does not get automatically activated when you change to the tfs-ctrl/ folder, then execute the following command:
+
+```bash
+cd ~/tfs-ctrl
+pyenv activate 3.9.13/envs/tfs
+```
+
 After completing these commands, you should see in your prompt that now you're within the virtual environment
 `3.9.13/envs/tfs` on folder `~/tfs-ctrl`:
 ```
diff --git a/tutorial/2-2-ofc22.md b/tutorial/2-2-ofc22.md
index 5a0547d640267ebd45030d10ce8673d984c6b137..1a2ee8cda8c58fb534cd73f056f46345116d779e 100644
--- a/tutorial/2-2-ofc22.md
+++ b/tutorial/2-2-ofc22.md
@@ -30,8 +30,8 @@ __Important__: The device drivers operating with real devices, e.g., OpenConfigD
 ## 2.2.3. Deployment and Dependencies
 
 To run this functional test, it is assumed you have deployed a MicroK8s-based Kubernetes environment and a TeraFlowSDN
-controller instance as described in the [Tutorial: Deployment Guide](./1-0-deployment.md), and you configured
-the Python environment as described in
+controller instance as described in the [Tutorial: Deployment Guide](./1-0-deployment.md), and you configured the Python
+environment as described in
 [Tutorial: Run Experiments Guide > 2.1. Configure Python Environment](./2-1-python-environment.md).
 Remember to source the scenario settings appropriately, e.g., `cd ~/tfs-ctrl && source my_deploy.sh` in each terminal
 you open.
@@ -49,6 +49,24 @@ Notes:
 
 ## 2.2.5. Test execution
 
+Before executing the tests, the environment variables need to be prepared. First, make sure to load your deployment variables by:
+
+```
+source my_deploy.sh
+```
+
+Then, you also need to load the environment variables to support the execution of the tests by:
+
+```
+source tfs_runtime_env_vars.sh
+```
+
+You also need to make sure that you have all the gRPC-generate code in your folder. To do so, run:
+
+```
+proto/generate_code_python.sh
+```
+
 To execute this functional test, four main steps needs to be carried out:
 1. Device bootstrapping
 2. L3VPN Service creation
diff --git a/tutorial/2-4-ecoc22.md b/tutorial/2-4-ecoc22.md
index f752bda840a3eb2fbde6c907e4ce139de3f8ce82..6fc9333b58fe7c6da51be5eefe9167853508456a 100644
--- a/tutorial/2-4-ecoc22.md
+++ b/tutorial/2-4-ecoc22.md
@@ -1 +1,120 @@
-# 2.4. ECOC'22 Demo (PENDING)
+# 2.4. ECOC'22 Demo - Disjoint DC-2-DC L3VPN Service (WORK IN PROGRESS)
+
+This functional test reproduces the experimental assessment of "Experimental Demonstration of Transport Network Slicing
+with SLA Using the TeraFlowSDN Controller" presented at [ECOC'22](https://www.ecoc2022.org/).
+
+## 2.4.1. Functional test folder
+
+This functional test can be found in folder `./src/tests/ecoc22/`. A convenience alias `./ecoc22/` pointing to that
+folder has been defined.
+
+## 2.4.2. Execute with real devices
+
+This functional test has only been tested with emulated devices; however, if you have access to real devices, you can
+modify the files `./ecoc22/tests/Objects.py` and `./ecoc22/tests/Credentials.py` to point to your devices, and map to
+your network topology.
+Otherwise, you can modify the `./ecoc22/tests/descriptors_emulated.json` that is designed to be uploaded through the
+WebUI instead of using the command line scripts.
+
+__Important__: The device drivers operating with real devices, e.g., OpenConfigDriver, P4Driver, and TransportApiDriver,
+               have to be considered as experimental. The configuration and monitoring capabilities they support are
+               limited or partially implemented/tested. Use them with care.
+
+
+## 2.4.3. Deployment and Dependencies
+
+To run this functional test, it is assumed you have deployed a MicroK8s-based Kubernetes environment and a TeraFlowSDN
+controller instance as described in the [Tutorial: Deployment Guide](./1-0-deployment.md), and you configured the Python
+environment as described in
+[Tutorial: Run Experiments Guide > 2.1. Configure Python Environment](./2-1-python-environment.md).
+Remember to source the scenario settings appropriately, e.g., `cd ~/tfs-ctrl && source my_deploy.sh` in each terminal
+you open.
+Next, remember to source the environment variables created by the deployment, e.g.,
+`cd ~/tfs-ctrl && source tfs_runtime_env_vars.sh`.
+Then, re-build the protocol buffers code from the proto files:
+`./proto/generate_code_python.sh`
+
+
+
+## 2.4.4. Access to the WebUI and Dashboard
+
+When the deployment completes, you can connect to the TeraFlowSDN WebUI and Dashboards as described in
+[Tutorial: Deployment Guide > 1.4. Access TeraFlowSDN WebUI and Grafana Dashboards](./1-4-access-webui.md)
+
+Notes:
+- the default credentials for the Grafana Dashboiard is user/pass: `admin`/`admin123+`.
+- this functional test does not involve the Monitoring component, so no monitoring data is plotted in Grafana.
+
+
+## 2.4.5. Test execution
+
+To execute this functional test, four main steps needs to be carried out:
+1. Device bootstrapping
+2. L3VPN Service creation
+3. L3VPN Service removal
+4. Cleanup
+
+Upon the execution of each test progresses, a report will be generated indicating PASSED / FAILED / SKIPPED. If there
+is some error during the execution, you should see a detailed report on the error. See the troubleshooting section if
+needed.
+
+You can check the logs of the different components using the appropriate `scripts/show_logs_[component].sh` scripts
+after you execute each step.
+
+
+### 2.4.5.1. Device bootstrapping
+
+This step configures some basic entities (Context and Topology), the devices, and the links in the topology. The
+expected results are:
+- The devices to be added into the Topology.
+- The devices to be pre-configured and initialized as ENABLED by the Automation component.
+- The monitoring for the device ports (named as endpoints in TeraFlowSDN) to be activated and data collection to
+  automatically start.
+- The links to be added to the topology.
+
+To run this step, you can do it from the WebUI by uploading the file `./ecoc22/tests/descriptors_emulated.json` that
+contains the descriptors of the contexts, topologies, devices, and links, or by executing the
+`./ecoc22/run_test_01_bootstrap.sh` script.
+
+When the bootstrapping finishes, check in the Grafana L3-Monitoring Dashboard and you should see the monitoring data
+being plotted and updated every 5 seconds (by default). Given that there is no service configured, you should see a
+0-valued flat plot.
+
+In the WebUI, select the "admin" Context. Then, in the "Devices" tab you should see that 5 different emulated devices
+have been created and activated: 4 packet routers, and 1 optical line system controller. Besides, in the "Services" tab
+you should see that there is no service created. Note here that the emulated devices produce synthetic
+randomly-generated data and do not care about the services configured.
+
+
+### 2.4.5.2. L3VPN Service creation
+
+This step configures a new service emulating the request an OSM WIM would make by means of a Mock OSM instance.
+
+To run this step, execute the `./ecoc22/run_test_02_create_service.sh` script.
+
+When the script finishes, check the WebUI "Services" tab. You should see that two services have been created, one for
+the optical layer and another for the packet layer. Besides, you can check the "Devices" tab to see the configuration
+rules that have been configured in each device. In the Grafana Dashboard, given that there is now a service configured,
+you should see the plots with the monitored data for the device. By default, device R1-EMU is selected.
+
+
+### 2.4.5.3. L3VPN Service removal
+
+This step deconfigures the previously created services emulating the request an OSM WIM would make by means of a Mock
+OSM instance.
+
+To run this step, execute the `./ecoc22/run_test_03_delete_service.sh` script, or delete the L3NM service from the WebUI.
+
+When the script finishes, check the WebUI "Services" tab. You should see that the two services have been removed.
+Besides, in the "Devices" tab you can see that the appropriate configuration rules have been deconfigured. In the
+Grafana Dashboard, given that there is no service configured, you should see a 0-valued flat plot again.
+
+
+### 2.4.5.4. Cleanup
+
+This last step performs a cleanup of the scenario removing all the TeraFlowSDN entities for completeness.
+
+To run this step, execute the `./ecoc22/run_test_04_cleanup.sh` script.
+
+When the script finishes, check the WebUI "Devices" tab, you should see that the devices have been removed. Besides, in
+the "Services" tab you can see that the "admin" Context has no services given that that context has been removed.
diff --git a/tutorial/3-2-develop-cth.md b/tutorial/3-2-develop-cth.md
index eda70c9e8c411c8cc6a0ed0832f573ca787962ca..1b2a4690a3177628e18a4ca6f77365f515d6dcc5 100644
--- a/tutorial/3-2-develop-cth.md
+++ b/tutorial/3-2-develop-cth.md
@@ -1,5 +1,18 @@
 # 3.2. Development Commands, Tricks, and Hints (WORK IN PROGRESS)
 
+## Building, running, testing and reporting code coverage locally
+
+The project runs a CI/CD loops that ensures that all tests are run whenever new code is committed to our reporitory.
+However, committing and waiting for the pipeline to run can take substantial time.
+For this reason, we prepared a script that runs in your local machine, builds the container image and executes the tests within the image.
+
+To use the script receives one argument that is the name of the component you want to run.
+For instance, if you want to build and run the tests of the `compute` component, you can run:
+
+```shell
+scripts/build_run_report_tests_locally.sh compute
+```
+
 
 
 ## Items to be addressed: