diff --git a/manifests/pcepservice.yaml b/manifests/pcepservice.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d2e82abffe034a92d913a619da9b0a8333b06d58
--- /dev/null
+++ b/manifests/pcepservice.yaml
@@ -0,0 +1,72 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: pcepservice
+spec:
+  selector:
+    matchLabels:
+      app: pcepservice
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: pcepservice
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: localhost:32000/tfs/pcep:dev
+        imagePullPolicy: Always
+        ports:
+        - containerPort: 10050
+        - containerPort: 9192
+        env:
+        - name: LOG_LEVEL
+          value: "DEBUG"
+        readinessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:10050"]
+        livenessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:10050"]
+        resources:
+          requests:
+            cpu: 50m
+            memory: 64Mi
+          limits:
+            cpu: 500m
+            memory: 512Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: pcepservice
+  labels:
+    app: pcepservice
+spec:
+  type: ClusterIP
+  selector:
+    app: pcepservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 10050
+    targetPort: 10050
+  - name: metrics
+    protocol: TCP
+    port: 9192
+    targetPort: 9192
diff --git a/proto/context.proto b/proto/context.proto
index 3104f1b545c02bab71c8638ebba03efdcbfe71ff..e7e2aa3fa88b9af4e477c5ccdb0322616d2ff834 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -34,6 +34,14 @@ service ContextService {
   rpc RemoveTopology     (TopologyId    ) returns (       Empty           ) {}
   rpc GetTopologyEvents  (Empty         ) returns (stream TopologyEvent   ) {}
 
+  rpc ListInventoryIds   (Empty         ) returns (       InventoryIdList ) {}
+  rpc ListInventory      (Empty         ) returns (       InventoryList   ) {}
+  rpc ListInventoryNames (InventoryIdList) returns(     InventoryNameList ) {}
+  rpc GetInventory       (InventoryId   ) returns (       Inventory       ) {}
+  rpc SetInventory       (Inventory     ) returns (       InventoryId     ) {}
+  rpc RemoveInventory    (InventoryId   ) returns (       Empty           ) {}
+  rpc GetInventoryEvents (InventoryId   ) returns (stream InventoryEvent  ) {}
+
   rpc ListDeviceIds      (Empty         ) returns (       DeviceIdList    ) {}
   rpc ListDevices        (Empty         ) returns (       DeviceList      ) {}
   rpc GetDevice          (DeviceId      ) returns (       Device          ) {}
@@ -174,12 +182,17 @@ message Device {
   DeviceOperationalStatusEnum device_operational_status = 5;
   repeated DeviceDriverEnum device_drivers = 6;
   repeated EndPoint device_endpoints = 7;
-  repeated Component component = 8; // Used for inventory
-  DeviceId controller_id = 9; // Identifier of node controlling the actual device
+  // Used for inventory:
+  map<string, Component> components = 8; // dict[comp.name => Component]
+    DeviceId controller_id = 9; // Identifier of node controlling the actual device
 }
 
 message Component {
-  repeated string comp_string = 1;
+  Uuid uuid = 1;
+  string name = 2;
+  string type = 3;
+  repeated string child = 4; // list[sub-component.name]
+  map<string, string> attributes = 5; // dict[attr.name => json.dumps(attr.value)]
 }
 
 message DeviceConfig {
@@ -589,3 +602,42 @@ message AuthenticationResult {
   ContextId context_id = 1;
   bool authenticated = 2;
 }
+
+// -----Inventory ------------------------------------------------------------------------------------------------------
+message InventoryId{
+  TopologyId topology_id = 1;
+  DeviceId device_id = 2;
+  Uuid inventory_uuid = 3;
+}
+
+message Inventory{
+  InventoryId inventory_id = 1;
+  string name = 2;
+  string inventory_type = 3;
+  repeated kpi_sample_types.KpiSampleType kpi_sample_types = 4;
+  string datos = 5;
+}
+
+message InventoryName {
+  InventoryId inventory_id = 1;
+  string device_name = 2;
+  string inventory_name = 3;
+  string inventory_type = 4;
+}
+
+message InventoryIdList {
+  repeated InventoryId inventory_ids = 1;
+}
+
+message InventoryNameList {
+  repeated InventoryName inventory_names = 1;
+}
+
+message InventoryList {
+  repeated Inventory inventory = 1;
+}
+
+message InventoryEvent {
+  Inventory event = 1;
+  InventoryId inventory_id = 2;
+}
\ No newline at end of file
diff --git a/proto/pcep.proto b/proto/pcep.proto
new file mode 100644
index 0000000000000000000000000000000000000000..c238e24bb43e54ecfd3a3c26bfdd381ad7a87b4f
--- /dev/null
+++ b/proto/pcep.proto
@@ -0,0 +1,40 @@
+// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package pcep;
+
+
+service PcepService {
+  rpc sendRequest    ( RequestRq ) returns (       RequestRp      ) {}
+  rpc configuratePCE ( PceIpRq   ) returns (       PceIpRp      ) {}
+}
+
+message RequestRq {
+  string command = 1;
+}
+
+message RequestRp {
+  string commandRp = 1;
+}
+
+message PceIpRq {
+  string address=1;
+  string port= 2;
+  string asNumber=3;
+}
+
+message PceIpRp{
+  string addressRp=1;
+}
diff --git a/src/common/Constants.py b/src/common/Constants.py
index ed1c1475ad3c69cfb9bd650f0d99f33c6cf0f2bc..5db459168a442b482333c5deb6bff59f724e587f 100644
--- a/src/common/Constants.py
+++ b/src/common/Constants.py
@@ -56,6 +56,7 @@ class ServiceNameEnum(Enum):
     OPTICALATTACKDETECTOR  = 'opticalattackdetector'
     OPTICALATTACKMITIGATOR = 'opticalattackmitigator'
     CACHING                = 'caching'
+    PCEP          = 'pcep'
 
     # Used for test and debugging only
     DLT_GATEWAY    = 'dltgateway'
@@ -80,6 +81,7 @@ DEFAULT_SERVICE_GRPC_PORTS = {
     ServiceNameEnum.OPTICALATTACKMANAGER   .value : 10005,
     ServiceNameEnum.INTERDOMAIN            .value : 10010,
     ServiceNameEnum.PATHCOMP               .value : 10020,
+    ServiceNameEnum.PCEP         .value : 10050,
 
     # Used for test and debugging only
     ServiceNameEnum.DLT_GATEWAY   .value : 50051,
diff --git a/src/pcep/.gitlab-ci.yml b/src/pcep/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c8f765c8702e2f063a207fb9ddca4ba31b57a35c
--- /dev/null
+++ b/src/pcep/.gitlab-ci.yml
@@ -0,0 +1,224 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Build, tag, and push the Docker image to the GitLab Docker registry
+build service:
+  variables:
+    IMAGE_NAME: 'pcep' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: build
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile .
+    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+  after_script:
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+    - changes:
+      - src/common/**/*.py
+      - proto/*.proto
+      - src/$IMAGE_NAME/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/Dockerfile
+      - src/$IMAGE_NAME/tests/*.py
+      - manifests/${IMAGE_NAME}service.yaml
+      - .gitlab-ci.yml
+
+# Apply unit test to the component
+unit_test service:
+  variables:
+    IMAGE_NAME: 'pcep' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: unit_test
+  needs:
+    - build service
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create --driver=bridge teraflowbridge; fi
+
+    # Context-related
+    - if docker container ls | grep crdb; then docker rm -f crdb; else echo "CockroachDB container is not in the system"; fi
+    - if docker volume ls | grep crdb; then docker volume rm -f crdb; else echo "CockroachDB volume is not in the system"; fi
+    - if docker container ls | grep nats; then docker rm -f nats; else echo "NATS container is not in the system"; fi
+
+    # Device-related
+    - if docker container ls | grep context; then docker rm -f context; else echo "context image is not in the system"; fi
+    - if docker container ls | grep device; then docker rm -f device; else echo "device image is not in the system"; fi
+
+    # Pathcomp-related
+    - if docker container ls | grep pathcomp-frontend; then docker rm -f pathcomp-frontend; else echo "pathcomp-frontend image is not in the system"; fi
+    - if docker container ls | grep pathcomp-backend; then docker rm -f pathcomp-backend; else echo "pathcomp-backend image is not in the system"; fi
+
+    # Service-related
+    - if docker container ls | grep $IMAGE_NAME; then docker rm -f $IMAGE_NAME; else echo "$IMAGE_NAME image is not in the system"; fi
+
+  script:
+    - docker pull "cockroachdb/cockroach:latest-v22.2"
+    - docker pull "nats:2.9"
+    - docker pull "$CI_REGISTRY_IMAGE/context:$IMAGE_TAG"
+    - docker pull "$CI_REGISTRY_IMAGE/device:$IMAGE_TAG"
+    - docker pull "$CI_REGISTRY_IMAGE/pathcomp-frontend:$IMAGE_TAG"
+    - docker pull "$CI_REGISTRY_IMAGE/pathcomp-backend:$IMAGE_TAG"
+    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+
+    # Context preparation
+    - docker volume create crdb
+    - >
+      docker run --name crdb -d --network=teraflowbridge -p 26257:26257 -p 8080:8080
+      --env COCKROACH_DATABASE=tfs_test --env COCKROACH_USER=tfs --env COCKROACH_PASSWORD=tfs123
+      --volume "crdb:/cockroach/cockroach-data"
+      cockroachdb/cockroach:latest-v22.2 start-single-node
+    - >
+      docker run --name nats -d --network=teraflowbridge -p 4222:4222 -p 8222:8222
+      nats:2.9 --http_port 8222 --user tfs --pass tfs123
+    - echo "Waiting for initialization..."
+    - while ! docker logs crdb 2>&1 | grep -q 'finished creating default user \"tfs\"'; do sleep 1; done
+    - docker logs crdb
+    - while ! docker logs nats 2>&1 | grep -q 'Server is ready'; do sleep 1; done
+    - docker logs nats
+    - docker ps -a
+    - CRDB_ADDRESS=$(docker inspect crdb --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
+    - echo $CRDB_ADDRESS
+    - NATS_ADDRESS=$(docker inspect nats --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
+    - echo $NATS_ADDRESS
+    - >
+      docker run --name context -d -p 1010:1010
+      --env "CRDB_URI=cockroachdb://tfs:tfs123@${CRDB_ADDRESS}:26257/tfs_test?sslmode=require"
+      --env "MB_BACKEND=nats"
+      --env "NATS_URI=nats://tfs:tfs123@${NATS_ADDRESS}:4222"
+      --network=teraflowbridge
+      $CI_REGISTRY_IMAGE/context:$IMAGE_TAG
+    - CONTEXTSERVICE_SERVICE_HOST=$(docker inspect context --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
+    - echo $CONTEXTSERVICE_SERVICE_HOST
+
+    # Device preparation
+    - >
+      docker run --name device -d -p 2020:2020
+      --env "CONTEXTSERVICE_SERVICE_HOST=${CONTEXTSERVICE_SERVICE_HOST}"
+      --network=teraflowbridge
+      $CI_REGISTRY_IMAGE/device:$IMAGE_TAG
+    - DEVICESERVICE_SERVICE_HOST=$(docker inspect device --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
+    - echo $DEVICESERVICE_SERVICE_HOST
+
+    # PathComp preparation
+    - >
+      docker run --name pathcomp-backend -d -p 8081:8081
+      --network=teraflowbridge
+      $CI_REGISTRY_IMAGE/pathcomp-backend:$IMAGE_TAG
+    - PATHCOMP_BACKEND_HOST=$(docker inspect pathcomp-backend --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
+    - echo $PATHCOMP_BACKEND_HOST
+    - sleep 1
+    - >
+      docker run --name pathcomp-frontend -d -p 10020:10020
+      --env "CONTEXTSERVICE_SERVICE_HOST=${CONTEXTSERVICE_SERVICE_HOST}"
+      --env "PATHCOMP_BACKEND_HOST=${PATHCOMP_BACKEND_HOST}"
+      --env "PATHCOMP_BACKEND_PORT=8081"
+      --network=teraflowbridge
+      $CI_REGISTRY_IMAGE/pathcomp-frontend:$IMAGE_TAG
+    - sleep 1
+    - PATHCOMPSERVICE_SERVICE_HOST=$(docker inspect pathcomp-frontend --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
+    - echo $PATHCOMPSERVICE_SERVICE_HOST
+
+    # Service preparation
+    - >
+      docker run --name $IMAGE_NAME -d -p 3030:3030
+      --env "CONTEXTSERVICE_SERVICE_HOST=${CONTEXTSERVICE_SERVICE_HOST}"
+      --env "DEVICESERVICE_SERVICE_HOST=${DEVICESERVICE_SERVICE_HOST}"
+      --env "PATHCOMPSERVICE_SERVICE_HOST=${PATHCOMPSERVICE_SERVICE_HOST}"
+      --volume "$PWD/src/$IMAGE_NAME/tests:/opt/results"
+      --network=teraflowbridge
+      $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG
+
+    # Check status before the tests
+    - sleep 5
+    - docker ps -a
+    - docker logs context
+    - docker logs device
+    - docker logs pathcomp-frontend
+    - docker logs pathcomp-backend
+    - docker logs $IMAGE_NAME
+
+    # Run the tests
+    - >
+      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"
+
+  coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  after_script:
+    # Check status after the tests
+    - docker ps -a
+    - docker logs context
+    - docker logs device
+    - docker logs pathcomp-frontend
+    - docker logs pathcomp-backend
+    - docker logs $IMAGE_NAME
+
+    - docker rm -f $IMAGE_NAME
+    - docker rm -f pathcomp-frontend
+    - docker rm -f pathcomp-backend
+    - docker rm -f device
+    - docker rm -f context
+
+    - docker rm -f $IMAGE_NAME crdb nats
+    - docker volume rm -f crdb
+    - docker network rm teraflowbridge
+    - docker volume prune --force
+    - docker image prune --force
+
+  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/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/Dockerfile
+      - src/$IMAGE_NAME/tests/*.py
+      - manifests/${IMAGE_NAME}service.yaml
+      - .gitlab-ci.yml
+
+  artifacts:
+      when: always
+      reports:
+        junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
+
+## Deployment of the service in Kubernetes Cluster
+#deploy service:
+#  variables:
+#    IMAGE_NAME: 'service' # name of the microservice
+#    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+#  stage: deploy
+#  needs:
+#    - unit test service
+#    # - integ_test execute
+#  script:
+#    - 'sed -i "s/$IMAGE_NAME:.*/$IMAGE_NAME:$IMAGE_TAG/" manifests/${IMAGE_NAME}service.yaml'
+#    - kubectl version
+#    - kubectl get all
+#    - kubectl apply -f "manifests/${IMAGE_NAME}service.yaml"
+#    - kubectl get all
+#  # environment:
+#  #   name: test
+#  #   url: https://example.com
+#  #   kubernetes:
+#  #     namespace: test
+#  rules:
+#    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+#      when: manual    
+#    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+#      when: manual
diff --git a/src/pcep/Config.py b/src/pcep/Config.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/pcep/Config.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/pcep/Dockerfile b/src/pcep/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..0229d098d409eb89c27c7cc6efb89e6bf4a3238a
--- /dev/null
+++ b/src/pcep/Dockerfile
@@ -0,0 +1,82 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3.9-slim
+
+# Install dependencies
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install wget g++ && \
+    rm -rf /var/lib/apt/lists/*
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Download the gRPC health probe
+RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
+    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
+    chmod +x /bin/grpc_health_probe
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip
+RUN python3 -m pip install --upgrade setuptools wheel
+RUN python3 -m pip install --upgrade pip-tools
+
+# Install OpenJDK-11
+RUN apt-get update && \
+    apt-get install -y openjdk-11-jre-headless && \
+    apt-get clean;
+
+# Get common Python packages
+# Note: this step enables sharing the previous Docker build steps among all the Python components
+WORKDIR /var/teraflow
+COPY common_requirements.in common_requirements.in
+RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in
+RUN python3 -m pip install -r common_requirements.txt
+
+# Add common files into working directory
+WORKDIR /var/teraflow/common
+COPY src/common/. ./
+RUN rm -rf proto
+
+# Create proto sub-folder, copy .proto files, and generate Python code
+RUN mkdir -p /var/teraflow/common/proto
+WORKDIR /var/teraflow/common/proto
+RUN touch __init__.py
+COPY proto/*.proto ./
+RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto
+RUN rm *.proto
+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/pcep
+WORKDIR /var/teraflow/pcep
+COPY src/pcep/requirements.in requirements.in
+RUN pip-compile --quiet --output-file=requirements.txt requirements.in
+RUN python3 -m pip install -r requirements.txt
+
+# Java module necessary config files
+WORKDIR /var/teraflow/pcep
+RUN mkdir -p /resources
+COPY src/pcep/service/resources/. resources/
+
+# Add component files into working directory
+WORKDIR /var/teraflow
+COPY src/context/. context/
+COPY src/device/. device/
+COPY src/pathcomp/frontend/. pathcomp/frontend/
+COPY src/service/. service/
+COPY src/pcep/. pcep/
+
+# Start the service
+ENTRYPOINT ["python", "-m", "pcep.service"]
diff --git a/src/pcep/__init__.py b/src/pcep/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/pcep/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/pcep/client/PcepClient.py b/src/pcep/client/PcepClient.py
new file mode 100644
index 0000000000000000000000000000000000000000..057844e70b59a59a4bade4572a7f274acfa75dfd
--- /dev/null
+++ b/src/pcep/client/PcepClient.py
@@ -0,0 +1,63 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
+from common.proto.context_pb2 import Empty, Service, ServiceId
+from common.proto.pcep_pb2_grpc import PcepServiceStub
+from common.proto.pcep_pb2 import RequestRq, RequestRp, PceIpRq, PceIpRp
+from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
+
+LOGGER = logging.getLogger(__name__)
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+
+class PcepClient:
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.PCEP)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.PCEP)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
+        LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
+        self.channel = None
+        self.stub = None
+        self.connect()
+        LOGGER.debug('Channel created')
+
+    def connect(self):
+        self.channel = grpc.insecure_channel(self.endpoint)
+        self.stub = PcepServiceStub(self.channel)
+
+    def close(self):
+        if self.channel is not None: self.channel.close()
+        self.channel = None
+        self.stub = None
+
+    @RETRY_DECORATOR
+    def sendRequest(self, request : RequestRq) -> RequestRp:
+        LOGGER.debug('Send request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.sendRequest(request)
+        LOGGER.debug('Send request result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def configuratePCE(self, request : PceIpRq) -> PceIpRp:
+        LOGGER.debug('Configurate PCE: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.configuratePCE(request)
+        LOGGER.debug('Configurate PCE result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+
diff --git a/src/pcep/client/__init__.py b/src/pcep/client/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/pcep/client/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/pcep/requirements.in b/src/pcep/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..bffe88732b108cd5da3bf6331d6a8c3056ccaf02
--- /dev/null
+++ b/src/pcep/requirements.in
@@ -0,0 +1,34 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+anytree==2.8.0
+APScheduler==3.8.1
+#networkx==2.6.3
+#pydot==1.4.2
+#redis==4.1.2
+
+#fastcache==1.1.0
+ncclient==0.6.13
+python-json-logger==2.0.2
+pytz==2021.3
+xmltodict==0.12.0
+
+
+# pip's dependency resolver does not take into account installed packages.
+# p4runtime does not specify the version of grpcio/protobuf it needs, so it tries to install latest one
+# adding here again grpcio==1.47.* and protobuf==3.20.* with explicit versions to prevent collisions
+grpcio==1.47.*
+protobuf==3.20.*
+prometheus_client==0.13.0
\ No newline at end of file
diff --git a/src/pcep/service/PcepService.py b/src/pcep/service/PcepService.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6e9004044a1425f515bab396a43171920a73b23
--- /dev/null
+++ b/src/pcep/service/PcepService.py
@@ -0,0 +1,29 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from pcep.service.tools.GrpcServer import GrpcServer
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.proto.pcep_pb2_grpc import add_PcepServiceServicer_to_server
+from common.tools.service.GenericGrpcService import GenericGrpcService
+from .PcepServiceServicerImpl import PcepServiceServicerImpl
+
+class PcepService(GenericGrpcService):
+    def __init__(self, pcepServer : GrpcServer,cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.PCEP) # El enum en common.constants
+        super().__init__(port, cls_name=cls_name)
+        self.pcep_servicer = PcepServiceServicerImpl(pcepServer)
+
+    def install_servicers(self):
+        add_PcepServiceServicer_to_server(self.pcep_servicer, self.server)
diff --git a/src/pcep/service/PcepServiceServicerImpl.py b/src/pcep/service/PcepServiceServicerImpl.py
new file mode 100644
index 0000000000000000000000000000000000000000..c70a6043f7a675836c5812b8ff00636e82ac4ef6
--- /dev/null
+++ b/src/pcep/service/PcepServiceServicerImpl.py
@@ -0,0 +1,58 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, json, logging
+from typing import Optional
+from pcep.service.tools.GrpcServer import GrpcServer
+from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
+from common.method_wrappers.ServiceExceptions import AlreadyExistsException, InvalidArgumentException
+from common.proto.context_pb2 import (DeviceId, Empty, EndPointId, Link, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, TopologyId,ContextId,Topology
+    ,Device,DeviceDriverEnum, Uuid)
+from common.proto.pathcomp_pb2 import PathCompRequest
+from common.proto.service_pb2_grpc import ServiceServiceServicer
+
+from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from pathcomp.frontend.client.PathCompClient import PathCompClient
+
+from common.proto.pcep_pb2 import (RequestRq, RequestRp, PceIpRq, PceIpRp)
+from common.proto.pcep_pb2_grpc import PcepServiceServicer
+
+# from .task_scheduler.TaskScheduler import TasksScheduler
+# from .tools.ContextGetters import get_service
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool('Service', 'RPC')
+
+class PcepServiceServicerImpl(PcepServiceServicer):
+    def __init__(self, pcepServer : GrpcServer) -> None:
+        LOGGER.debug('Creating Servicer...')
+        self.pcepServer=pcepServer
+        LOGGER.debug('Servicer Created')
+   
+    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+    def configuratePCE(self, request : PceIpRq, context : grpc.ServicerContext) -> PceIpRp:
+
+        LOGGER.debug("(ConfiguratePCE) Create pce instance %s",request)
+
+        configurateIP=self.pcepServer.connectToJavaPcep(request.address)
+        return PceIpRp(addressRp=configurateIP)
+    
+    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+    def sendRequest(self, request : RequestRq, context : grpc.ServicerContext) -> RequestRp:
+        message=self.pcepServer.requestToJavaPcep(request.command)
+
+        return RequestRp(commandRp=message)
+    
diff --git a/src/pcep/service/__init__.py b/src/pcep/service/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/pcep/service/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/pcep/service/__main__.py b/src/pcep/service/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e084fd0a78546c7b4e7602dd3fb5b1f15a5b44e6
--- /dev/null
+++ b/src/pcep/service/__main__.py
@@ -0,0 +1,87 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, signal, sys, threading, time
+from prometheus_client import start_http_server
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
+    wait_for_environment_variables)
+from .PcepService import PcepService
+from .tools.JavaRunner import JavaRunner
+from .tools.GrpcServer import GrpcServer
+
+terminate = threading.Event()
+LOGGER : logging.Logger = None
+
+def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
+    LOGGER.warning('Terminate signal received')
+    LOGGER.warning(signal)
+    terminate.set()
+
+def main():
+    global LOGGER # pylint: disable=global-statement
+
+    log_level = get_log_level()
+    logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
+    LOGGER = logging.getLogger(__name__)
+
+    ###wait_for_environment_variables([
+        ###get_env_var_name(ServiceNameEnum.CONTEXT,  ENVVAR_SUFIX_SERVICE_HOST     ),
+        ###get_env_var_name(ServiceNameEnum.CONTEXT,  ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+        ###get_env_var_name(ServiceNameEnum.DEVICE,   ENVVAR_SUFIX_SERVICE_HOST     ),
+        ###get_env_var_name(ServiceNameEnum.DEVICE,   ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+        ###get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_HOST     ),
+        ###get_env_var_name(ServiceNameEnum.PATHCOMP, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+    ###])
+
+    signal.signal(signal.SIGINT,  signal_handler)
+    signal.signal(signal.SIGTERM, signal_handler)
+
+    LOGGER.info('Starting...')
+
+    # Start metrics server
+    metrics_port = get_metrics_port()
+    start_http_server(metrics_port)
+
+    # Initialize ServiceHandler Factory
+    ###service_handler_factory = ServiceHandlerFactory(SERVICE_HANDLERS)
+
+    #DB=DiscoveredDBManager()
+    
+    pcep_server = GrpcServer()
+    #pcep_server.Connect()
+    
+    pcep_server.connectToJavaPcep("10.95.41.240")
+    time.sleep(30)
+    n = "initiate lsp directo 10.95.86.214 1.1.1.1 1.1.1.3 m1228800 na192.168.3.11-192.168.3.13"
+    pcep_server.requestToJavaPcep(n)
+    
+    # Starting pcep service
+    pcep_service = PcepService(pcep_server)
+    pcep_service.start()
+
+    
+
+    # Wait for Ctrl+C or termination signal
+    while not terminate.wait(timeout=0.1): pass
+    LOGGER.info('Terminating...')
+    pcep_server.terminateGrpcServer()
+    pcep_service.stop()
+
+    LOGGER.info('Bye')
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/pcep/service/resources/BGP4Parameters_2.xml b/src/pcep/service/resources/BGP4Parameters_2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d7a101668f7aff256afd2b236b4d951e554e0a8e
--- /dev/null
+++ b/src/pcep/service/resources/BGP4Parameters_2.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<config>
+	<!-- TCP port where the BGP is listening for incoming bgp4 connections. Optional Parameter. Default value: 179 (BGP Port)  --> 
+	<BGP4Port>22179</BGP4Port>
+	<BGPIdentifier>1.1.1.1</BGPIdentifier>
+<!-- TCP port to connect to manage the BGP connection. Default value: 1112 -->
+	<BGP4ManagementPort>1112</BGP4ManagementPort> 
+	<!-- Peers to which this Peer is going to establish connection -->
+    <configPeer>
+                <peer>localhost</peer>
+                <export>false</export>
+                <import>true</import>
+                <peerPort>11179</peerPort>
+    </configPeer>
+
+	<!-- Ficheros log (servidor, protocolo PCEP y OSPF). Campos opcionales-->
+	<BGP4LogFile>BGP4Parser2.log</BGP4LogFile><!-- Default value: BGP4Parser.log -->
+	<BGP4LogFileClient>BGP4Client2.log</BGP4LogFileClient><!-- Default value: BGP4Client.log-->
+	<BGP4LogFileServer>BGP4Server2.log</BGP4LogFileServer><!-- Default value: BGP4Server.log-->
+	<!-- If the tcp no delay option is used or not. Optional Parameter. Default value: false. -->
+	<nodelay>true</nodelay>
+	<!-- Waiting Time to re-connect to clients. Default value: 6000 ms. -->
+	<delay>40000</delay>
+	<setTraces>true</setTraces>
+	<!-- OPEN Parameters -->
+	<!-- RFC 4271. This 2-octet unsigned integer indicates the number of seconds the sender proposes for the value of the Hold Timer.  
+		Upon receipt of an OPEN message, a BGP speaker MUST calculate the value of the Hold Timer by using the smaller of its configured
+         Hold Time and the Hold Time received in the OPEN message.  The Hold Time MUST be either zero or at least three seconds.  An
+         implementation MAY reject connections on the basis of the Hold Time.  The calculated value indicates the maximum number of
+         seconds that may elapse between the receipt of successive KEEPALIVE and/or UPDATE messages from the sender. -->
+	<holdTime>180</holdTime><!-- Optional Parameter. Default value: 3. -->
+	<!-- RFC 4271. This 1-octet unsigned integer indicates the protocol version number of the message.  The current BGP version number is 4. -->
+	<version>4</version><!-- Optional Parameter. Default value: 4. -->
+	<!-- RFC 4271.  This 2-octet unsigned integer indicates the Autonomous System number of the sender.-->
+	<myAutonomousSystem>1</myAutonomousSystem>
+	<!-- RFC 4271. This 4-octet unsigned integer indicates the BGP Identifier of the sender.  A given BGP speaker sets the value of its BGP
+         Identifier to an IP address that is assigned to that BGP speaker.  The value of the BGP Identifier is determined upon
+         startup and is the same for every local interface and BGP peer. --> 
+	<!--<BGPIdentifier>192.168.1.200</BGPIdentifier> -->
+	<!-- If the peer is in charge of sending its topology (only the interdomain Links) to the other BGP peer it is connected to. Default: false -->
+	<sendTopology>false</sendTopology>
+	<!-- If the peer is in charge of sending its whole topology to the other BGP peer it is connected to. Default: false -->
+	<sendIntradomainLinks>true</sendIntradomainLinks>
+	<!-- Optional Parameter. How to learn the topology. Possibilities: fromXML, fromBGP. Default: fromBGP -->
+	<learnTopology>fromBGP</learnTopology>	
+	<!-- Topology network to read. It is mandatory if and only if learnTopology parameter is fromXML. -->
+	<!--<topologyFile>src/test/resources/network1.xml</topologyFile>-->
+	<!-- Optional Parameter. Instance Identifier for node and link NLRI. See rfc 6549. Default value: 0-->
+	<!--<instanceID>0</instanceID>-->
+	<!-- Optional Parameter. Default value: localhost -->
+	<localBGPAddress>0.0.0.0</localBGPAddress>
+</config>
diff --git a/src/pcep/service/resources/Ejecutable.jar b/src/pcep/service/resources/Ejecutable.jar
new file mode 100644
index 0000000000000000000000000000000000000000..52cd4230167f6e261fbec6384b2c975c9f696c09
Binary files /dev/null and b/src/pcep/service/resources/Ejecutable.jar differ
diff --git a/src/pcep/service/resources/PCEServerConfiguration.xml b/src/pcep/service/resources/PCEServerConfiguration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a48b4c03bc0a512555dba403c2a63432ef65acc2
--- /dev/null
+++ b/src/pcep/service/resources/PCEServerConfiguration.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<config>
+	<PCEServerPort>4189</PCEServerPort>
+	<PCEManagementPort>6666</PCEManagementPort>
+	<!--<LocalPCEAddress>192.168.1.200</LocalPCEAddress>-->
+	<!--<LocalPCEAddress>10.95.40.175</LocalPCEAddress>-->
+	<!--<LocalPCEAddress>127.0.0.1</LocalPCEAddress>-->
+	<LocalPCEAddress>10.95.43.150</LocalPCEAddress>
+	
+	<ConnectTimer>
+	<!-- Connect:  the timer (in seconds) started after having initialized a
+      TCP connection using the PCEP-registered TCP port.  The value of
+      the Connect timer is 60 seconds. -->
+	60
+	</ConnectTimer>
+  <KeepAliveTimer>
+  30
+  </KeepAliveTimer>
+  <DeadTimer>
+  120
+  </DeadTimer>
+	<ConnectMaxRetry>
+	<!-- ConnectMaxRetry:  the maximum number of times the system tries to
+      establish a TCP connection using the PCEP-registered TCP port
+      before going back to the Idle state.  The value of the
+      ConnectMaxRetry is 5.-->
+	  5
+	</ConnectMaxRetry>
+	<OpenWait>
+   <!-- OpenWait:  the timer that corresponds to the amount of time a PCEP
+      peer will wait to receive an Open message from the PCEP peer after
+      the expiration of which the system releases the PCEP resource and
+      goes back to the Idle state.  The OpenWait timer has a fixed value
+      of 60 seconds.-->
+	  60
+	</OpenWait>
+	<KeepWait>
+   <!-- KeepWait:  the timer that corresponds to the amount of time a PCEP
+      peer will wait to receive a Keepalive or a PCErr message from the
+      PCEP peer after the expiration of which the system releases the
+      PCEP resource and goes back to the Idle state.  The KeepWait timer
+      has a fixed value of 60 seconds.-->
+	</KeepWait>
+	<parentPCE>
+		<!-- <parentPCEAddress>10.95.30.29</parentPCEAddress> -->
+		<!-- <parentPCEAddress>2.2.2.2</parentPCEAddress>-->
+		<!--<parentPCEAddress>10.95.30.29</parentPCEAddress> 	-->
+		<!--<parentPCEAddress>10.95.15.126</parentPCEAddress>-->
+		<!-- <parentPCEPort>4172</parentPCEPort> -->
+	</parentPCE>
+	<!-- Ficheros log (servidor, protocolo PCEP y OSPF). Campos opcionales -->
+	<PCEServerLogFile>PCEServer.log</PCEServerLogFile>
+	<PCEPParserLogFile>PCEPParserServer.log</PCEPParserLogFile>
+	<OSPFParserLogFile>OSPFParser.log</OSPFParserLogFile>
+	<isStateful>true</isStateful>
+  <isActive>true</isActive>
+	<PCCRequestsProcessors>1</PCCRequestsProcessors>
+	<ParentPCERequestProcessors>1</ParentPCERequestProcessors>
+	<!--<networkDescriptionFile>networks\Network_8_nodes.xml</networkDescriptionFile>-->
+	<!--<networkDescriptionFile>networks\network_NSFNet.xml</networkDescriptionFile>-->
+	<!--<networkDescriptionFile>/usr/local/nodeConfig/topologia.xml</networkDescriptionFile>-->
+	<networkDescriptionFile>topologia_ifusion.xml</networkDescriptionFile>
+
+	<actingAsBGP4Peer>false</actingAsBGP4Peer>
+	<BGP4File>BGP4Parameters_2.xml</BGP4File>
+
+	<initialSessionID>1000</initialSessionID>
+	<nodelay>true</nodelay>
+	<reservation>false</reservation>
+	<optimizedRead>false</optimizedRead>
+	<analyzeRequestTime>true</analyzeRequestTime>
+	<multilayer>false</multilayer>
+	<setTraces>true</setTraces>
+		 <!--OSPF>
+  		<OSPFSession>true</OSPFSession>
+ 		<OSPFListenerIP>192.168.1.200</OSPFListenerIP>
+  		<OSPFMulticast>true</OSPFMulticast>
+  		<OSPFUnicast>false</OSPFUnicast>
+  		<OSPFTCPSession>false</OSPFTCPSession>
+  		<OSPFTCPPort>7762</OSPFTCPPort>
+ 		</OSPF-->
+	<!--WSON NETWORK-->
+	<!--<layer type="gmpls" default="true" encodingType="1" switchingType="150">77</layer>-->
+	<layer type="mpls" default="true" ></layer>
+  <!--<algorithmRule of="0" svec="false" name="mpls.MPLS_MinTH_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="false"/>-->
+
+	<!--<algorithmRule of="1000" svec="false" name="wson.SP_FF_RWA_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<<algorithmRule of="1002" svec="false" name="sson.AURE_SSON_algorithm" isParentPCEAlgorithm="false" isSSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="998" svec="true" name="wson.svec.SVEC_SP_FF_WSON_PathComputing" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="1100" svec="false" name="multiLayer.Multilayer_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="900" svec="false" name="wson.KSPprecomp_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="1001" svec="false" name="wson.AURE_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="901" svec="false" name="wson.AURE_PACK_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="903" svec="false" name="wson.AURE_RANDOM_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="902" svec="false" name="wson.AURE_SPREAD_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="800" svec="false" name="wson.KSP_FF_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="801" svec="false" name="wson.KSP_PACK_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="803" svec="false" name="wson.KSP_RANDOM_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="802" svec="false" name="wson.KSP_SPREAD_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="900" svec="false" name="wson.AURE_FF_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="1001" svec="false" name="wson.AURE_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="false"/>-->
+	<!--<algorithmRule of="999" svec="true" name="CPLEXOptimizedPathComputing" isParentPCEAlgorithm="false" isWSONAlgorithm="false"/>-->
+	<!-- <layer type="mpls" default="true"/>-->
+	<!--<layer type="mpls" default="true"/>-->
+
+</config>
diff --git a/src/pcep/service/resources/java/generateJar.txt b/src/pcep/service/resources/java/generateJar.txt
new file mode 100644
index 0000000000000000000000000000000000000000..858aa02c7c72745b09020776140c615a92270c1d
--- /dev/null
+++ b/src/pcep/service/resources/java/generateJar.txt
@@ -0,0 +1 @@
+"/home/ubuntu/downloads/apache-maven-3.8.8/bin/mvn" clean package -P pcep assembly:single -DskipTests=True -f "/home/ubuntu/tfs-ctrl/src/pcep/service/resources/java/netphony-pce/pom.xml"
\ No newline at end of file
diff --git a/src/pcep/service/resources/log4j2.xml b/src/pcep/service/resources/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fa4ad59c9e4745a568adbaf76ab34540e73cd7f5
--- /dev/null
+++ b/src/pcep/service/resources/log4j2.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+    <Configuration status="DEBUG">
+      <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+          <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+        </Console>
+      </Appenders>
+      <Loggers>
+        <Logger name="BGP4Peer" level="trace" additivity="false">
+          <AppenderRef ref="Console"/>
+        </Logger>
+        <Root level="DEBUG">
+          <AppenderRef ref="Console"/>
+        </Root>
+      </Loggers>
+    </Configuration>
diff --git a/src/pcep/service/resources/topologia_ifusion.xml b/src/pcep/service/resources/topologia_ifusion.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7c1f9ad3d3d039b2caf04ce7d83d1bf6eae763df
--- /dev/null
+++ b/src/pcep/service/resources/topologia_ifusion.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<network>
+	<domain>
+		<layer type="mpls" ></layer>
+
+		<domain_id>0.0.0.1</domain_id>
+		<reachability_entry>
+			<ipv4_address>1.1.1.0</ipv4_address>
+			<prefix>12</prefix>
+		</reachability_entry>
+
+	  <node>
+			<router_id>1.1.1.1</router_id>
+		</node>
+		<node>
+			<router_id>1.1.1.2</router_id>
+		</node>
+		<node>
+			<router_id>1.1.1.3</router_id>
+		</node>
+
+		<!-- 1 al 2 -->
+		 <edge type="intradomain">
+			<source>
+				<router_id>1.1.1.1</router_id>
+				<NumIf_id>192.168.1.11</NumIf_id>
+			</source>
+			<destination>
+				<router_id>1.1.1.2</router_id>
+				<NumIf_id>192.168.1.12</NumIf_id>
+			</destination>
+			<delay>
+				3.13
+			</delay>
+			<maximum_bandwidth>
+				100
+			</maximum_bandwidth>
+			<unreserved_bandwidth priority="0">
+				100
+			</unreserved_bandwidth>
+		</edge>
+
+    <edge type="intradomain">
+			<source>
+				<router_id>1.1.1.1</router_id>
+				<NumIf_id>192.168.3.11</NumIf_id>
+			</source>
+			<destination>
+				<router_id>1.1.1.3</router_id>
+				<NumIf_id>192.168.3.13</NumIf_id>
+			</destination>
+			<delay>
+				3.13
+			</delay>
+			<maximum_bandwidth>
+				100
+			</maximum_bandwidth>
+			<unreserved_bandwidth priority="0">
+				100
+			</unreserved_bandwidth>
+		</edge>
+
+      <edge type="intradomain">
+			<source>
+				<router_id>1.1.1.3</router_id>
+				<NumIf_id>192.168.2.13</NumIf_id>
+			</source>
+			<destination>
+				<router_id>1.1.1.2</router_id>
+				<NumIf_id>192.168.2.12</NumIf_id>
+			</destination>
+			<delay>
+				3.13
+			</delay>
+			<maximum_bandwidth>
+				100
+			</maximum_bandwidth>
+			<unreserved_bandwidth priority="0">
+				100
+			</unreserved_bandwidth>
+		</edge>
+
+
+	</domain>
+</network>
diff --git a/src/pcep/service/tools/GrpcServer.py b/src/pcep/service/tools/GrpcServer.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e3353cb1930ea92be3b2e0650b60aa3c50e6947
--- /dev/null
+++ b/src/pcep/service/tools/GrpcServer.py
@@ -0,0 +1,200 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json, logging,threading, queue,time,signal
+from datetime import datetime, timedelta
+from typing import Any, Iterator, List, Optional, Tuple, Union
+# from apscheduler.executors.pool import ThreadPoolExecutor
+# from apscheduler.job import Job
+# from apscheduler.jobstores.memory import MemoryJobStore
+# from apscheduler.schedulers.background import BackgroundScheduler
+# from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, metered_subclass_method, INF
+# from common.type_checkers.Checkers import chk_float, chk_length, chk_string, chk_type
+
+
+import logging,threading
+import grpc
+
+from .protos import grpcService_pb2_grpc
+from .protos import grpcService_pb2
+
+from concurrent import futures
+import os
+import subprocess
+from multiprocessing import Pool
+import logging
+
+from .JavaRunner import JavaRunner
+
+LOGGER = logging.getLogger(__name__)
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+SERVER_ADDRESS = 'localhost:2021'
+
+class GrpcServer():
+
+    def __init__(self) -> None: # pylint: disable=super-init-not-called
+        self.__lock = threading.Lock()
+        self.__started = threading.Event()
+        self.__terminate = threading.Event()
+        self.__out_samples = queue.Queue()
+        self.__server=grpc.aio.server()
+        # self.__address="10.95.86.214"
+        # self.__port=179
+        # self.__asNumber=65006
+        # self.__configFile="TMConfiguration_guillermo.xml"
+        # self.__process=0
+        # self.__javaLocalPort=0 # --> BGP4Port in XML file
+        self.__mngPort=0 # Port used in XML config file for management (NOT used in TFS)
+        self.__runnerList=[]
+        # Data base for saving all new devices discovered
+        #self.__discoveredDB=DiscoveredDB
+        # self.__comms=grpcComms
+        # Este tendría que tener la info del runner al que se connecta¿
+    
+    def ConnectThread(self) -> bool:
+        # TODO: Metodos necesarios para conectarte al speaker
+        # If started, assume it is already connected
+        if self.__started.is_set(): return True
+        self.__started.set() #notifyAll -->event.is_set()
+        # 10 workers ?
+        self.__server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+        grpcService_pb2_grpc.add_pceServiceServicer_to_server(self, self.__server)
+        self.__server.add_insecure_port(SERVER_ADDRESS)
+        # server.add_secure_port(SERVER_ADDRESS)
+        LOGGER.info("Starting server on %s", SERVER_ADDRESS)
+        self.__server.start()
+        try:
+            while True:
+                time.sleep(_ONE_DAY_IN_SECONDS)
+        except KeyboardInterrupt:
+            LOGGER.info("DISCONNECT")
+            self.Disconnect()
+        return True
+
+    def Connect(self):
+        grpcThread = threading.Thread(target=self.ConnectThread)
+        grpcThread.start()
+        return True
+
+    def Disconnect(self) -> bool:
+        self.__terminate.set()
+        # If not started, assume it is already disconnected
+        if not self.__started.is_set(): return True
+        LOGGER.info("Keyboard interrupt, stop server")
+        self.__server.stop(0)
+        # Disconnect triggers deactivation of sampling events
+        # self.__scheduler.shutdown()
+        # exit(0)
+        return True
+
+    
+    def update(self,request, context) -> bool:
+        """
+        Processes the messages recived by de grpc server
+        """
+        with self.__lock:
+            #TODO: Get update
+            LOGGER.info("(server) Update message from pcep: \n %s" % (request))
+            response = grpcService_pb2.commandResponse(commandResp="OK")
+            LOGGER.debug("Update class string %s",response.commandResp)
+            return response
+    
+
+
+    #def connectToJavaPcep(self, address : str = "10.95.86.214", port : str = "11179", asNumber : str = "1"):
+    def connectToJavaPcep(self, address):
+        # Get unused* port
+        #self.setLocalPort()
+        #runner = JavaRunner(self.__javaLocalPort,address,self.__mngPort)
+        LOGGER.debug("Ejecutando el servidor java")
+        runner = JavaRunner(address)
+        # Sets port in XML config file for java program
+        #runner.setAsNumber(asNumber)
+        #runner.setPort(port)
+        runner.setPeer()
+        process=runner.execPcep()
+        self.__runnerList.append(runner)
+
+        return process.pid
+    
+    def requestToJavaPcep(self,message):
+        """
+        If java already running add 1 to current used port,
+        else initialize port .
+        initPort --> BGP4Port, usually 179 corresponding to BGP
+        """
+        with grpc.insecure_channel('localhost:10050') as channel:
+            #n = "initiate lsp largo2 10.95.86.214 1.1.1.1 1.1.1.2 m69644288 nn1.1.1.3 m69640192 nn1.1.1.2"
+            #n = "initiate lsp directo 10.95.86.214 1.1.1.1 1.1.1.3 m1228800 na192.168.3.11-192.168.3.13"
+            #n="initiate lsp largo 10.95.86.214 1.1.1.1 1.1.1.3 m61849600 na192.168.1.11-192.168.1.12 m62259200 na192.168.2.12-192.168.2.13"
+            #n = "terminate lsp 10.95.86.214 0 nombre"
+            #n="create candidatepath 10.95.86.214 1.1.1.1 4 97 m69644288 nn1.1.1.3 m69640192 nn1.1.1.2"
+            #n="fallo"
+            #n="quit";
+            LOGGER.debug("LLego al request")
+            stub = grpcService_pb2_grpc.pceServiceStub(channel)
+            LOGGER.debug("LLego al request 2")
+            request = grpcService_pb2.commandRequest(command=message)
+            print("updateService req: %s" ,request)
+            response = stub.update(request)
+            #response=stub.GetCommand(grpcService_pb2.commandRequest(command=n))
+            #response_observer = ResponseObserver()
+            #stub.update(response, response_observer)
+            print("updateServide client received: %s" ,response.commandResp)
+            return response.commandResp
+
+    def terminateRunners(self):
+        for runner in self.__runnerList:
+            runner.endBGPSpeaker()
+        return True
+    
+    def terminateGrpcServer(self):
+        LOGGER.debug("Terminating java programs...")
+        self.terminateRunners()
+        LOGGER.debug("Disconnecting grpc server...")
+        self.Disconnect() 
+        return True
+
+    def terminateRunnerById(self,speaker_id):
+        """
+        Disconnect from BGP-LS speaker given an speaker Id. Its the same
+        as the java running proccess PID.
+        """
+        for runner in self.__runnerList:
+            if(runner.getPid()==speaker_id):
+                runner.endBGPSpeaker()
+                self.__runnerList.remove(runner)
+
+        return True
+        
+    def setLocalPort(self,initPort=22179):
+        """
+        If java already running add 1 to current used port,
+        else initialize port .
+        initPort --> BGP4Port, usually 179 corresponding to BGP
+        """
+        with self.__lock:
+            if(self.__runnerList):
+                LOGGER.debug("Port exists %s",self.__javaLocalPort)
+                lastRunner=self.__runnerList[-1]
+                self.__javaLocalPort=lastRunner.getCurrentLocalPort()+1
+                self.__mngPort=lastRunner.getCurrentMngPort()+1
+            else:
+                LOGGER.debug("Port DONT exists %s",self.__javaLocalPort)
+                self.__javaLocalPort=initPort
+                self.__mngPort=1112 # default management port
+            return self.__javaLocalPort
+        
+    
\ No newline at end of file
diff --git a/src/pcep/service/tools/JavaRunner.py b/src/pcep/service/tools/JavaRunner.py
new file mode 100644
index 0000000000000000000000000000000000000000..1e1cd0314d80d71352253cc6245277b1cadd25bc
--- /dev/null
+++ b/src/pcep/service/tools/JavaRunner.py
@@ -0,0 +1,147 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json, logging,threading, queue,time,signal
+from datetime import datetime, timedelta
+from typing import Any, Iterator, List, Optional, Tuple, Union
+import logging
+import grpc
+
+from concurrent import futures
+from lxml import etree
+import os
+import subprocess
+from multiprocessing import Pool
+
+
+SERVER_ADDRESS = 'localhost:2021'
+SERVER_ID = 1
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+#XML_FILE="/var/teraflow/bgpls_speaker/service/resources/BGP4Parameters_2.xml"
+XML_CONFIG_FILE="/var/teraflow/pcep/resources/PCEServerConfiguration.xml"
+
+LOGGER = logging.getLogger(__name__)
+
+
+class JavaRunner:
+
+    #def __init__(self,localPort : int, address : str ="10.95.86.214", mngPort : int = 1112):
+    def __init__(self,address): 
+        #self.__peerPort=11179
+        #self.__localPort=localPort 
+        #self.__managementPort=mngPort
+        # To support multiple speakers at same time 
+        # Add 1 to port and then pass port to subproccess call
+        #self.__configFile=XML_CONFIG_FILE
+        #self.__process=0
+        self.__lock = threading.Lock()
+        self.__address = address
+        #self.__portConf=6666
+        #self.__pceAddress="10.95.43.16"
+        #self.__asNumber=1
+
+    def getCurrentLocalPort(self):
+        with self.__lock:
+            return self.__localPort
+
+    def getCurrentMngPort(self):
+        with self.__lock:
+            return self.__managementPort
+    def getPid(self):
+        return self.__process.pid
+
+    def execAndKill(self):
+
+        LOGGER.debug("Before exec and kill")
+        os.chdir("/var/teraflow/pcep/service/resources/")
+        cwd = os.getcwd()
+        LOGGER.info("Current working directory: %s", cwd)
+        # Security shell=False
+        self.__process=subprocess.Popen(['java -jar Ejecutable.jar '+ XML_CONFIG_FILE],
+                shell=False,start_new_session=True,stdout=subprocess.PIPE)
+        LOGGER.debug("Time to sleep")
+        java_pid = self.__process.pid
+        print("Java PID:", java_pid)    
+        time.sleep(15)
+        self.__process.terminate()
+
+
+    def execPcep(self) -> bool:
+            """
+            Executes java pcep in non-blocking process
+            """
+            # CHECKEAR muchas cosas
+            LOGGER.debug("Before exec")
+            os.chdir("/var/teraflow/pcep/service/resources/")
+            # Security reasons shell=False
+            self.__process=subprocess.Popen(['java' , '-jar' , 'Ejecutable.jar' , XML_CONFIG_FILE],
+                shell=False,start_new_session=True)
+            return self.__process
+
+    def setPort(self,port):
+         self.__peerPort=port
+         return True
+    def setAsNumber(self,asNumber):
+         self.__asNumber=asNumber
+         return True
+
+    def setPeer(self) -> bool:
+            """
+            Sets XML existing config file with peer address and port. TODO: as_number
+            """
+
+            #XMLParser = etree.XMLParser(remove_blank_text=False)
+            #tree = etree.parse(XML_FILE, parser=XMLParser)
+            #root = tree.getroot()
+            ##peerAddress = root.find(".//peer")
+            ##peerAddress.text=self.__address
+            #peerPort = root.find(".//peerPort")
+            #peerPort.text=str(self.__peerPort)
+            #localPort = root.find(".//BGP4Port")
+            #localPort.text=str(self.__localPort)
+            #myAutonomousSystem = root.find(".//myAutonomousSystem")
+            #myAutonomousSystem.text=str(self.__asNumber)
+            #managePort = root.find(".//BGP4ManagementPort")
+            #managePort.text=str(self.__managementPort)
+            #tree.write(XML_FILE) #with ... as ..
+
+            XMLParser = etree.XMLParser(remove_blank_text=False)
+            tree = etree.parse(XML_CONFIG_FILE, parser=XMLParser)
+            root = tree.getroot()
+            #portConf = root.find(".//PCEManagementPort")
+            #portConf.text=str(self.__portConf)
+            pceAddress = root.find(".//LocalPCEAddress")
+
+            LOGGER.debug("Valor anterior de LocalPCEAddress: %s", pceAddress.text)
+            pceAddress.text=str(self.__address)
+            LOGGER.debug("Valor posterior de LocalPCEAddress: %s", pceAddress.text)          
+            tree.write(XML_CONFIG_FILE)
+            return True
+
+    def endBGPSpeaker(self) -> bool:
+            """
+            Kills java program connected to BGPLS Speaker with SIGKILL signal
+            """
+            LOGGER.debug("sending kill signal to process %s",self.__process.pid)
+            # time.sleep(15)
+            LOGGER.debug("PID: %d",self.__process.pid)
+            # LOGGER.debug("Group PID: %d",os.getpgid(self.__process.pid))
+            # os.killpg(os.getpgid(self.__process.pid), signal.SIGKILL)
+            self.__process.kill()
+            # .terminate() for SIGTERM
+            return True
+    
+    def getRunnerInfo(self):
+         return self.__address,self.__asNumber,self.__peerPort
\ No newline at end of file
diff --git a/src/pcep/service/tools/PCEServerConfiguration.xml b/src/pcep/service/tools/PCEServerConfiguration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a48b4c03bc0a512555dba403c2a63432ef65acc2
--- /dev/null
+++ b/src/pcep/service/tools/PCEServerConfiguration.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<config>
+	<PCEServerPort>4189</PCEServerPort>
+	<PCEManagementPort>6666</PCEManagementPort>
+	<!--<LocalPCEAddress>192.168.1.200</LocalPCEAddress>-->
+	<!--<LocalPCEAddress>10.95.40.175</LocalPCEAddress>-->
+	<!--<LocalPCEAddress>127.0.0.1</LocalPCEAddress>-->
+	<LocalPCEAddress>10.95.43.150</LocalPCEAddress>
+	
+	<ConnectTimer>
+	<!-- Connect:  the timer (in seconds) started after having initialized a
+      TCP connection using the PCEP-registered TCP port.  The value of
+      the Connect timer is 60 seconds. -->
+	60
+	</ConnectTimer>
+  <KeepAliveTimer>
+  30
+  </KeepAliveTimer>
+  <DeadTimer>
+  120
+  </DeadTimer>
+	<ConnectMaxRetry>
+	<!-- ConnectMaxRetry:  the maximum number of times the system tries to
+      establish a TCP connection using the PCEP-registered TCP port
+      before going back to the Idle state.  The value of the
+      ConnectMaxRetry is 5.-->
+	  5
+	</ConnectMaxRetry>
+	<OpenWait>
+   <!-- OpenWait:  the timer that corresponds to the amount of time a PCEP
+      peer will wait to receive an Open message from the PCEP peer after
+      the expiration of which the system releases the PCEP resource and
+      goes back to the Idle state.  The OpenWait timer has a fixed value
+      of 60 seconds.-->
+	  60
+	</OpenWait>
+	<KeepWait>
+   <!-- KeepWait:  the timer that corresponds to the amount of time a PCEP
+      peer will wait to receive a Keepalive or a PCErr message from the
+      PCEP peer after the expiration of which the system releases the
+      PCEP resource and goes back to the Idle state.  The KeepWait timer
+      has a fixed value of 60 seconds.-->
+	</KeepWait>
+	<parentPCE>
+		<!-- <parentPCEAddress>10.95.30.29</parentPCEAddress> -->
+		<!-- <parentPCEAddress>2.2.2.2</parentPCEAddress>-->
+		<!--<parentPCEAddress>10.95.30.29</parentPCEAddress> 	-->
+		<!--<parentPCEAddress>10.95.15.126</parentPCEAddress>-->
+		<!-- <parentPCEPort>4172</parentPCEPort> -->
+	</parentPCE>
+	<!-- Ficheros log (servidor, protocolo PCEP y OSPF). Campos opcionales -->
+	<PCEServerLogFile>PCEServer.log</PCEServerLogFile>
+	<PCEPParserLogFile>PCEPParserServer.log</PCEPParserLogFile>
+	<OSPFParserLogFile>OSPFParser.log</OSPFParserLogFile>
+	<isStateful>true</isStateful>
+  <isActive>true</isActive>
+	<PCCRequestsProcessors>1</PCCRequestsProcessors>
+	<ParentPCERequestProcessors>1</ParentPCERequestProcessors>
+	<!--<networkDescriptionFile>networks\Network_8_nodes.xml</networkDescriptionFile>-->
+	<!--<networkDescriptionFile>networks\network_NSFNet.xml</networkDescriptionFile>-->
+	<!--<networkDescriptionFile>/usr/local/nodeConfig/topologia.xml</networkDescriptionFile>-->
+	<networkDescriptionFile>topologia_ifusion.xml</networkDescriptionFile>
+
+	<actingAsBGP4Peer>false</actingAsBGP4Peer>
+	<BGP4File>BGP4Parameters_2.xml</BGP4File>
+
+	<initialSessionID>1000</initialSessionID>
+	<nodelay>true</nodelay>
+	<reservation>false</reservation>
+	<optimizedRead>false</optimizedRead>
+	<analyzeRequestTime>true</analyzeRequestTime>
+	<multilayer>false</multilayer>
+	<setTraces>true</setTraces>
+		 <!--OSPF>
+  		<OSPFSession>true</OSPFSession>
+ 		<OSPFListenerIP>192.168.1.200</OSPFListenerIP>
+  		<OSPFMulticast>true</OSPFMulticast>
+  		<OSPFUnicast>false</OSPFUnicast>
+  		<OSPFTCPSession>false</OSPFTCPSession>
+  		<OSPFTCPPort>7762</OSPFTCPPort>
+ 		</OSPF-->
+	<!--WSON NETWORK-->
+	<!--<layer type="gmpls" default="true" encodingType="1" switchingType="150">77</layer>-->
+	<layer type="mpls" default="true" ></layer>
+  <!--<algorithmRule of="0" svec="false" name="mpls.MPLS_MinTH_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="false"/>-->
+
+	<!--<algorithmRule of="1000" svec="false" name="wson.SP_FF_RWA_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<<algorithmRule of="1002" svec="false" name="sson.AURE_SSON_algorithm" isParentPCEAlgorithm="false" isSSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="998" svec="true" name="wson.svec.SVEC_SP_FF_WSON_PathComputing" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="1100" svec="false" name="multiLayer.Multilayer_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="900" svec="false" name="wson.KSPprecomp_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="1001" svec="false" name="wson.AURE_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="901" svec="false" name="wson.AURE_PACK_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="903" svec="false" name="wson.AURE_RANDOM_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="902" svec="false" name="wson.AURE_SPREAD_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="800" svec="false" name="wson.KSP_FF_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="801" svec="false" name="wson.KSP_PACK_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+	<!--<algorithmRule of="803" svec="false" name="wson.KSP_RANDOM_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="802" svec="false" name="wson.KSP_SPREAD_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="900" svec="false" name="wson.AURE_FF_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="true"/>-->
+
+	<!--<algorithmRule of="1001" svec="false" name="wson.AURE_Algorithm" isParentPCEAlgorithm="false" isWSONAlgorithm="false"/>-->
+	<!--<algorithmRule of="999" svec="true" name="CPLEXOptimizedPathComputing" isParentPCEAlgorithm="false" isWSONAlgorithm="false"/>-->
+	<!-- <layer type="mpls" default="true"/>-->
+	<!--<layer type="mpls" default="true"/>-->
+
+</config>
diff --git a/src/pcep/service/tools/__init__.py b/src/pcep/service/tools/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/pcep/service/tools/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/pcep/service/tools/protos/grpcService.proto b/src/pcep/service/tools/protos/grpcService.proto
new file mode 100644
index 0000000000000000000000000000000000000000..fc5a6e852c6b46b31a2348fdb678ec43b349ff70
--- /dev/null
+++ b/src/pcep/service/tools/protos/grpcService.proto
@@ -0,0 +1,20 @@
+syntax = "proto3";
+package src.main.proto;
+
+//el modulo java abre la comunicacion
+//cliente(java) manda la info al servidor(python)
+//el modulo en python responde con ok
+
+message commandRequest{
+	string command = 1;
+}
+
+message commandResponse{
+	string commandResp = 1;
+}
+
+// Defining a Service, a Service can have multiple RPC operations
+service pceService {
+  // MODIFY HERE: Update the return to streaming return.
+  rpc update(commandRequest) returns (commandResponse);
+}
\ No newline at end of file
diff --git a/src/pcep/service/tools/protos/grpcService_pb2.py b/src/pcep/service/tools/protos/grpcService_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..e6b1f576d914cdda8be1dd5ff18c95b46c43c828
--- /dev/null
+++ b/src/pcep/service/tools/protos/grpcService_pb2.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: grpcService.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11grpcService.proto\x12\x0esrc.main.proto\"!\n\x0e\x63ommandRequest\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\"&\n\x0f\x63ommandResponse\x12\x13\n\x0b\x63ommandResp\x18\x01 \x01(\t2W\n\npceService\x12I\n\x06update\x12\x1e.src.main.proto.commandRequest\x1a\x1f.src.main.proto.commandResponseb\x06proto3')
+
+
+
+_COMMANDREQUEST = DESCRIPTOR.message_types_by_name['commandRequest']
+_COMMANDRESPONSE = DESCRIPTOR.message_types_by_name['commandResponse']
+commandRequest = _reflection.GeneratedProtocolMessageType('commandRequest', (_message.Message,), {
+  'DESCRIPTOR' : _COMMANDREQUEST,
+  '__module__' : 'grpcService_pb2'
+  # @@protoc_insertion_point(class_scope:src.main.proto.commandRequest)
+  })
+_sym_db.RegisterMessage(commandRequest)
+
+commandResponse = _reflection.GeneratedProtocolMessageType('commandResponse', (_message.Message,), {
+  'DESCRIPTOR' : _COMMANDRESPONSE,
+  '__module__' : 'grpcService_pb2'
+  # @@protoc_insertion_point(class_scope:src.main.proto.commandResponse)
+  })
+_sym_db.RegisterMessage(commandResponse)
+
+_PCESERVICE = DESCRIPTOR.services_by_name['pceService']
+if _descriptor._USE_C_DESCRIPTORS == False:
+
+  DESCRIPTOR._options = None
+  _COMMANDREQUEST._serialized_start=37
+  _COMMANDREQUEST._serialized_end=70
+  _COMMANDRESPONSE._serialized_start=72
+  _COMMANDRESPONSE._serialized_end=110
+  _PCESERVICE._serialized_start=112
+  _PCESERVICE._serialized_end=199
+# @@protoc_insertion_point(module_scope)
diff --git a/src/pcep/service/tools/protos/grpcService_pb2_grpc.py b/src/pcep/service/tools/protos/grpcService_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..8458247c26fd176da3a307c4aac1fea3bcd067f4
--- /dev/null
+++ b/src/pcep/service/tools/protos/grpcService_pb2_grpc.py
@@ -0,0 +1,70 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from . import grpcService_pb2 as grpcService__pb2
+
+
+class pceServiceStub(object):
+    """Defining a Service, a Service can have multiple RPC operations
+    """
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.update = channel.unary_unary(
+                '/src.main.proto.pceService/update',
+                request_serializer=grpcService__pb2.commandRequest.SerializeToString,
+                response_deserializer=grpcService__pb2.commandResponse.FromString,
+                )
+
+
+class pceServiceServicer(object):
+    """Defining a Service, a Service can have multiple RPC operations
+    """
+
+    def update(self, request, context):
+        """MODIFY HERE: Update the return to streaming return.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_pceServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'update': grpc.unary_unary_rpc_method_handler(
+                    servicer.update,
+                    request_deserializer=grpcService__pb2.commandRequest.FromString,
+                    response_serializer=grpcService__pb2.commandResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'src.main.proto.pceService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class pceService(object):
+    """Defining a Service, a Service can have multiple RPC operations
+    """
+
+    @staticmethod
+    def update(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/src.main.proto.pceService/update',
+            grpcService__pb2.commandRequest.SerializeToString,
+            grpcService__pb2.commandResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/pcep/tests/.gitignore b/src/pcep/tests/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6b97d6fe3ad32f39097745229ab7f547f26ecb12
--- /dev/null
+++ b/src/pcep/tests/.gitignore
@@ -0,0 +1 @@
+# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
diff --git a/src/pcep/tests/__init__.py b/src/pcep/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/pcep/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+