diff --git a/.gitignore b/.gitignore
index 71b77da25c4d53db49b24642d88062906e7db219..56f7580de26e47f75f8bf16346b35f35e229491d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -130,6 +130,9 @@ venv.bak/
 # VSCode project settings
 .vscode/
 
+# Visual Studio project settings
+/.vs
+
 # Rope project settings
 .ropeproject
 
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/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/src/common/tools/object_factory/Link.py b/src/common/tools/object_factory/Link.py
index 13973566ece5e6f83312c9bd50ca0c4add2d262b..922a39dbe24f4f4b635f378180ab13c80322801b 100644
--- a/src/common/tools/object_factory/Link.py
+++ b/src/common/tools/object_factory/Link.py
@@ -18,7 +18,7 @@ from typing import Dict, List
 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 json_link_id(link_uuid : str):
     return {'link_uuid': {'uuid': link_uuid}}
diff --git a/src/common/tools/object_factory/Service.py b/src/common/tools/object_factory/Service.py
index f0f49210ec067267984dede6f28d7adad8009261..51f75e6dbe5e430330e697da772d65703f7568c7 100644
--- a/src/common/tools/object_factory/Service.py
+++ b/src/common/tools/object_factory/Service.py
@@ -21,7 +21,7 @@ from common.tools.object_factory.Context import json_context_id
 def get_service_uuid(a_endpoint_id : Dict, z_endpoint_id : Dict) -> str:
     return 'svc:{: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 json_service_id(service_uuid : str, context_id : Optional[Dict] = None):
     result = {'service_uuid': {'uuid': service_uuid}}
diff --git a/src/pathcomp/.gitlab-ci.yml b/src/pathcomp/.gitlab-ci.yml
index fd52da6fb7bf8dc556b92e4db080c9927bb58a5d..1515ad0395b9e54142f1076d42d3eb5b2febac5d 100644
--- a/src/pathcomp/.gitlab-ci.yml
+++ b/src/pathcomp/.gitlab-ci.yml
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 # Build, tag, and push the Docker image to the GitLab Docker registry
-build pathcomp:
+build pathcomp-backend:
   variables:
     IMAGE_NAME: 'pathcomp' # name of the microservice
     IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
@@ -21,9 +21,11 @@ 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 tag "${IMAGE_NAME}-backend:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG"
   after_script:
     - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
   rules:
@@ -32,35 +34,126 @@ 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
       - manifests/${IMAGE_NAME}service.yaml
       - .gitlab-ci.yml
 
+# Build, tag, and push the Docker image to the GitLab Docker registry
+build pathcomp-frontend:
+  variables:
+    IMAGE_NAME: 'pathcomp' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: build
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    - docker build -t "${IMAGE_NAME}-frontend:$IMAGE_TAG" -f ./src/$IMAGE_NAME/frontend/Dockerfile .
+    - docker tag "${IMAGE_NAME}-frontend:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/${IMAGE_NAME}-frontend:$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:
+    - 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
+      - manifests/${IMAGE_NAME}service.yaml
+      - .gitlab-ci.yml
+
+# Apply unit test to the component
+unit test pathcomp-backend:
+  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-backend
+  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}-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}-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}
+    - sleep 5
+    - docker ps -a
+    - docker logs ${IMAGE_NAME}-backend
+    - sleep 5
+    - 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"
+    - sleep 5
+    - docker exec -i ${IMAGE_NAME}-backend bash -c "killall -USR1 pathComp-cvr"
+    - sleep 5
+    - docker exec -i ${IMAGE_NAME}-backend bash -c "gcovr"
+  coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  after_script:
+    - 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)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+    - changes:
+      - src/common/**/*.py
+      - proto/*.proto
+      - 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:
+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
+    - build pathcomp-frontend
+    - build pathcomp-backend
   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}-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 $CI_REGISTRY_IMAGE/${IMAGE_NAME}-backend:$IMAGE_TAG
+    - sleep 1
+    - docker run --name ${IMAGE_NAME}-frontend -d -p 10020:10020 --env "PATHCOMP_BACKEND_HOST=${IMAGE_NAME}-backend" --env "PATHCOMP_BACKEND_PORT=8081" -v "$PWD/src/${IMAGE_NAME}/frontend/tests:/opt/results" --network=teraflowbridge $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
-    - 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}-frontend
+    - docker logs ${IMAGE_NAME}-backend
+    - sleep 5
+    - 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"
+    - sleep 5
+    - docker exec -i ${IMAGE_NAME}-frontend bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
+    - sleep 5
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
-    - docker rm -f $IMAGE_NAME
+    - 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)'
@@ -68,16 +161,16 @@ 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/frontend/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/frontend/Dockerfile
+      - src/$IMAGE_NAME/frontend/tests/*.py
       - 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 +179,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..b239d2ea04d981869fa3a52905359bfc9336489f
--- /dev/null
+++ b/src/pathcomp/backend/Dockerfile
@@ -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.
+
+# 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
+
+# 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
+
+EXPOSE 8081
+
+# builder defines coverage version of pathcomp by default
+ENTRYPOINT [ "./pathComp-cvr", "config/pathcomp.conf", "pathcomp.log" ]
+
+
+# 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
+
+ENTRYPOINT [ "./pathComp", "config/pathcomp.conf", "pathcomp.log" ]
diff --git a/src/pathcomp/backend/Dockerfile-gdb b/src/pathcomp/backend/Dockerfile-gdb
new file mode 100644
index 0000000000000000000000000000000000000000..13af33006504095204878b465bdee7f84f549d20
--- /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", "pathcomp.log" ] 
diff --git a/src/pathcomp/backend/Makefile b/src/pathcomp/backend/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2777468b2ee54d764aa410a5c41f9e443ade2f06
--- /dev/null
+++ b/src/pathcomp/backend/Makefile
@@ -0,0 +1,67 @@
+#
+# 	# 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_RESTapi.o 
+	gcc -o pathComp pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.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_RESTapi.o 
+	gcc -o pathComp-dbg pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.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_RESTapi.o 
+	gcc -o pathComp-cvr pathComp.o pathComp_log.o pathComp_cjson.o pathComp_tools.o pathComp_ksp.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_RESTapi.o: pathComp_tools.h pathComp_log.h pathComp_cjson.h pathComp_ksp.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..330f0f61a6d1ea9ff0d4327ede6541b4faca1528
--- /dev/null
+++ b/src/pathcomp/backend/pathComp.c
@@ -0,0 +1,185 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# 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]);
+	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..dd352c613d26124a97c2bdd79070634572a3c976
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_RESTapi.c
@@ -0,0 +1,1963 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# 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_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) {
+    
+	g_assert(compRouteOutputList);
+	gint ret = 0;
+    
+    //DEBUG_PC ("Creating the JSON Body and sending the response of the computed Route List");
+    
+    guchar buftmp[1024];
+    char * buf = g_malloc0 (sizeof (char) * 2048000); 
+    // Create the Body of the Response 
+    char * jsonBody = g_malloc0 (sizeof (char) * 2048000);    
+    gint length = 0;
+    
+    rapi_response_json_contents (jsonBody, &length, compRouteOutputList);
+		
+	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);
+    //DEBUG_PC ("Buffer Length (JSON BODY): %d Added to the Content Length", 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 *)jsonBody);		
+	//DEBUG_PC ("%s", buf);	    
+    ret = rapi_send_message (source, buf);    
+    g_free (buf);
+    memset (buftmp, '\0', sizeof ( buftmp));    
+    g_free (jsonBody);
+    (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) {
+
+	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++) {
+		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) -- Device Id: %s (uuid)", 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);
+			}
+		}
+	}
+	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) {
+
+	for (gint i = 0; i < cJSON_GetArraySize(linkListArray); i++) {
+		linkList->numLinks++;
+		struct link_t* l = &(linkList->links[i]);
+
+		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)) {
+			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("Starting the Creation of the Reverse Links [current: %d]", linkList->numLinks);
+	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
+#if 0
+		if (refLink->numLinkEndPointIds != 2) {
+			DEBUG_PC("To construct the new Link from ref, 2 EndPoints are a MUST");
+			exit(-1);
+		}
+#endif
+		//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)//////////////////////////////////////	
+	// Connectivity Service Abstraction (CSA)
+	if (strncmp ((const char*)algId, "KSP", 3) == 0)
+	{
+		DEBUG_PC ("Alg Id: KSP");
+		httpCode = pathComp_ksp_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';	
+
+	// for method POST, PUT check that the url is "/pathComp"
+	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..25e9d0b6041fdfab2373213408f62c12da31eb12
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_ksp.c
@@ -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)
+ */
+ ////////////////////////////////////////////////////////////////////////////////////////
+#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 = NULL;
+struct graph_t *graph = NULL;
+struct contextSet_t* contextSet = NULL;
+//struct linkList_t* linkList;
+//struct deviceList_t* deviceList;
+//struct serviceList_t* serviceList;
+
+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_ksp.c
+ * 	@brief update statistics of the KSP path computation
+ *
+ *  @param routeConnList
+ *	@param d
+ *
+ *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
+ *	@date 2021
+ */
+ /////////////////////////////////////////////////////////////////////////////////////////
+void update_stats_ksp_path_comp(struct compRouteOutputList_t* routeConnList, struct timeval d)
+{
+	g_assert(routeConnList);
+	g_assert(serviceList);
+	
+	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 KSP 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;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@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 shortes 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);
+	
+	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_ksp_path_comp(routeConnList, delta);
+	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..628bd6e83b06f6bedda13ee31fe052eff01d6809
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_ksp.h
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# 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>
+
+#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
+
+
+// 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_tools.c b/src/pathcomp/backend/pathComp_tools.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e584438461e9b99fdda9607ae3143ac5f48edf3
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_tools.c
@@ -0,0 +1,2703 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# 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"
+
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	@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);
+	}
+	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;
+}
+
diff --git a/src/pathcomp/backend/pathComp_tools.h b/src/pathcomp/backend/pathComp_tools.h
new file mode 100644
index 0000000000000000000000000000000000000000..90a0cc8b878134cf29fa4eb1728f08a8b72aa4d9
--- /dev/null
+++ b/src/pathcomp/backend/pathComp_tools.h
@@ -0,0 +1,606 @@
+////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 	# 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 K_MAX							5
+
+#define MAX_NODE_ID_SIZE				37 // UUID 128 Bits - In hexadecimal requires 36 char
+#define MAX_CONTEXT_ID					37
+#define UUID_CHAR_LENGTH				37
+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				100
+#define MAX_NUM_EDGES					100
+// 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		100
+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)
+
+	guint 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*);
+#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..75f910e36f92ca008b318cfc61718ae81f94214c
--- /dev/null
+++ b/src/pathcomp/frontend/Config.py
@@ -0,0 +1,28 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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_HOST    = str(os.environ.get('PATHCOMP_BACKEND_HOST',    DEFAULT_PATHCOMP_BACKEND_HOST   ))
+PATHCOMP_BACKEND_PORT    = int(os.environ.get('PATHCOMP_BACKEND_PORT',    DEFAULT_PATHCOMP_BACKEND_PORT   ))
+PATHCOMP_BACKEND_BASEURL = str(os.environ.get('PATHCOMP_BACKEND_BASEURL', DEFAULT_PATHCOMP_BACKEND_BASEURL))
+
+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/__init__.py b/src/pathcomp/frontend/__init__.py
similarity index 100%
rename from src/pathcomp/__init__.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/client/__init__.py b/src/pathcomp/frontend/client/__init__.py
similarity index 100%
rename from src/pathcomp/client/__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..b1da515631320d7d77dee073e8985a8d63bd3c30
--- /dev/null
+++ b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.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 grpc, json, logging, requests, uuid
+from typing import Dict, Tuple
+from common.proto.context_pb2 import Empty, EndPointId, Service
+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.Config import BACKEND_URL
+from pathcomp.frontend.service.tools.ComposeRequest import compose_device, compose_link, compose_service
+#from pathcomp.frontend.service.tools.Constants import CapacityUnit
+
+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)))
+
+        algorithm = request.WhichOneof('algorithm')
+        if algorithm == 'shortest_path':
+            # no attributes
+            pass
+        elif algorithm == 'k_shortest_path':
+            k_inspection = request.k_shortest_path.k_inspection
+            k_return = request.k_shortest_path.k_return
+        else:
+            raise NotImplementedError('Unsupported Algorithm: {:s}'.format(str(algorithm)))
+
+        context_client = ContextClient()
+
+        algorithm = {'id': 'KSP', 'sync': False, 'k_paths': k_return}
+        service_list = [
+            compose_service(grpc_service, algorithm)
+            for grpc_service in request.services
+        ]
+        get_service_key = lambda service_id: (service_id['contextId'], service_id['service_uuid'])
+        service_dict : Dict[Tuple[str, str], Tuple[Dict, Service]] = {
+            get_service_key(json_service['serviceId']): (json_service, grpc_service)
+            for json_service,grpc_service in zip(service_list, request.services)
+        }
+        #LOGGER.info('service_dict = {:s}'.format(str(service_dict)))
+
+        # TODO: consider filtering resources
+
+        #grpc_contexts = context_client.ListContexts(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
+
+        grpc_devices = context_client.ListDevices(Empty())
+        device_list = [
+            compose_device(grpc_device)
+            for grpc_device in grpc_devices.devices
+        ]
+        endpoint_dict : Dict[str, Dict[str, Tuple[Dict, EndPointId]]] = {
+            json_device['device_Id']: {
+                json_endpoint['endpoint_id']['endpoint_uuid']: (json_endpoint['endpoint_id'], grpc_endpoint.endpoint_id)
+                for json_endpoint,grpc_endpoint in zip(json_device['device_endpoints'], grpc_device.device_endpoints)
+            }
+            for json_device,grpc_device in zip(device_list, grpc_devices.devices)
+        }
+        #LOGGER.info('endpoint_dict = {:s}'.format(str(endpoint_dict)))
+
+        grpc_links = context_client.ListLinks(Empty())
+        link_list = [
+            compose_link(grpc_link)
+            for grpc_link in grpc_links.links
+        ]
+
+        request = {
+            'serviceList': service_list,
+            'deviceList' : device_list,
+            'linkList'   : link_list,
+        }
+
+        #with open('pc-req.json', 'w', encoding='UTF-8') as f:
+        #    f.write(json.dumps(request, sort_keys=True, indent=4))
+
+        reply = requests.post(BACKEND_URL, json=request)
+        if reply.status_code not in {requests.codes.ok}:
+            raise Exception('Backend error({:s}) for request({:s})'.format(
+                str(reply.content.decode('UTF-8')), json.dumps(request, sort_keys=True)))
+        LOGGER.info('status_code={:s} reply={:s}'.format(
+            str(reply.status_code), str(reply.content.decode('UTF-8'))))
+
+        json_reply = reply.json()
+        response_list = json_reply.get('response-list', [])
+        reply = PathCompReply()
+        for response in response_list:
+            service_key = get_service_key(response['serviceId'])
+            tuple_service = service_dict.get(service_key)
+            if tuple_service is None: raise Exception('ServiceKey({:s}) not found'.format(str(service_key)))
+            json_service, grpc_service = tuple_service
+
+            # TODO: implement support for multi-point services
+            service_endpoint_ids = grpc_service.service_endpoint_ids
+            if len(service_endpoint_ids) != 2: raise NotImplementedError('Service must have 2 endpoints')
+
+            service = reply.services.add()
+            service.CopyFrom(grpc_service)
+
+            connection = reply.connections.add()
+            connection.connection_id.connection_uuid.uuid = str(uuid.uuid4())
+            connection.service_id.CopyFrom(service.service_id)
+
+            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
+
+            service_paths = response['path']
+
+            for service_path in service_paths:
+                # ... "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']
+
+                path_endpoints = service_path['devices']
+                for endpoint in path_endpoints:
+                    device_uuid = endpoint['device_id']
+                    endpoint_uuid = endpoint['endpoint_uuid']
+                    endpoint_id = connection.path_hops_endpoint_ids.add()
+                    endpoint_id.CopyFrom(endpoint_dict[device_uuid][endpoint_uuid][1])
+
+        LOGGER.info('[Compute] end ; reply = {:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
diff --git a/src/pathcomp/service/__init__.py b/src/pathcomp/frontend/service/__init__.py
similarity index 100%
rename from src/pathcomp/service/__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 100%
rename from src/pathcomp/service/__main__.py
rename to src/pathcomp/frontend/service/__main__.py
diff --git a/src/pathcomp/frontend/service/tools/ComposeRequest.py b/src/pathcomp/frontend/service/tools/ComposeRequest.py
new file mode 100644
index 0000000000000000000000000000000000000000..68395523b4bb122483479451cc08b26094032b5c
--- /dev/null
+++ b/src/pathcomp/frontend/service/tools/ComposeRequest.py
@@ -0,0 +1,137 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+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 .Constants import CapacityUnit, LinkForwardingDirection, LinkPortDirection, TerminationDirection, TerminationState
+
+def compose_topology_id(topology_id : TopologyId) -> Dict:
+    context_uuid = topology_id.context_id.context_uuid.uuid
+    topology_uuid = topology_id.topology_uuid.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
+    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':
+        MSG = 'Constraint({:s}) not supported'
+        str_constraint = grpc_message_to_json_string(constraint)
+        raise NotImplementedError(MSG.format(str_constraint))
+    constraint_type = constraint.custom.constraint_type
+    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, algorithm : Dict) -> 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 = [
+        compose_constraint(service_constraint)
+        for service_constraint in grpc_service.service_constraints
+    ]
+
+    # algorithm to be executed
+    algorithm_id = algorithm.get('id', 'SP')
+
+    # if multiple services included in the request, prevent contention
+    # If true, services are computed one after the other and resources
+    # assigned to service i, are considered as used by services i+1..n
+    sync_paths = algorithm.get('sync', False)
+
+    k_paths = algorithm.get('k_paths', 1)
+
+    return {
+        'serviceId': service_id,
+        'serviceType': service_type,
+        'service_endpoints_ids': endpoint_ids,
+        'service_constraints': constraints,
+
+        'algId': algorithm_id,
+        'syncPaths': sync_paths,
+        'kPaths': k_paths,
+    }
diff --git a/src/pathcomp/frontend/service/tools/Constants.py b/src/pathcomp/frontend/service/tools/Constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb774669c97144fa65afdaf0f3373c67a67c3212
--- /dev/null
+++ b/src/pathcomp/frontend/service/tools/Constants.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 enum import IntEnum
+
+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
diff --git a/src/pathcomp/tests/__init__.py b/src/pathcomp/frontend/service/tools/__init__.py
similarity index 100%
rename from src/pathcomp/tests/__init__.py
rename to src/pathcomp/frontend/service/tools/__init__.py
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 100%
rename from src/pathcomp/tests/MockService_Dependencies.py
rename to src/pathcomp/frontend/tests/MockService_Dependencies.py
diff --git a/src/pathcomp/tests/Objects.py b/src/pathcomp/frontend/tests/Objects.py
similarity index 71%
rename from src/pathcomp/tests/Objects.py
rename to src/pathcomp/frontend/tests/Objects.py
index f4785d7ae670efcc5525d6b00c4baf3acf3f22b1..586911180bcb7379382b644cac1eb338a31bd522 100644
--- a/src/pathcomp/tests/Objects.py
+++ b/src/pathcomp/frontend/tests/Objects.py
@@ -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])
@@ -94,12 +98,12 @@ 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('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/tests/PrepareTestScenario.py b/src/pathcomp/frontend/tests/PrepareTestScenario.py
similarity index 91%
rename from src/pathcomp/tests/PrepareTestScenario.py
rename to src/pathcomp/frontend/tests/PrepareTestScenario.py
index a4efcbdbfc0d311dfb120ab8124a9d2268660daf..9fb57e41b51f99b52bf71f7c6fc4d02d98ea100e 100644
--- a/src/pathcomp/tests/PrepareTestScenario.py
+++ b/src/pathcomp/frontend/tests/PrepareTestScenario.py
@@ -18,9 +18,9 @@ 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
diff --git a/src/pathcomp/Config.py b/src/pathcomp/frontend/tests/__init__.py
similarity index 99%
rename from src/pathcomp/Config.py
rename to src/pathcomp/frontend/tests/__init__.py
index 9953c820575d42fa88351cc8de022d880ba96e6a..70a33251242c51f49140e596b8208a19dd5245f7 100644
--- a/src/pathcomp/Config.py
+++ b/src/pathcomp/frontend/tests/__init__.py
@@ -11,3 +11,4 @@
 # WITHOUT 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/test_unitary.py b/src/pathcomp/frontend/tests/test_unitary.py
similarity index 74%
rename from src/pathcomp/tests/test_unitary.py
rename to src/pathcomp/frontend/tests/test_unitary.py
index 23e574e0e1b512b7a69b69847ef5ef034bd2ca41..7f614e69c2c6594c2fbf7f1b85b5ae7a9f71f328 100644
--- a/src/pathcomp/tests/test_unitary.py
+++ b/src/pathcomp/frontend/tests/test_unitary.py
@@ -18,8 +18,8 @@ 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 pathcomp.frontend.client.PathCompClient import PathCompClient
+from .Objects import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, 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)
@@ -37,13 +37,34 @@ def test_prepare_environment(
     for device   in DEVICES   : device_client .AddDevice  (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(
     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']
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/test-commands.sh b/src/pathcomp/test-commands.sh
new file mode 100644
index 0000000000000000000000000000000000000000..cb764fae11bf1326edce75e24cc9229c0f480379
--- /dev/null
+++ b/src/pathcomp/test-commands.sh
@@ -0,0 +1,31 @@
+#!/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 teraflowbridge
+
+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"