diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0c3626b2f576dae2135de2030c01ada133aa89d7..095e542dfa8c5eca947a2931e6a9348aef70d838 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -35,12 +35,13 @@ include:
- local: '/src/ztp/.gitlab-ci.yml'
- local: '/src/policy/.gitlab-ci.yml'
- local: '/src/forecaster/.gitlab-ci.yml'
- #- local: '/src/webui/.gitlab-ci.yml'
+ - local: '/src/webui/.gitlab-ci.yml'
#- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml'
#- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml'
#- local: '/src/l3_attackmitigator/.gitlab-ci.yml'
- #- local: '/src/slice/.gitlab-ci.yml'
+ - local: '/src/slice/.gitlab-ci.yml'
#- local: '/src/interdomain/.gitlab-ci.yml'
- local: '/src/pathcomp/.gitlab-ci.yml'
#- local: '/src/dlt/.gitlab-ci.yml'
- local: '/src/load_generator/.gitlab-ci.yml'
+ - local: '/src/bgpls_speaker/.gitlab-ci.yml'
diff --git a/manifests/bgpls_speakerservice.yaml b/manifests/bgpls_speakerservice.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..aa985d13ea81ad5f5aafdee4b62ca1c54915e527
--- /dev/null
+++ b/manifests/bgpls_speakerservice.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: bgpls-speakerservice
+spec:
+ selector:
+ matchLabels:
+ app: bgpls-speakerservice
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: bgpls-speakerservice
+ spec:
+ terminationGracePeriodSeconds: 5
+ containers:
+ - name: server
+ image: localhost:32000/tfs/bgpls_speaker:dev
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 20030
+ - containerPort: 9192
+ env:
+ - name: LOG_LEVEL
+ value: "INFO"
+ readinessProbe:
+ exec:
+ command: ["/bin/grpc_health_probe", "-addr=:20030"]
+ livenessProbe:
+ exec:
+ command: ["/bin/grpc_health_probe", "-addr=:20030"]
+ resources:
+ requests:
+ cpu: 250m
+ memory: 128Mi
+ limits:
+ cpu: 1000m
+ memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: bgpls-speakerservice
+ labels:
+ app: bgpls-speakerservice
+spec:
+ type: ClusterIP
+ selector:
+ app: bgpls-speakerservice
+ ports:
+ - name: grpc
+ protocol: TCP
+ port: 20030
+ targetPort: 20030
+ - name: metrics
+ protocol: TCP
+ port: 9192
+ targetPort: 9192
diff --git a/my_deploy.sh b/my_deploy.sh
index 0fcb51f90509732452620126c9062597a17735ed..0c5ba03c5b9f63038a622f44ab2dfaaf1e7e6ada 100755
--- a/my_deploy.sh
+++ b/my_deploy.sh
@@ -25,6 +25,9 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_gene
# Uncomment to activate Monitoring
#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"
+# Uncomment to activate bgpls_speaker
+#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker"
+
# Uncomment to activate ZTP
#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp"
diff --git a/proto/bgpls.proto b/proto/bgpls.proto
new file mode 100644
index 0000000000000000000000000000000000000000..9b6f1efab8e3fbd2d913d1b44ac87b78bf46d6eb
--- /dev/null
+++ b/proto/bgpls.proto
@@ -0,0 +1,70 @@
+// 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 bgpls;
+
+import "context.proto";
+
+service BgplsService {
+ rpc ListDiscoveredDevices (context.Empty ) returns (DiscoveredDeviceList) {}
+ rpc ListDiscoveredLinks (context.Empty ) returns (DiscoveredLinkList ) {}
+ rpc AddBgplsSpeaker (BgplsSpeaker ) returns (BgplsSpeakerId ) {}
+ rpc ListBgplsSpeakers (context.Empty ) returns (BgplsSpeakerList ) {}
+ rpc DisconnectFromSpeaker (BgplsSpeaker ) returns (context.Empty ) {}
+ rpc GetSpeakerInfoFromId (BgplsSpeakerId ) returns (BgplsSpeaker ) {}
+ rpc NotifyAddNodeToContext(NodeDescriptors) returns (context.Empty ) {}
+}
+
+message DiscoveredDevice {
+ string nodeName = 1;
+ string ip = 2;
+ string igpID = 3;
+ string learntFrom = 4;
+}
+
+message DiscoveredDeviceList {
+ repeated DiscoveredDevice discovereddevices = 1;
+}
+
+message DiscoveredLinkList{
+ repeated DiscoveredLink discoveredlinks = 1;
+}
+
+message DiscoveredLink{
+ NodeDescriptors local = 1;
+ NodeDescriptors remote = 2;
+ string learntFrom = 3;
+ string local_ipv4 = 4;
+ string remote_ipv4 = 5;
+}
+
+message NodeDescriptors{
+ string asNumber = 1;
+ string igp_id = 2;
+ string nodeName = 3;
+}
+
+message BgplsSpeaker{
+ string address = 1;
+ string port = 2;
+ string asNumber = 3;
+}
+message BgplsSpeakerId{
+ uint32 id = 1;
+}
+
+message BgplsSpeakerList{
+ repeated BgplsSpeakerId speakers = 1;
+}
diff --git a/scripts/show_logs_bgp.sh b/scripts/show_logs_bgp.sh
new file mode 100755
index 0000000000000000000000000000000000000000..29e8fa60c4768d1a0638556f9b68d4ab63dc9c22
--- /dev/null
+++ b/scripts/show_logs_bgp.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# If not already set, set the name of the Kubernetes namespace to deploy to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/bgpls_speakerservice -c server
diff --git a/src/bgpls_speaker/.gitlab-ci.yml b/src/bgpls_speaker/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..68b04f8e7d12812c3d19a269a00d5337874d7762
--- /dev/null
+++ b/src/bgpls_speaker/.gitlab-ci.yml
@@ -0,0 +1,105 @@
+# 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 bgpls_speaker:
+ variables:
+ IMAGE_NAME: 'bgpls_speaker' # 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 bgpls_speaker:
+ variables:
+ IMAGE_NAME: 'bgpls_speaker' # name of the microservice
+ IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+ stage: unit_test
+ needs:
+ - build bgpls_speaker
+ 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
+ - if docker container ls | grep $IMAGE_NAME; then docker rm -f $IMAGE_NAME; else echo "$IMAGE_NAME image is not in the system"; fi
+ script:
+ - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+ - docker run --name $IMAGE_NAME -d -p 20030:20030 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG
+ - sleep 5
+ - docker ps -a
+ - docker logs $IMAGE_NAME
+ - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
+ - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
+ coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+ after_script:
+ - docker rm -f $IMAGE_NAME
+ - 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/**/*.{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 bgpls_speaker:
+# variables:
+# IMAGE_NAME: 'bgpls_speaker' # name of the microservice
+# IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+# stage: deploy
+# needs:
+# - unit test bgpls_speaker
+# # - 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/bgpls_speaker/Config.py b/src/bgpls_speaker/Config.py
new file mode 100644
index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf
--- /dev/null
+++ b/src/bgpls_speaker/Config.py
@@ -0,0 +1,13 @@
+# 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/bgpls_speaker/Dockerfile b/src/bgpls_speaker/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..87463943af647188791e5d162b2af416df867285
--- /dev/null
+++ b/src/bgpls_speaker/Dockerfile
@@ -0,0 +1,110 @@
+# 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.
+
+#
+# Maven install stage
+#
+# ----------------------------------------------
+# FROM alpine/git:latest AS repo
+
+# WORKDIR /usr/src/app
+# RUN git clone https://github.com/telefonicaid/netphony-network-protocols.git .
+
+FROM maven:3.8.8-eclipse-temurin-17 AS build
+
+WORKDIR /
+COPY src/bgpls_speaker/service/java/netphony-topology/ netphony-topology/
+COPY src/bgpls_speaker/service/java/netphony-topology/pom.xml netphony-topology/pom.xml
+
+WORKDIR /netphony-topology/
+RUN mvn clean compile -DskipTests -X
+RUN mvn package assembly:single -P bgp-ls-speaker -DskipTests
+WORKDIR /netphony-topology/target/
+# ENTRYPOINT [ "ls" ,"-a"]
+# -------------------------------------------
+# jar created in /netphony-topology/target/bgp-ls-speaker-jar-with-dependencies.jar
+
+#
+# Stage 2
+#
+
+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-17-jre && \
+ 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/bgpls_speaker
+WORKDIR /var/teraflow/bgpls_speaker
+COPY src/bgpls_speaker/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/bgpls_speaker
+RUN mkdir -p /java
+COPY src/bgpls_speaker/service/java/* /java/
+COPY --from=build /netphony-topology/target/bgp-ls-speaker-jar-with-dependencies.jar /var/teraflow/bgpls_speaker/service/java/bgp_ls.jar
+
+# Add component files into working directory
+WORKDIR /var/teraflow
+COPY src/context/__init__.py context/__init__.py
+COPY src/context/client/. context/client/
+COPY src/bgpls_speaker/. bgpls_speaker/
+
+# Start the service
+ENTRYPOINT ["python", "-m", "bgpls_speaker.service"]
+# ENTRYPOINT [ "ls","-R" ]
\ No newline at end of file
diff --git a/src/bgpls_speaker/__init__.py b/src/bgpls_speaker/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf
--- /dev/null
+++ b/src/bgpls_speaker/__init__.py
@@ -0,0 +1,13 @@
+# 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/bgpls_speaker/client/BgplsClient.py b/src/bgpls_speaker/client/BgplsClient.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc8ecf4ecaa10076e673e42069c5d8c2033cd309
--- /dev/null
+++ b/src/bgpls_speaker/client/BgplsClient.py
@@ -0,0 +1,91 @@
+# 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.service_pb2_grpc import ServiceServiceStub
+from common.proto.bgpls_pb2_grpc import BgplsServiceStub
+from common.proto.bgpls_pb2 import BgplsSpeaker, DiscoveredDeviceList,DiscoveredLinkList,BgplsSpeakerId, NodeDescriptors
+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 BgplsClient:
+ def __init__(self, host=None, port=None):
+ if not host: host = get_service_host(ServiceNameEnum.BGPLS)
+ if not port: port = get_service_port_grpc(ServiceNameEnum.BGPLS)
+ self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
+ LOGGER.info('Creating channel to {:s}...'.format(str(self.endpoint)))
+ self.channel = None
+ self.stub = None
+ self.connect()
+ LOGGER.info('Channel created')
+
+ def connect(self):
+ self.channel = grpc.insecure_channel(self.endpoint)
+ self.stub = BgplsServiceStub(self.channel)
+
+ def close(self):
+ if self.channel is not None: self.channel.close()
+ self.channel = None
+ self.stub = None
+
+ @RETRY_DECORATOR
+ def ListDiscoveredDevices(self, request: Empty) -> DiscoveredDeviceList:
+ LOGGER.info('ListDiscoveredDevices request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.ListDiscoveredDevices(request)
+ LOGGER.info('ListDiscoveredDevices result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
+ @RETRY_DECORATOR
+ def ListDiscoveredLinks(self, request: Empty) -> DiscoveredLinkList:
+ LOGGER.info('ListDiscoveredDevices request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.ListDiscoveredLinks(request)
+ LOGGER.info('ListDiscoveredDevices result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
+ @RETRY_DECORATOR
+ def AddBgplsSpeaker(self, request: BgplsSpeaker) -> str:
+ LOGGER.info('AddBgplsSpeaker request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.AddBgplsSpeaker(request)
+ LOGGER.info('AddBgplsSpeaker result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
+ @RETRY_DECORATOR
+ def ListBgplsSpeakers(self, request: Empty) -> BgplsSpeakerId:
+ LOGGER.info('ListBgplsSpeakers request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.ListBgplsSpeakers(request)
+ LOGGER.info('ListBgplsSpeakers result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
+ @RETRY_DECORATOR
+ def DisconnectFromSpeaker(self, request: BgplsSpeaker) -> bool:
+ LOGGER.info('DisconnectFromSpeaker request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.DisconnectFromSpeaker(request)
+ LOGGER.info('DisconnectFromSpeaker result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
+ @RETRY_DECORATOR
+ def GetSpeakerInfoFromId(self, request: BgplsSpeakerId) -> BgplsSpeaker:
+ LOGGER.info('GetSpeakerInfoFromId request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.GetSpeakerInfoFromId(request)
+ LOGGER.info('GetSpeakerInfoFromId result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
+ @RETRY_DECORATOR
+ def NotifyAddNodeToContext(self, request: NodeDescriptors) -> str:
+ LOGGER.info('NotifyAddNodeToContext request: {:s}'.format(grpc_message_to_json_string(request)))
+ response = self.stub.NotifyAddNodeToContext(request)
+ LOGGER.info('NotifyAddNodeToContext result: {:s}'.format(grpc_message_to_json_string(response)))
+ return response
diff --git a/src/bgpls_speaker/client/__init__.py b/src/bgpls_speaker/client/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..38d04994fb0fa1951fb465bc127eb72659dc2eaf
--- /dev/null
+++ b/src/bgpls_speaker/client/__init__.py
@@ -0,0 +1,13 @@
+# 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/bgpls_speaker/quick_deploy.sh b/src/bgpls_speaker/quick_deploy.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7276f3287d6523d35ce99362963c6f45dfde911c
--- /dev/null
+++ b/src/bgpls_speaker/quick_deploy.sh
@@ -0,0 +1,438 @@
+#!/bin/bash
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+########################################################################################################################
+# Read deployment settings
+########################################################################################################################
+
+
+# ----- TeraFlowSDN ------------------------------------------------------------
+
+# If not already set, set the URL of the Docker registry where the images will be uploaded to.
+# By default, assume internal MicroK8s registry is used.
+export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"}
+
+# If not already set, set the list of components, separated by spaces, you want to build images for, and deploy.
+# By default, only basic components are deployed
+export TFS_COMPONENTS=${TFS_COMPONENTS:-"context device pathcomp service slice nbi webui load_generator bgpls_speaker"}
+
+# If not already set, set the tag you want to use for your images.
+export TFS_IMAGE_TAG=${TFS_IMAGE_TAG:-"dev"}
+
+# If not already set, set the name of the Kubernetes namespace to deploy TFS to.
+export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"}
+
+# If not already set, set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS=${TFS_EXTRA_MANIFESTS:-""}
+
+# If not already set, set the new Grafana admin password
+export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"}
+
+# If not already set, disable skip-build flag to rebuild the Docker images.
+# If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used.
+export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-"YES"}
+
+# If TFS_SKIP_BUILD is "YES", select the containers to be build
+# Any other container will use previous docker images
+export TFS_QUICK_COMPONENTS="bgpls_speaker"
+
+# ----- CockroachDB ------------------------------------------------------------
+
+# If not already set, set the namespace where CockroackDB will be deployed.
+export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"}
+
+# If not already set, set the database username to be used by Context.
+export CRDB_USERNAME=${CRDB_USERNAME:-"tfs"}
+
+# If not already set, set the database user's password to be used by Context.
+export CRDB_PASSWORD=${CRDB_PASSWORD:-"tfs123"}
+
+# If not already set, set the database name to be used by Context.
+export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"}
+
+
+# ----- NATS -------------------------------------------------------------------
+
+# If not already set, set the namespace where NATS will be deployed.
+export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"}
+
+
+# ----- QuestDB ----------------------------------------------------------------
+
+# If not already set, set the namespace where QuestDB will be deployed.
+export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"}
+
+# If not already set, set the database username to be used for QuestDB.
+export QDB_USERNAME=${QDB_USERNAME:-"admin"}
+
+# If not already set, set the database user's password to be used for QuestDB.
+export QDB_PASSWORD=${QDB_PASSWORD:-"quest"}
+
+# If not already set, set the table name to be used by Monitoring for KPIs.
+export QDB_TABLE_MONITORING_KPIS=${QDB_TABLE_MONITORING_KPIS:-"tfs_monitoring_kpis"}
+
+# If not already set, set the table name to be used by Slice for plotting groups.
+export QDB_TABLE_SLICE_GROUPS=${QDB_TABLE_SLICE_GROUPS:-"tfs_slice_groups"}
+
+
+########################################################################################################################
+# Automated steps start here
+########################################################################################################################
+
+# Constants
+GITLAB_REPO_URL="labs.etsi.org:5050/tfs/controller"
+TMP_FOLDER="./tmp"
+
+# Create a tmp folder for files modified during the deployment
+TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests"
+mkdir -p $TMP_MANIFESTS_FOLDER
+TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
+mkdir -p $TMP_LOGS_FOLDER
+
+echo "Deleting and Creating a new namespace..."
+kubectl delete namespace $TFS_K8S_NAMESPACE --ignore-not-found
+kubectl create namespace $TFS_K8S_NAMESPACE
+printf "\n"
+
+echo "Create secret with CockroachDB data"
+CRDB_SQL_PORT=$(kubectl --namespace ${CRDB_NAMESPACE} get service cockroachdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}')
+kubectl create secret generic crdb-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \
+ --from-literal=CRDB_NAMESPACE=${CRDB_NAMESPACE} \
+ --from-literal=CRDB_SQL_PORT=${CRDB_SQL_PORT} \
+ --from-literal=CRDB_DATABASE=${CRDB_DATABASE} \
+ --from-literal=CRDB_USERNAME=${CRDB_USERNAME} \
+ --from-literal=CRDB_PASSWORD=${CRDB_PASSWORD} \
+ --from-literal=CRDB_SSLMODE=require
+printf "\n"
+
+echo "Create secret with NATS data"
+NATS_CLIENT_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service nats -o 'jsonpath={.spec.ports[?(@.name=="client")].port}')
+kubectl create secret generic nats-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \
+ --from-literal=NATS_NAMESPACE=${NATS_NAMESPACE} \
+ --from-literal=NATS_CLIENT_PORT=${NATS_CLIENT_PORT}
+printf "\n"
+
+echo "Create secret with QuestDB data"
+QDB_HTTP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}')
+QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}')
+QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}')
+METRICSDB_HOSTNAME="questdb-public.${QDB_NAMESPACE}.svc.cluster.local"
+kubectl create secret generic qdb-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \
+ --from-literal=QDB_NAMESPACE=${QDB_NAMESPACE} \
+ --from-literal=METRICSDB_HOSTNAME=${METRICSDB_HOSTNAME} \
+ --from-literal=METRICSDB_REST_PORT=${QDB_HTTP_PORT} \
+ --from-literal=METRICSDB_ILP_PORT=${QDB_ILP_PORT} \
+ --from-literal=METRICSDB_SQL_PORT=${QDB_SQL_PORT} \
+ --from-literal=METRICSDB_TABLE_MONITORING_KPIS=${QDB_TABLE_MONITORING_KPIS} \
+ --from-literal=METRICSDB_TABLE_SLICE_GROUPS=${QDB_TABLE_SLICE_GROUPS} \
+ --from-literal=METRICSDB_USERNAME=${QDB_USERNAME} \
+ --from-literal=METRICSDB_PASSWORD=${QDB_PASSWORD}
+printf "\n"
+
+echo "Deploying components and collecting environment variables..."
+ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh
+echo "# Environment variables for TeraFlowSDN deployment" > $ENV_VARS_SCRIPT
+PYTHONPATH=$(pwd)/src
+echo "export PYTHONPATH=${PYTHONPATH}" >> $ENV_VARS_SCRIPT
+
+for COMPONENT in $TFS_COMPONENTS; do
+ echo "Processing '$COMPONENT' component..."
+
+ if [ "$TFS_SKIP_BUILD" != "YES" ]; then
+ echo " Building Docker image..."
+ BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log"
+
+ if [ "$COMPONENT" == "automation" ] || [ "$COMPONENT" == "policy" ]; then
+ docker build -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
+ elif [ "$COMPONENT" == "pathcomp" ]; then
+ BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-frontend.log"
+ docker build -t "$COMPONENT-frontend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/frontend/Dockerfile . > "$BUILD_LOG"
+
+ BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-backend.log"
+ docker build -t "$COMPONENT-backend:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/backend/Dockerfile . > "$BUILD_LOG"
+ # next command is redundant, but helpful to keep cache updated between rebuilds
+ IMAGE_NAME="$COMPONENT-backend:$TFS_IMAGE_TAG-builder"
+ docker build -t "$IMAGE_NAME" --target builder -f ./src/"$COMPONENT"/backend/Dockerfile . >> "$BUILD_LOG"
+ elif [ "$COMPONENT" == "dlt" ]; then
+ BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-connector.log"
+ docker build -t "$COMPONENT-connector:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/connector/Dockerfile . > "$BUILD_LOG"
+
+ BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}-gateway.log"
+ docker build -t "$COMPONENT-gateway:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/gateway/Dockerfile . > "$BUILD_LOG"
+ else
+ docker build -t "$COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$COMPONENT"/Dockerfile . > "$BUILD_LOG"
+ fi
+
+ echo " Pushing Docker image to '$TFS_REGISTRY_IMAGES'..."
+
+ if [ "$COMPONENT" == "pathcomp" ]; then
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+ TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-frontend.log"
+ docker tag "$COMPONENT-frontend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG"
+
+ PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-frontend.log"
+ docker push "$IMAGE_URL" > "$PUSH_LOG"
+
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+ TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-backend.log"
+ docker tag "$COMPONENT-backend:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG"
+
+ PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-backend.log"
+ docker push "$IMAGE_URL" > "$PUSH_LOG"
+ elif [ "$COMPONENT" == "dlt" ]; then
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+ TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-connector.log"
+ docker tag "$COMPONENT-connector:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG"
+
+ PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-connector.log"
+ docker push "$IMAGE_URL" > "$PUSH_LOG"
+
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+ TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}-gateway.log"
+ docker tag "$COMPONENT-gateway:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG"
+
+ PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}-gateway.log"
+ docker push "$IMAGE_URL" > "$PUSH_LOG"
+ else
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+ TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log"
+ docker tag "$COMPONENT:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG"
+
+ PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log"
+ docker push "$IMAGE_URL" > "$PUSH_LOG"
+ fi
+ else
+ for QUICK_COMPONENT in $TFS_QUICK_COMPONENTS; do
+ if [ "$COMPONENT" == "$QUICK_COMPONENT" ]; then
+
+ echo " Building Docker image..."
+ BUILD_LOG="$TMP_LOGS_FOLDER/build_${QUICK_COMPONENT}.log"
+
+ docker build -t "$QUICK_COMPONENT:$TFS_IMAGE_TAG" -f ./src/"$QUICK_COMPONENT"/Dockerfile . > "$BUILD_LOG"
+ echo " Pushing Docker image to '$TFS_REGISTRY_IMAGES'..."
+
+
+
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$QUICK_COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+
+ TAG_LOG="$TMP_LOGS_FOLDER/tag_${QUICK_COMPONENT}.log"
+ docker tag "$QUICK_COMPONENT:$TFS_IMAGE_TAG" "$IMAGE_URL" > "$TAG_LOG"
+
+ PUSH_LOG="$TMP_LOGS_FOLDER/push_${QUICK_COMPONENT}.log"
+ docker push "$IMAGE_URL" > "$PUSH_LOG"
+ fi
+ done
+ fi
+
+ echo " Adapting '$COMPONENT' manifest file..."
+ MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml"
+ cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST"
+
+ if [ "$COMPONENT" == "pathcomp" ]; then
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+ VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-frontend:" "$MANIFEST" | cut -d ":" -f4)
+ sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-frontend:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-backend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+ VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-backend:" "$MANIFEST" | cut -d ":" -f4)
+ sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-backend:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+ elif [ "$COMPONENT" == "dlt" ]; then
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-connector:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+ VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-connector:" "$MANIFEST" | cut -d ":" -f4)
+ sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-connector:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-gateway:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+ VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}-gateway:" "$MANIFEST" | cut -d ":" -f4)
+ sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-gateway:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+ else
+ IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
+ VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f4)
+ sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+ fi
+
+ sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+
+ # TODO: harmonize names of the monitoring component
+
+ echo " Deploying '$COMPONENT' component to Kubernetes..."
+ DEPLOY_LOG="$TMP_LOGS_FOLDER/deploy_${COMPONENT}.log"
+ kubectl --namespace $TFS_K8S_NAMESPACE apply -f "$MANIFEST" > "$DEPLOY_LOG"
+ COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/")
+ #kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=0 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG"
+ #kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=1 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG"
+
+ echo " Collecting env-vars for '$COMPONENT' component..."
+
+ SERVICE_DATA=$(kubectl get service ${COMPONENT_OBJNAME}service --namespace $TFS_K8S_NAMESPACE -o json)
+ if [ -z "${SERVICE_DATA}" ]; then continue; fi
+
+ # Env vars for service's host address
+ SERVICE_HOST=$(echo ${SERVICE_DATA} | jq -r '.spec.clusterIP')
+ if [ -z "${SERVICE_HOST}" ]; then continue; fi
+ ENVVAR_HOST=$(echo "${COMPONENT}service_SERVICE_HOST" | tr '[:lower:]' '[:upper:]')
+ echo "export ${ENVVAR_HOST}=${SERVICE_HOST}" >> $ENV_VARS_SCRIPT
+
+ # Env vars for service's 'grpc' port (if any)
+ SERVICE_PORT_GRPC=$(echo ${SERVICE_DATA} | jq -r '.spec.ports[] | select(.name=="grpc") | .port')
+ if [ -n "${SERVICE_PORT_GRPC}" ]; then
+ ENVVAR_PORT_GRPC=$(echo "${COMPONENT}service_SERVICE_PORT_GRPC" | tr '[:lower:]' '[:upper:]')
+ echo "export ${ENVVAR_PORT_GRPC}=${SERVICE_PORT_GRPC}" >> $ENV_VARS_SCRIPT
+ fi
+
+ # Env vars for service's 'http' port (if any)
+ SERVICE_PORT_HTTP=$(echo ${SERVICE_DATA} | jq -r '.spec.ports[] | select(.name=="http") | .port')
+ if [ -n "${SERVICE_PORT_HTTP}" ]; then
+ ENVVAR_PORT_HTTP=$(echo "${COMPONENT}service_SERVICE_PORT_HTTP" | tr '[:lower:]' '[:upper:]')
+ echo "export ${ENVVAR_PORT_HTTP}=${SERVICE_PORT_HTTP}" >> $ENV_VARS_SCRIPT
+ fi
+
+ printf "\n"
+done
+
+echo "Deploying extra manifests..."
+for EXTRA_MANIFEST in $TFS_EXTRA_MANIFESTS; do
+ echo "Processing manifest '$EXTRA_MANIFEST'..."
+ if [[ "$EXTRA_MANIFEST" == *"servicemonitor"* ]]; then
+ kubectl apply -f $EXTRA_MANIFEST
+ else
+ kubectl --namespace $TFS_K8S_NAMESPACE apply -f $EXTRA_MANIFEST
+ fi
+ printf "\n"
+done
+printf "\n"
+
+for COMPONENT in $TFS_COMPONENTS; do
+ echo "Waiting for '$COMPONENT' component..."
+ COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/")
+ kubectl wait --namespace $TFS_K8S_NAMESPACE \
+ --for='condition=available' --timeout=300s deployment/${COMPONENT_OBJNAME}service
+ printf "\n"
+done
+
+if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then
+ echo "Configuring WebUI DataStores and Dashboards..."
+ sleep 5
+
+ # Exposed through the ingress controller "tfs-ingress"
+ GRAFANA_URL="127.0.0.1:80/grafana"
+
+ # Default Grafana credentials
+ GRAFANA_USERNAME="admin"
+ GRAFANA_PASSWORD="admin"
+
+ # Configure Grafana Admin Password
+ # Ref: https://grafana.com/docs/grafana/latest/http_api/user/#change-password
+ GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_URL}"
+
+ echo ">> Updating Grafana 'admin' password..."
+ curl -X PUT -H "Content-Type: application/json" -d '{
+ "oldPassword": "'${GRAFANA_PASSWORD}'",
+ "newPassword": "'${TFS_GRAFANA_PASSWORD}'",
+ "confirmNew" : "'${TFS_GRAFANA_PASSWORD}'"
+ }' ${GRAFANA_URL_DEFAULT}/api/user/password
+ echo
+ echo
+
+ # Updated Grafana API URL
+ GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_URL}"
+ echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT
+
+ echo ">> Installing Scatter Plot plugin..."
+ curl -X POST -H "Content-Type: application/json" -H "Content-Length: 0" \
+ ${GRAFANA_URL_UPDATED}/api/plugins/michaeldmoore-scatter-panel/install
+ echo
+
+ # Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/
+ QDB_HOST_PORT="${METRICSDB_HOSTNAME}:${QDB_SQL_PORT}"
+ echo ">> Creating datasources..."
+ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{
+ "access" : "proxy",
+ "type" : "postgres",
+ "name" : "questdb-mon-kpi",
+ "url" : "'${QDB_HOST_PORT}'",
+ "database" : "'${QDB_TABLE_MONITORING_KPIS}'",
+ "user" : "'${QDB_USERNAME}'",
+ "basicAuth": false,
+ "isDefault": true,
+ "jsonData" : {
+ "sslmode" : "disable",
+ "postgresVersion" : 1100,
+ "maxOpenConns" : 0,
+ "maxIdleConns" : 2,
+ "connMaxLifetime" : 14400,
+ "tlsAuth" : false,
+ "tlsAuthWithCACert" : false,
+ "timescaledb" : false,
+ "tlsConfigurationMethod": "file-path",
+ "tlsSkipVerify" : true
+ },
+ "secureJsonData": {"password": "'${QDB_PASSWORD}'"}
+ }' ${GRAFANA_URL_UPDATED}/api/datasources
+ echo
+
+ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{
+ "access" : "proxy",
+ "type" : "postgres",
+ "name" : "questdb-slc-grp",
+ "url" : "'${QDB_HOST_PORT}'",
+ "database" : "'${QDB_TABLE_SLICE_GROUPS}'",
+ "user" : "'${QDB_USERNAME}'",
+ "basicAuth": false,
+ "isDefault": false,
+ "jsonData" : {
+ "sslmode" : "disable",
+ "postgresVersion" : 1100,
+ "maxOpenConns" : 0,
+ "maxIdleConns" : 2,
+ "connMaxLifetime" : 14400,
+ "tlsAuth" : false,
+ "tlsAuthWithCACert" : false,
+ "timescaledb" : false,
+ "tlsConfigurationMethod": "file-path",
+ "tlsSkipVerify" : true
+ },
+ "secureJsonData": {"password": "'${QDB_PASSWORD}'"}
+ }' ${GRAFANA_URL_UPDATED}/api/datasources
+ printf "\n\n"
+
+ echo ">> Creating dashboards..."
+ # Ref: https://grafana.com/docs/grafana/latest/http_api/dashboard/
+ curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_db_mon_kpis_psql.json' \
+ ${GRAFANA_URL_UPDATED}/api/dashboards/db
+ echo
+
+ curl -X POST -H "Content-Type: application/json" -d '@src/webui/grafana_db_slc_grps_psql.json' \
+ ${GRAFANA_URL_UPDATED}/api/dashboards/db
+ printf "\n\n"
+
+ echo ">> Staring dashboards..."
+ DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-l3-monit"
+ DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id')
+ curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID}
+ echo
+
+ DASHBOARD_URL="${GRAFANA_URL_UPDATED}/api/dashboards/uid/tfs-slice-grps"
+ DASHBOARD_ID=$(curl -s "${DASHBOARD_URL}" | jq '.dashboard.id')
+ curl -X POST ${GRAFANA_URL_UPDATED}/api/user/stars/dashboard/${DASHBOARD_ID}
+ echo
+
+ printf "\n\n"
+fi
diff --git a/src/bgpls_speaker/requirements.in b/src/bgpls_speaker/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..3af49b784a205ac6aada306219f5a2e658beea27
--- /dev/null
+++ b/src/bgpls_speaker/requirements.in
@@ -0,0 +1,23 @@
+# 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
+ncclient==0.6.13
+python-json-logger==2.0.2
+lxml==4.9.1
+pytz==2021.3
+xmltodict==0.12.0
+grpcio==1.47.*
+protobuf==3.20.*
\ No newline at end of file
diff --git a/src/bgpls_speaker/service/BgplsService.py b/src/bgpls_speaker/service/BgplsService.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ac4d1c5bab56cfea2a0457893691175a5dfdfbb
--- /dev/null
+++ b/src/bgpls_speaker/service/BgplsService.py
@@ -0,0 +1,31 @@
+# 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 bgpls_speaker.service.tools.DiscoveredDBManager import DiscoveredDBManager
+from bgpls_speaker.service.tools.GrpcServer import GrpcServer
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.proto.bgpls_pb2_grpc import add_BgplsServiceServicer_to_server
+from common.tools.service.GenericGrpcService import GenericGrpcService
+from .BgplsServiceServicerImpl import BgplsServiceServicerImpl
+
+class BgplsService(GenericGrpcService):
+ def __init__(self, discoveredDB : DiscoveredDBManager,
+ speakerServer : GrpcServer,cls_name: str = __name__) -> None:
+ port = get_service_port_grpc(ServiceNameEnum.BGPLS) # El enum en common.constants
+ super().__init__(port, cls_name=cls_name)
+ self.bgpls_servicer = BgplsServiceServicerImpl(discoveredDB,speakerServer)
+
+ def install_servicers(self):
+ add_BgplsServiceServicer_to_server(self.bgpls_servicer, self.server)
diff --git a/src/bgpls_speaker/service/BgplsServiceServicerImpl.py b/src/bgpls_speaker/service/BgplsServiceServicerImpl.py
new file mode 100644
index 0000000000000000000000000000000000000000..79862ee3b1204af105c5bd75c233f80ff3a9cf00
--- /dev/null
+++ b/src/bgpls_speaker/service/BgplsServiceServicerImpl.py
@@ -0,0 +1,192 @@
+# 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 List, Tuple, Union
+from bgpls_speaker.service.tools.DiscoveredDBManager import DiscoveredDBManager, GetContextDevices
+from bgpls_speaker.service.tools.GrpcServer import GrpcServer
+from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
+from common.proto.context_pb2 import DeviceId, Empty, EndPointId, Link, LinkId, Uuid
+from context.client.ContextClient import ContextClient
+from common.proto.bgpls_pb2 import (
+ BgplsSpeaker, BgplsSpeakerId, DiscoveredDeviceList, DiscoveredDevice,
+ DiscoveredLink, DiscoveredLinkList, NodeDescriptors, BgplsSpeakerList
+)
+from common.proto.bgpls_pb2_grpc import BgplsServiceServicer
+
+def json_to_list(json_str : str) -> List[Union[str, Tuple[str, str]]]:
+ try:
+ data = json.loads(json_str)
+ except: # pylint: disable=bare-except
+ return [('item', str(json_str))]
+
+ if isinstance(data, dict):
+ return [('kv', (key, value)) for key, value in data.items()]
+ elif isinstance(data, list):
+ return [('item', ', '.join(data))]
+ else:
+ return [('item', str(data))]
+
+LOGGER = logging.getLogger(__name__)
+
+METRICS_POOL = MetricsPool('Service', 'RPC')
+
+class BgplsServiceServicerImpl(BgplsServiceServicer):
+ def __init__(self,discoveredDB : DiscoveredDBManager,
+ speakerServer : GrpcServer) -> None:
+ LOGGER.debug('Creating Servicer...')
+ self.speaker_handler_factory = 1
+ self.speaker_server=speakerServer
+ self.discoveredDB=discoveredDB
+ LOGGER.debug('Servicer Created')
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def ListDiscoveredDevices(self, request : Empty, context : grpc.ServicerContext) -> DiscoveredDeviceList:
+ """
+ Get devices discovered from bgpls protocol
+ """
+ device_names=self.discoveredDB.GetNodeNamesFromDiscoveredDB()
+ nodes = self.discoveredDB.GetNodesFromDiscoveredDB()
+ devices = [DiscoveredDevice(nodeName=node.node_name,igpID=node.igp_id,learntFrom=node.learnt_from) for node in nodes]
+ return DiscoveredDeviceList(discovereddevices=devices)
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def ListDiscoveredLinks(self, request : Empty, context : grpc.ServicerContext) -> DiscoveredLinkList:
+ """
+ Get links discovered from bgpls protocol
+ """
+ self.discoveredDB.UpdateNodeNameInLink()
+ links = self.discoveredDB.GetLinksFromDiscoveredDB()
+ links_info=[]
+ for link in links:
+ local=NodeDescriptors(igp_id=link.local_id,nodeName=link.local_id)
+ remote=NodeDescriptors(igp_id=link.remote_id,nodeName=link.remote_id)
+ links_info.append(DiscoveredLink(local=local,remote=remote,learntFrom=link.learnt_from,
+ local_ipv4=link.local_ipv4_id,remote_ipv4=link.remote_ipv4_id))
+ return DiscoveredLinkList(discoveredlinks=links_info)
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def AddBgplsSpeaker(self, request : BgplsSpeaker, context : grpc.ServicerContext) -> BgplsSpeakerId:
+ """
+ Creates a new connection with an speaker with the given ip address, port and as.
+ Returns de id of the speaker created (to kill proccess¿)
+ """
+ LOGGER.debug("(AddBgplsSpeaker) Create speaker instance %s",request)
+
+ speaker_id=self.speaker_server.connectToJavaBgpls(request.address,request.port,request.asNumber)
+ return BgplsSpeakerId(id=speaker_id)
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def ListBgplsSpeakers(self, request : Empty, context : grpc.ServicerContext) -> BgplsSpeakerId:
+ """
+ Returns a list of the IDs of the BGP-LS speakers with open connections.
+ """
+ speaker_list=[]
+ bgpls_speaker_list=[]
+ speaker_list=self.speaker_server.getSpeakerListIds()
+ for speaker in speaker_list:
+ bgpls_speaker_list.append(BgplsSpeakerId(id=speaker))
+ return BgplsSpeakerList(speakers=bgpls_speaker_list)
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def DisconnectFromSpeaker(self, request : BgplsSpeaker, context : grpc.ServicerContext) -> bool:
+ """
+ Disconencts from the BGP-LS speaker given its ipv4 address.
+ """
+ speaker_id=self.speaker_server.getSpeakerIdFromIpAddr(request.address)
+ self.speaker_server.terminateRunnerById(speaker_id)
+ return Empty()
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def GetSpeakerInfoFromId(self, request : BgplsSpeakerId, context : grpc.ServicerContext) -> BgplsSpeaker:
+ """
+ Get the address, port and as number of the speaker given its id.
+ """
+ address,as_number,port=self.speaker_server.getSpeakerFromId(request.id)
+ return BgplsSpeaker(address=address,port=port,asNumber=as_number)
+
+ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+ def NotifyAddNodeToContext(self, request : DiscoveredDevice, context : grpc.ServicerContext) :
+ """
+ When a node is added to context via bgpls module this function checks if there are other nodes in the
+ topology connected by links discovered via bgpls. Then, if the link exist adds it to the context.
+ TODO: get endpoints from pce module
+ """
+ node_name=request.nodeName
+ node_igp=self.discoveredDB.GetIgpIdFromNodeName(node_name)
+ LOGGER.debug("(NotifyAddNodeToContext) Find links to nodes ")
+ nodes_conected=self.discoveredDB.FindConnectedNodes(node_igp)
+ # Check if nodes are in context
+ context_client=ContextClient()
+ context_client.connect()
+ # devices=context_client.ListDevices(Empty())
+ device_names,devices_ips=GetContextDevices(context_client)
+ LOGGER.debug("(NotifyAddNodeToContext) Devices in context: %s", device_names)
+ LOGGER.debug("(NotifyAddNodeToContext) Nodes conected in context: %s", nodes_conected)
+ nodes_conected_in_context=list(set(nodes_conected) & set(device_names))
+ LOGGER.debug("(NotifyAddNodeToContext) nodes_conected_in_context: %s", nodes_conected_in_context)
+ # TODO: next to function
+ for remote_node in nodes_conected_in_context:
+
+ # TODO: get endpoints connected to remote ip (pce¿)
+ end_point1="eth-1/0/20"
+ end_point2="eth-1/0/20"
+ end_point_uuid1=Uuid(uuid=end_point1)
+ end_point_uuid2=Uuid(uuid=end_point2)
+
+ link_name_src_dest=node_name+"/"+end_point1+"=="+remote_node+"/"+end_point2
+ device_uuid_src=DeviceId(device_uuid=Uuid(uuid=node_name))
+ device_src=context_client.GetDevice(device_uuid_src)
+
+ link_name_dest_src=remote_node+"/"+end_point2+"=="+node_name+"/"+end_point1
+ device_uuid_dest=DeviceId(device_uuid=Uuid(uuid=remote_node))
+ device_dest=context_client.GetDevice(device_uuid_dest)
+
+ self.getEndpointFromIpInterface(device_src,link.local_ipv4_id)
+ self.getEndpointFromIpInterface(device_dest,link.remote_ipv4_id)
+ # LOGGER.debug("(NotifyAddNodeToContext) Source: %s Destination: %s", device_src,device_dest)
+
+ end_point_id1=EndPointId(endpoint_uuid=end_point_uuid1,device_id=device_uuid_src)
+ end_point_id2=EndPointId(endpoint_uuid=end_point_uuid2,device_id=device_uuid_dest)
+
+ end_point_ids_src_dest=[end_point_id1,end_point_id2]
+ end_point_ids_dest_src=[end_point_id2,end_point_id1]
+
+ link_id_src=context_client.SetLink(Link(link_id=LinkId(link_uuid=Uuid(uuid=link_name_src_dest)),
+ link_endpoint_ids=end_point_ids_src_dest))
+
+ link_id_dst=context_client.SetLink(Link(link_id=LinkId(link_uuid=Uuid(uuid=link_name_dest_src)),
+ link_endpoint_ids=end_point_ids_dest_src))
+
+ LOGGER.debug("(NotifyAddNodeToContext) Link set id src--->dst: %s", link_id_src)
+ context_client.close()
+ return Empty()
+
+ def getEndpointFromIpInterface(self,device,ipv4):
+ """
+ Get TFS endpoint from interface IPv4.
+ """
+ for config in device.device_config.config_rules:
+ if config.WhichOneof('config_rule') == 'custom':
+ for item_type, item in json_to_list(config.custom.resource_value):
+ if item_type == 'kv':
+ # LOGGER.debug("(getEndpointFromIpInterface) item: %s",item)
+ endpoint=item
+ LOGGER.debug("(getEndpointFromIpInterface) config: %s",config.custom.resource_key)
+ if "/interface" in config.custom.resource_key:
+ interface=config.custom.resource_key.split("/interface")[1].strip("[]")
+ LOGGER.debug("(getEndpointFromIpInterface) interface: %s",interface)
+ if ipv4 in config.custom.resource_value:
+ LOGGER.debug("(getEndpointFromIpInterface) value: %s",config.custom.resource_value)
+ return endpoint
\ No newline at end of file
diff --git a/src/bgpls_speaker/service/__init__.py b/src/bgpls_speaker/service/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..f80ccfd52ebfd4fa1783267201c52eb7381741bf
--- /dev/null
+++ b/src/bgpls_speaker/service/__init__.py
@@ -0,0 +1,13 @@
+# 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.
\ No newline at end of file
diff --git a/src/bgpls_speaker/service/__main__.py b/src/bgpls_speaker/service/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a56449eafb0eb40a31768e16f0fdcb1fa1dc72f8
--- /dev/null
+++ b/src/bgpls_speaker/service/__main__.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 logging, signal, sys, threading
+from prometheus_client import start_http_server
+from common.Settings import get_log_level, get_metrics_port
+from .tools.DiscoveredDBManager import DiscoveredDBManager
+from .BgplsService import BgplsService
+from .tools.GrpcServer import GrpcServer
+
+terminate = threading.Event()
+LOGGER : logging.Logger = None
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+def signal_handler(signal, frame):
+ LOGGER.warning('Terminate signal received')
+ LOGGER.warning(signal)
+ terminate.set()
+
+def main():
+ global LOGGER
+
+ log_level = get_log_level()
+ logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
+ LOGGER = logging.getLogger(__name__)
+ signal.signal(signal.SIGINT, signal_handler)
+ signal.signal(signal.SIGTERM, signal_handler)
+
+ LOGGER.info('Starting...')
+
+ # Start metrics server
+ metrics_port = get_metrics_port()
+ start_http_server(metrics_port)
+ # One common database for all bgpls_speakers connection
+ DB=DiscoveredDBManager()
+
+ speaker_server = GrpcServer(DB)
+ speaker_server.Connect()
+
+ grpc_service = BgplsService(DB,speaker_server)
+ grpc_service.start()
+
+ # Wait for termination signal
+ while not terminate.wait(timeout=0.1): pass
+ LOGGER.info('Terminating...')
+ speaker_server.terminateGrpcServer()
+ grpc_service.stop()
+ LOGGER.info('Bye')
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/src/bgpls_speaker/service/java/BGP4Parameters_3.xml b/src/bgpls_speaker/service/java/BGP4Parameters_3.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ec6894922db6cee3fa696a9610929041817e4c82
--- /dev/null
+++ b/src/bgpls_speaker/service/java/BGP4Parameters_3.xml
@@ -0,0 +1,65 @@
+
+
+
+
+ 12179
+ 7.7.7.7
+
+ 1112
+
+
+ 10.95.90.43
+ false
+ true
+ 179
+
+
+
+ BGP4Parser2.log
+ BGP4Client2.log
+ BGP4Server2.log
+
+ true
+
+ 40000
+ true
+
+
+ 180
+
+ 4
+
+ 65006
+
+
+
+ false
+
+ true
+
+ fromBGP
+
+
+
+
+
+ 0.0.0.0
+
\ No newline at end of file
diff --git a/src/bgpls_speaker/service/java/exec_speakear_java.sh b/src/bgpls_speaker/service/java/exec_speakear_java.sh
new file mode 100644
index 0000000000000000000000000000000000000000..10f84c6537714982a1441b284b45b59373e9b49f
--- /dev/null
+++ b/src/bgpls_speaker/service/java/exec_speakear_java.sh
@@ -0,0 +1,19 @@
+# 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.
+
+#!/bin/bash
+cd netphony-topology/
+"/home/ubuntu/downloads/apache-maven-3.8.8/bin/mvn" clean package -P bgp-ls-speaker assembly:single -DskipTests
+cd ..
+sudo java -jar netphony-topology/target/bgp-ls-speaker-jar-with-dependencies.jar BGP4Parameters_3.xml
\ No newline at end of file
diff --git a/src/bgpls_speaker/service/java/netphony-topology/.settings/org.eclipse.jdt.core.prefs b/src/bgpls_speaker/service/java/netphony-topology/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..cb635b1c2a6bee7b1279cac6db56bd9ee2f6c271
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/src/bgpls_speaker/service/java/netphony-topology/BGP4Parameters_3.xml b/src/bgpls_speaker/service/java/netphony-topology/BGP4Parameters_3.xml
new file mode 100644
index 0000000000000000000000000000000000000000..063344673d2a07b7fdf2f69871c44518cd7f2d1a
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/BGP4Parameters_3.xml
@@ -0,0 +1,65 @@
+
+
+
+
+ 12179
+ 7.7.7.7
+
+ 1112
+
+
+ 10.95.90.43
+ false
+ true
+ 179
+
+
+
+ BGP4Parser2.log
+ BGP4Client2.log
+ BGP4Server2.log
+
+ true
+
+ 40000
+ true
+
+
+ 180
+
+ 4
+
+ 100
+
+
+
+ false
+
+ true
+
+ fromBGP
+
+
+
+
+
+ 0.0.0.0
+
\ No newline at end of file
diff --git a/src/bgpls_speaker/service/java/netphony-topology/CHANGELOG b/src/bgpls_speaker/service/java/netphony-topology/CHANGELOG
new file mode 100644
index 0000000000000000000000000000000000000000..4049eba8ae25be4be928f0b937d80788d6c955eb
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/CHANGELOG
@@ -0,0 +1,50 @@
+# 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.
+
+v1.3.3
+- Topology Module added
+- Topology Module: Export via RESCONF with COP model
+- Topology Module: Export via RESTCONF with IETF model (nodes only)
+- Topology Module: Export via UNIFY model
+- Topology Module: Import via XML
+- Topology Module: Import/Export via BGP-LS
+v1.3.2
+- Supports network-protocols 1.3.2
+- Update to support reading multiple AS_PATH
+- Apache 2.0 license
+- Moved to slf4j logging framework
+- Added method to pass multiple TEDs from en external program
+- Added docker support in travis
+v1.3
+- Compile with networking-protocols v1.3.0 (available in maven central)
+- JUnit Test upgrade to check intraTEDBs after sending
+- Added functionality: read multiple intraTEDBs from xml file
+- Added support to draft-previdi-idr-bgpls-te-metric-extensions-00
+v1.2.2
+- Added travis integration
+- Javadoc errors fixed
+- Ready to meet maven central requirements
+- Compile with networking-protocols v1.2.3 (available in maven central)
+v1.2.1
+- Compile with networking-protocols v1.2.1
+v1.2
+- JUnit Test added
+- Bugfixes
+- Reduced number of logs
+- Updated README with explanation of parameters
+v1.1.1
+- Added configuration instructions of the standalone BGP Peer
+- Added dependencies to pom.xml
+v1.1.0
+First Public Release
diff --git a/src/bgpls_speaker/service/java/netphony-topology/LICENSE b/src/bgpls_speaker/service/java/netphony-topology/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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/bgpls_speaker/service/java/netphony-topology/VERSION b/src/bgpls_speaker/service/java/netphony-topology/VERSION
new file mode 100644
index 0000000000000000000000000000000000000000..31e5c843497c24df077777c05af122d8b3a60ddb
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/VERSION
@@ -0,0 +1 @@
+1.3.3
diff --git a/src/bgpls_speaker/service/java/netphony-topology/doc/Examples.md b/src/bgpls_speaker/service/java/netphony-topology/doc/Examples.md
new file mode 100644
index 0000000000000000000000000000000000000000..88f7a7bd5c7a268857a7a4ec2642c388daf715d3
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/doc/Examples.md
@@ -0,0 +1,133 @@
+
+
+#Examples
+
+##Topology Module Examples
+
+Two sets of basic configuration files are here included with Topology Module software: the setup for running three TM within the same machine (configuration A) and the setup for running three TM in three dedicated machines (configuration B). In both cases three example network topologies are provided to represent the abstract topology of 2 end-point providers and 1 transit provider.
+
+### Example TM1: 1 Way Test in the same virtual machine, BPG-LS Plugin and UNIFY Export.
+
+The setup has been provided just for testing purpose and configures 3 TADS in the same machine to perform unidirectional information exchange.
+
+![1WayTest](figures/1wayTest.png?raw=true "Test with 3 TM")
+
+The reference files, including Topology Module configuration, BGP-LS Plugin configuration and abstracted topologies are copiend in the folder target/conf1wayTest after the maven installation. Be sure to compile also the Topology Module as indicated in README.md.
+
+To execute TM1 run:
+ ```bash
+ sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM1.xml
+ ```
+
+To execute TM2 run:
+ ```bash
+ sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM2.xml
+ ```
+
+To execute TM3 run:
+ ```bash
+ sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM3.xml
+ ```
+
+To verify the retrieved information:
+ ```bash
+curl http://localhost:8087/restconf/data/virtualizer/ | python -m json.tool
+ ```
+[for TADS2]
+ ```bash
+curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
+ ```
+[for TADS3]
+ ```bash
+curl http://localhost:8089/restconf/data/virtualizer/ | python -m json.tool
+ ```
+
+### Example TM2: 2 Way Test in the different virtual machines, BPG-LS Plugin and UNIFY Export.
+The setup has been provided as reference configuration for the configuration of 3 TM in dedicated machines to perform bidirectional exchange of information
+![1WayTest](figures/2wayTest.png?raw=true "Test with 3 TM in 3 different machines")
+The reference files, including Topology Module configuration, BGP-LS Plugin configuration and abstracted topologies are in
+ ```bash
+target/conf2waysReal
+ ```
+Before running the reference scenario be sure to complete the IP configuration in the 3 modules, in fact, according to previous description, minor ad-hoc changes are needed.
+
+In the Topology Module configuration files (TM*.xml):
+• set the IP address used for the BGP-LS communication as Identifier
+
+In the BGP-LS Plugin configuration (BGPLS*_2way.xml):
+• set the IP address used for the BGP-LS communication as BGPIdentifier
+• configure the peers as needed (IP address and port)
+
+[where * = 1,2,3]
+
+To execute TADS1 in machine 1 run:
+ ```bash
+ sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM1.xml
+ ```
+
+To execute TADS1 in machine 2 run:
+ ```bash
+ sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM2.xml
+ ```
+
+To execute TADS1 in machine 3 run:
+ ```bash
+ sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM3.xml
+ ```
+
+To verify the retrieved information:
+[for TADS2, in machine 1]
+ ```bash
+curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
+ ```
+[for TADS2, in machine 2]
+ ```bash
+>curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
+ ```
+[for TADS3, in machine 3]
+ ```bash
+>curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
+ ```
+### Topology module with BGP-LS and COP plugins and BGP-LS speaker
+
+In this example there are 2 BGP-LS speakers, one acting as sender of topology, and the other as consumer. A small topology is loaded from an xml file in BGP-LS Speaker #1. This topology is sent to BGP-LS Speaker #2.
+ ```bash
+TBD
+ ```
+### Topology module with BGP-LS and COP plugins and Topology module with BGP-LS speaker
+
+In this example there are 2 BGP-LS speakers, one acting as sender of topology, and the other as consumer. A small topology is loaded from an xml file in BGP-LS Speaker #1. This topology is sent to BGP-LS Speaker #2.
+ ```bash
+TBD
+ ```
+## BGP-LS Speaker Examples
+
+### BPP-LS Speaker Example 1
+
+In this example there are 2 BGP-LS speakers, one acting as sender of topology, and the other as consumer. A small topology is loaded from an xml file in BGP-LS Speaker #1. This topology is sent to BGP-LS Speaker #2.
+To launch BGP-LS Speaker #1:
+ ```bash
+sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/bgp-ls-speaker-jar-with-dependencies.jar target/bgpls_example1/BGP4Parameters_1.xml
+ ```
+ BGP-LS Speaker #2:
+ ```bash
+sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/bgp-ls-speaker-jar-with-dependencies.jar target/bgpls_example1/BGP4Parameters_2.xml
+ ```
+To verify the retrieved information:
+ ```bash
+telnet localhost 1112
+show topology
+ ```
+Then, the topology is printed on screen.
diff --git a/src/bgpls_speaker/service/java/netphony-topology/doc/TAPIExample.md b/src/bgpls_speaker/service/java/netphony-topology/doc/TAPIExample.md
new file mode 100644
index 0000000000000000000000000000000000000000..9b0c48c8ed24fe8ca5c06f118b3d440653c686e5
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/doc/TAPIExample.md
@@ -0,0 +1,27 @@
+
+
+# Example 1: TM with XML Plugin and TAPI Plugin
+- First of all, compile the full-jar if you have not done so
+```bash
+ mvn package -P generate-full-jar
+```
+Execute the server
+```bash
+sudo java -Dlog4j.configurationFile=target/examples/log4j2.xml -jar target/topology-1.3.4-SNAPSHOT-shaded.jar target/TM_TAPI_example1/TMConfTAPI.xml
+```
+Make the query
+```bash
+curl http://localhost:8089/config/context/topology -X GET -i -H "Content-Type: application/json" -H "Accept: application/json"
+```
diff --git a/src/bgpls_speaker/service/java/netphony-topology/doc/TopologyFileDescription.md b/src/bgpls_speaker/service/java/netphony-topology/doc/TopologyFileDescription.md
new file mode 100644
index 0000000000000000000000000000000000000000..452050b65106b8393ac8a7df98ea472b7705e608
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/doc/TopologyFileDescription.md
@@ -0,0 +1,127 @@
+
+
+# Topology XML File
+
+This section describes the topology file format, used by the TADS to load the abstracted view of the local provider.
+
+The reference file for this description is
+
+```
+target/conf1wayTest/network1.xml
+```
+
+The main tag of the file is **network** that can include multiple **domains**, each domain represents a provider.
+
+```xml
+
+
+
+
+
+
+```
+
+In this case the network topology includes two providers.
+
+The first part of the each domain contains some general information:
+
+ - **domain_id**: the AS number of the domain represented in IPv4 format
+ - the **reachability_entry**: that summarizes the prefix network for the provider (IPv4 network prefix and mask)
+ - **it_resources**: here the information related to overall IT resources availability is described considering
+ - **controller_it**: the entry point for 5GEx orchestration
+ - **cpu**: overall available CPUs
+ - **mem**: overall available memory
+ - **storage**: overall available storage
+
+```xml
+0.0.0.1
+
+ 172.16.101.0
+ 24
+
+
+ https://openstack.5Gex.com/url
+ 100
+ 100Gbyte
+ 100Tbyte
+
+```
+
+Then the file is organized considering a list of nodes and a list unidirectional links.
+
+Each node is represented with a tag **node** and is identified with an IPv4 id called **router_id**
+
+```xml
+
+ 172.16.101.101
+
+
+ 172.16.101.102
+
+
+ 172.16.101.103
+
+
+ 172.16.101.104
+
+```
+
+In the reference case 4 nodes are considered.
+Each link is identified by the tag **edge**.
+The link description include:
+
+
+ - **source**: the source node of the link, identified with the pair **router_id** and interface id, **if_id**
+ - **destination**: the destination node of the link, identified with the pair router_id and interface
+ - **TE parameters**: several possibilities are available, in the considered example the focus was on
+ - unidirectional link delay
+ - minimum experienced delay
+ - maximum experienced delay
+
+```xml
+
+
+
+ 172.16.101.104
+ 1
+
+ 99
+
+ 23
+ 250
+
+
+
+```
+
+For setting up default TE parameters for all the network links, the **edgeCommon** tag is used.
+
+```xml
+
+ 99
+
+ 23
+ 43
+
+ 1
+ 102
+ 802
+ 500
+ 436
+
+```
diff --git a/src/bgpls_speaker/service/java/netphony-topology/doc/figures/1wayTest.png b/src/bgpls_speaker/service/java/netphony-topology/doc/figures/1wayTest.png
new file mode 100644
index 0000000000000000000000000000000000000000..021dd3ee5c6dff653af4131f8060e0b7cac88f1d
Binary files /dev/null and b/src/bgpls_speaker/service/java/netphony-topology/doc/figures/1wayTest.png differ
diff --git a/src/bgpls_speaker/service/java/netphony-topology/doc/figures/2wayTest.png b/src/bgpls_speaker/service/java/netphony-topology/doc/figures/2wayTest.png
new file mode 100644
index 0000000000000000000000000000000000000000..4800df6d96874c480059be8cc905e753b8614f2b
Binary files /dev/null and b/src/bgpls_speaker/service/java/netphony-topology/doc/figures/2wayTest.png differ
diff --git a/src/bgpls_speaker/service/java/netphony-topology/log4j2.xml b/src/bgpls_speaker/service/java/netphony-topology/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d0b383697fccd29960486751685e927d76dda34c
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/log4j2.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/bgpls_speaker/service/java/netphony-topology/pom.xml b/src/bgpls_speaker/service/java/netphony-topology/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..be949361d720695e225e4c9fc08c9730f453fd8a
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/pom.xml
@@ -0,0 +1,497 @@
+
+
+ 4.0.0
+ es.tid.netphony
+ topology
+ 1.4.0-SNAPSHOT
+ jar
+ Netphony TED and BGP-LS peer
+ Traffic Engineering Database, BGP-LS peer, Topology Module
+ http://telefonicaid.github.io/netphony-topology/
+
+
+ Apache License 2.0
+ http://www.apache.org/licenses/LICENSE-2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.sun.jersey
+ jersey-json
+ ${jersey-version}
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j-version}
+
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j-version}
+
+
+ es.tid.netphony
+ network-protocols
+ 1.4.1
+
+
+
+
+ org.jgrapht
+ jgrapht-core
+ ${jgrapht-core-version}
+
+
+ com.google.code.gson
+ gson
+ 2.2.2
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+
+
+ com.metaparadigm
+ json-rpc
+ 1.0
+
+
+ redis.clients
+ jedis
+ 2.1.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${jackson-version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson-version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson-version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-joda
+ ${jackson-datatype-joda-version}
+
+
+
+ joda-time
+ joda-time
+ ${jodatime-version}
+
+
+
+
+ io.grpc
+ grpc-netty-shaded
+ ${grpc-protobuf-version}
+
+
+ io.grpc
+ grpc-protobuf
+ ${grpc-protobuf-version}
+
+
+ io.grpc
+ grpc-stub
+ ${grpc-stub-version}
+
+
+ javax.annotation
+ javax.annotation-api
+ ${javax-annotation-api-version}
+
+
+
+ com.google.guava
+ guava
+ 31.1-jre
+
+
+
+
+
+ Telefonica I+D
+ oscar.gonzalezdedios@telefonica.com
+ Telefonica I+D
+ https://www.tid.es
+
+
+
+ scm:git:git@github.com:telefonicaid/netphony-topology.git
+ scm:git:git@github.com:telefonicaid/netphony-topology.git
+ git@github.com:telefonicaid/netphony-topology.git
+
+
+
+
+ oss.sonatype.org-snapshot
+ http://oss.sonatype.org/content/repositories/snapshots
+
+ false
+
+
+ true
+
+
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+ ${basedir}/src/main/java
+
+
+ kr.motd.maven
+ os-maven-plugin
+ 1.6.2
+
+
+
+
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+ 0.6.1
+
+ com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}
+ grpc-java
+ io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}
+
+
+
+
+ compile
+ compile-custom
+
+
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+
+ 8
+ UTF-8
+
+
+
+ maven-resources-plugin
+ 2.6
+
+ UTF-8
+
+
+
+ copy-resources
+ validate
+
+ copy-resources
+
+
+ ${basedir}/target
+
+
+ ${basedir}/src/main/resources
+ true
+
+
+ ${basedir}/src/main/sample-config-files
+ true
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+
+ true
+ lib/
+ eu.teraflow.tid.bgp4Peer.peer.BGPPeerMain
+
+
+
+
+
+
+
+
+ deploy-maven-central
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9.1
+
+ -Xdoclint:none
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
+
+ bgp-ls-speaker
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.5
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.5
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.5
+
+
+ io.netty
+ netty-transport-native-epoll
+ 4.1.77.Final
+ linux-x86_64
+
+
+
+
+
+ maven-assembly-plugin
+ 3.3.0
+
+
+ jar-with-dependencies
+
+ bgp-ls-speaker
+
+
+ eu.teraflow.tid.bgp4Peer.peer.BGPPeerMain
+
+
+
+
+
+
+
+
+ generate-javadoc
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ false
+
+ 2.9.1
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+
+
+
+ integration-test
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 2.13
+
+
+ integration-test
+
+ integration-test
+
+
+
+ verify
+
+ verify
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.19.1
+
+ true
+
+
+
+
+
+
+
+ generate-full-jar
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.5
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.5
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.5
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.4.3
+
+
+ package
+
+ shade
+
+
+ true
+
+
+ *:*
+
+
+
+ false
+
+
+
+ eu.teraflow.tid.bgp.bgp4Peer.peer.BGPPeerMain
+
+
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
+
+
+ 1.19.4
+ 2.0.6
+ 4.8.1
+ 2.5
+ 2.4.2
+ 2.3
+ 2.19.1
+ 0.9.1
+ 1.3.2
+ 1.24.0
+ 1.46.0
+ 2.1.5
+
+
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4PeerInitiatedSession.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4PeerInitiatedSession.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5a37e74344acd28c04428f02ac59d1692720aaf
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4PeerInitiatedSession.java
@@ -0,0 +1,188 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import es.tid.bgp.bgp4.messages.BGP4Message;
+import es.tid.bgp.bgp4.messages.BGP4MessageTypes;
+import es.tid.bgp.bgp4.messages.BGP4Update;
+import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
+import eu.teraflow.tid.bgp4Peer.updateTEDB.UpdateDispatcher;
+
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.Timer;
+
+/**
+ * BGP4 session server
+ *
+ * @author mcs
+ *
+ */
+public class BGP4PeerInitiatedSession extends GenericBGP4Session{
+ /**
+ * Class to dispatch the BGP4 update messages.
+ * If a BGP5 update message is received, it is stored in a queue of UpdateDispatcher.
+ */
+ private UpdateDispatcher updateDispatcher;
+
+
+ /**
+ * Constructor of the BGP4 Session
+ * @param s Socket of the BGP4Peer-BGP4Peer Communication
+ * @param bgp4SessionsInformation bgp4SessionsInformation
+ * @param updateDispatcher updateDispatcher
+ * @param holdTime holdTime
+ * @param BGPIdentifier BGPIdentifier
+ * @param version version
+ * @param myAutonomousSystem myAutonomousSystem
+ * @param noDelay noDelay
+ * @param keepAliveTimer keepAliveTimer
+ */
+ public BGP4PeerInitiatedSession(Socket s, BGP4SessionsInformation bgp4SessionsInformation, UpdateDispatcher updateDispatcher,int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem,boolean noDelay,int keepAliveTimer ){
+ super(bgp4SessionsInformation, holdTime, BGPIdentifier, version, myAutonomousSystem,keepAliveTimer);
+
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_IDLE);
+ log=LoggerFactory.getLogger("BGP4Server");
+ log.debug("New BGP4Session: "+s);
+ this.socket = s;
+ try {
+ s.setTcpNoDelay(noDelay);
+ } catch (SocketException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ this.newSessionId();
+
+ this.remotePeerIP =(Inet4Address) ((InetSocketAddress) socket.getRemoteSocketAddress()).getAddress();
+
+
+ timer=new Timer();
+ this.updateDispatcher = updateDispatcher;
+ //this.keepAliveLocal=params.getKeepAliveTimer();
+ //this.deadTimerLocal=params.getDeadTimer();
+ }
+
+
+
+ /**
+ * Initiates a Session the BGP-4 Peers
+ */
+ public void run() {
+ try {
+ initializeBGP4Session();
+ } catch (BGP4Exception e2) {
+ // TODO Auto-generated catch block
+ try {
+ this.socket.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return;
+ }
+ log.info("BGP4 Session established with peer "+this.remotePeerIP);
+ this.deadTimerT=new DeadTimerThread(this, this.holdTime);
+ startDeadTimer();
+ this.keepAliveT=new KeepAliveThread(out, this.keepAliveTimer);
+ startKeepAlive();
+
+ //Listen to new messages
+ try{
+ while(this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP) {
+ try {
+ this.msg = readBGP4Msg(in);//Read a new message
+
+ }catch (IOException e){
+ cancelDeadTimer();
+ cancelKeepAlive();
+ timer.cancel();
+ try {
+ in.close();
+ out.close();
+ } catch (Exception e1) {
+ log.warn("Exception Closing BGP4 Session with "+this.remotePeerIP);
+ }
+ log.debug("Finishing BGP4 Session with "+this.remotePeerIP);
+ return;
+ }
+ if (this.msg != null) {//If null, it is not a valid PCEP message
+ boolean bgp4Msg = true;//By now, we assume a valid PCEP message has arrived
+ //Depending on the type a different action is performed
+ switch(BGP4Message.getMessageType(this.msg)) {
+
+ case BGP4MessageTypes.MESSAGE_OPEN:
+ log.debug("OPEN message received");
+ //After the session has been started, ignore subsequent OPEN messages
+ log.warn("OPEN message ignored");
+ break;
+
+ case BGP4MessageTypes.MESSAGE_KEEPALIVE:
+ log.debug("KEEPALIVE message received from "+this.remotePeerIP);
+ //The Keepalive message allows to reset the deadtimer
+ break;
+
+ case BGP4MessageTypes.MESSAGE_NOTIFICATION:
+ log.info("NOTIFICATION message from "+this.remotePeerIP);
+ break;
+
+ case BGP4MessageTypes.MESSAGE_UPDATE:
+ log.debug("UPDATE message from "+this.remotePeerIP);
+ BGP4Update bgp4Update = new BGP4Update(msg);
+ log.debug(bgp4Update.toString());
+ bgp4Update.setLearntFrom(this.getRemotePeerIP().toString());
+ updateDispatcher.dispatchRequests(bgp4Update);
+ break;
+
+ default:
+ log.warn("ERROR: unexpected message from "+this.remotePeerIP);
+ bgp4Msg = false;
+ }
+
+ if (bgp4Msg) {
+ //Reseting Dead Timer as BGP4 Session Message has arrived
+ resetDeadTimer();
+ }
+ }
+ }
+ }finally{
+ log.error("BGP4 session with peer "+this.remotePeerIP+" has been closed");
+ cancelDeadTimer();
+ cancelKeepAlive();
+ this.FSMstate=BGP4StateSession.BGP4_STATE_IDLE;
+ endSession();
+ }
+ }
+
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+
+ }
+
+
+
+ @Override
+ protected void endSession() {
+ // TODO Auto-generated method stub
+ log.debug("Ending session with id "+this.getSessionId()+" from peer "+this.remotePeerIP);
+ BGP4SessionsInformation.deleteSession(this.getSessionId());
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4Session.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4Session.java
new file mode 100644
index 0000000000000000000000000000000000000000..002a5caa56f57f53b1d37f031e815377806684b3
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4Session.java
@@ -0,0 +1,44 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import es.tid.bgp.bgp4.messages.BGP4Message;
+
+
+/**
+ * BGP Session Interface
+ *
+ * @author mcs
+ *
+ */
+public interface BGP4Session {
+ /**
+ * Send close message and finish the BGP Session
+ */
+ public void close(/*int reason*/);
+ /**
+ * Finish the BGP Session abruptly,
+ */
+ public void killSession();
+
+ /**
+ * Encodes and sends BGP Message
+ * If the message is bad encoded, the session is closed
+ * @param message BGP4 Message
+ */
+ public void sendBGP4Message(BGP4Message message);
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionClient.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..61a5fc41c991947aeec8d9940605c9c934e216dd
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionClient.java
@@ -0,0 +1,222 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import es.tid.bgp.bgp4.messages.BGP4Message;
+import es.tid.bgp.bgp4.messages.BGP4MessageTypes;
+import es.tid.bgp.bgp4.messages.BGP4Update;
+import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
+import eu.teraflow.tid.bgp4Peer.updateTEDB.UpdateDispatcher;
+
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Socket;
+import java.util.Timer;
+/**
+ * Client session
+ *
+ * @author mcs
+ *
+ */
+public class BGP4SessionClient extends GenericBGP4Session{
+ /**
+ * Peer BGP port to which the session is connected
+ */
+ private int peerBGP_port;
+ /**
+ * Delay
+ */
+
+
+ private boolean no_delay=true;
+ private String localBGP4Address;
+ private int localBGP4Port;
+ /**
+ * Class to dispatch the BGP4 update messages.
+ * If a BGP5 update message is received, it is stored in a queue of UpdateDispatcher.
+ */
+ private UpdateDispatcher updateDispatcher;
+
+ public BGP4SessionClient(BGP4SessionsInformation bgp4SessionsInformation,UpdateDispatcher updateDispatcher, Inet4Address peerBGP_IPaddress, int peerBGP_port, int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem, String localBGP4Address, int localBGP4Port,int keepAliveTimer){
+ super(bgp4SessionsInformation, holdTime, BGPIdentifier, version, myAutonomousSystem,keepAliveTimer);
+ timer=new Timer();
+ log = LoggerFactory.getLogger("BGP4Client");
+ this.peerBGP_port = peerBGP_port;
+ this.updateDispatcher=updateDispatcher;
+ this.localBGP4Address=localBGP4Address;
+ this.localBGP4Port=localBGP4Port;
+ this.remotePeerIP = peerBGP_IPaddress;
+ }
+ /**
+ * Initiates a Session between the local BGP Peer and the remote BGP Peer
+ */
+ public void run() {
+
+ log.info("Opening new BGP4 Session with host "+ this.remotePeerIP.getHostAddress() + " on port " + this.peerBGP_port);
+ log.debug("Do we want to update from peer?" + updateFrom);
+ log.debug("Do we want to send to peer?" + sendTo);
+ try {
+ Inet4Address addr = (Inet4Address) Inet4Address.getByName(localBGP4Address);
+ Inet4Address addrPeer = remotePeerIP;
+ socket = new Socket(addrPeer, peerBGP_port, addr, 0);
+ if (no_delay){
+ this.socket.setTcpNoDelay(true);
+ log.debug("No delay activated");
+ }
+
+ } catch (IOException e) {
+ log.info("Connection refused trying to connect " + remotePeerIP.getHostAddress() + " on port " + peerBGP_port);
+ //As there is not yet a session added (it is added in the beginning of initializeBGP4Session());
+ //endSession();
+ return;
+ }
+
+ try {
+ initializeBGP4Session();
+ log.info("BGP4 Session established with peer "+this.remotePeerIP);
+ this.keepAliveT= new KeepAliveThread(this.getOut(),this.keepAliveTimer);
+ keepAliveT.start();
+ } catch (BGP4Exception e2) {
+ // TODO Auto-generated catch block
+ e2.printStackTrace();
+ log.debug("Session with "+this.remotePeerIP+" already exists: "+e2.getMessage());
+ try {
+ socket.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ log.error("Problem closing socket "+e.getMessage());
+ }
+ return;
+ }
+
+
+
+
+ try{
+ while(this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP) {
+ try {
+
+ this.msg = readBGP4Msg(in);//Read a new message
+
+ }catch (IOException e){
+ cancelDeadTimer();
+ cancelKeepAlive();
+ timer.cancel();
+ try {
+ in.close();
+ out.close();
+ } catch (Exception e1) {
+ log.warn("problem closing sockets");
+ }
+ log.debug("Finishing BGP4 Session abruptly!");
+ return;
+ }
+ if (this.msg != null) {//If null, it is not a valid PCEP message
+ boolean bgp4Msg = true;//By now, we assume a valid PCEP message has arrived
+ //Depending on the type a different action is performed
+ switch(BGP4Message.getMessageType(this.msg)) {
+
+ case BGP4MessageTypes.MESSAGE_OPEN:
+ log.debug("BGP OPEN message received from "+this.remotePeerIP);
+ //After the session has been started, ignore subsequent OPEN messages
+ log.warn("OPEN message ignored");
+ break;
+
+ case BGP4MessageTypes.MESSAGE_KEEPALIVE:
+ log.debug("BGP KEEPALIVE message received from "+this.remotePeerIP);
+ //The Keepalive message allows to reset the deadtimer
+ break;
+
+ case BGP4MessageTypes.MESSAGE_NOTIFICATION:
+ log.debug("BGP NOTIFICATION message received from "+this.remotePeerIP);
+ break;
+
+ case BGP4MessageTypes.MESSAGE_UPDATE:
+ log.debug("BGP UPDATE message received from "+this.remotePeerIP);
+ if(this.getUpdateFrom()){
+ BGP4Update bgp4Update = new BGP4Update(msg);
+ log.debug(bgp4Update.toString());
+ bgp4Update.setLearntFrom(this.remotePeerIP.getHostAddress() );
+ updateDispatcher.dispatchRequests(bgp4Update);
+ }
+ else
+ log.debug("Update message from " + this.remotePeerIP + " discarded");
+ break;
+
+ default:
+ log.warn("ERROR: unexpected message received");
+ bgp4Msg = false;
+ }
+
+ if (bgp4Msg) {
+ //Reseting Dead Timer as BGP4 Session Message has arrived
+ resetDeadTimer();
+ }
+ }
+ }
+ }finally{
+ //log.error("SESSION "+ internalSessionID+" IS KILLED");
+ log.info("BGP4 session with peer "+this.remotePeerIP+" has been closed");
+ cancelDeadTimer();
+ cancelKeepAlive();
+ this.FSMstate=BGP4StateSession.BGP4_STATE_IDLE;
+ endSession();
+ }
+ }
+
+
+ public int getPeerBGP_port() {
+ return peerBGP_port;
+ }
+ public void setPeerBGP_port(int peerBGP_port) {
+ this.peerBGP_port = peerBGP_port;
+ }
+ public Boolean getUpdateFrom() {
+ return updateFrom;
+ }
+ public void setUpdateFrom(Boolean updateFrom) {
+ this.updateFrom = updateFrom;
+ }
+ public Boolean getSendTo() {
+ return sendTo;
+ }
+ public void setSendTo(Boolean sendTo) {
+ this.sendTo = sendTo;
+ }
+ public boolean isNo_delay() {
+ return no_delay;
+ }
+ public void setNo_delay(boolean no_delay) {
+ this.no_delay = no_delay;
+ }
+
+
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+
+ }
+
+
+ @Override
+ protected void endSession() {
+ // TODO Auto-generated method stub
+ log.debug("Ending session with id "+this.getSessionId());
+ this.BGP4SessionsInformation.deleteSession(this.getSessionId());
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionExistsException.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionExistsException.java
new file mode 100644
index 0000000000000000000000000000000000000000..668825ca8ef616b7867e2bc58de91df4c741a36c
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionExistsException.java
@@ -0,0 +1,24 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+public class BGP4SessionExistsException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionsInformation.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionsInformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..df5d7bc9c828ab4270f5f2bad01e6c27d674ce98
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4SessionsInformation.java
@@ -0,0 +1,146 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
+
+import java.io.DataOutputStream;
+import java.net.Inet4Address;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+
+/**
+ * Class where the oppened BGP4 sessions are stored.
+ *
+ * @author mcs
+ *
+ */
+public class BGP4SessionsInformation {
+ public Hashtable sessionList;
+ public Hashtable sessionListByPeerIP;
+ private boolean isTest = false;
+ Logger log;
+ //FIXME: ya lo tenemos a trav�s de la lista de sesiones
+ DataOutputStream out;
+
+ public BGP4SessionsInformation(){
+ sessionList=new Hashtable();
+ sessionListByPeerIP=new Hashtable();
+ log = LoggerFactory.getLogger("BGP4Parser");
+ }
+
+ public BGP4SessionsInformation(boolean test){
+ sessionList=new Hashtable();
+ sessionListByPeerIP=new Hashtable();
+ log = LoggerFactory.getLogger("BGP4Parser");
+ isTest= test;
+ }
+
+
+ public synchronized void notifySessionStart(Inet4Address addr) throws BGP4SessionExistsException{
+ if (sessionListByPeerIP.containsKey(addr)){
+ throw new BGP4SessionExistsException();
+ }
+ }
+
+ public synchronized void addSession(long sessionId, GenericBGP4Session session) throws BGP4Exception{
+ Enumeration sessions = sessionList.elements();
+ log.debug("Looking to add session with id "+sessionId+" --> "+session.toString());
+
+ //Check if there is already a session with the remote peer.
+ //Only one session allowed with each remote peer
+ GenericBGP4Session existingSession=sessionListByPeerIP.get(session.remotePeerIP);
+ if(isTest){
+ //If there is no existing session with the peer
+ sessionList.put(new Long(sessionId),session);
+ sessionListByPeerIP.put(session.getPeerIP() , session);
+ log.debug("Registering new session with Peer "+session.getPeerIP() +" with ID "+sessionId);
+ }
+ else{
+ if (existingSession!=null){
+ log.debug("Session with id "+existingSession.getSessionId()+" against "+session.remotePeerIP.getHostAddress()+" already exists");
+ throw new BGP4Exception();//si no existe throw new BGP4Exception();
+ }
+
+ //If there is no existing session with the peer
+ sessionList.put(new Long(sessionId),session);
+ sessionListByPeerIP.put(session.getPeerIP() , session);
+ log.debug("Registering new session with Peer "+session.getPeerIP() +" with ID "+sessionId);
+
+ }
+
+ }
+
+ public synchronized void deleteSession(long sessionId){
+ GenericBGP4Session ses=sessionList.get(sessionId);
+ if (ses!=null) {
+ Inet4Address ip=sessionList.get(sessionId).getPeerIP();
+ sessionList.remove(new Long(sessionId));
+ sessionListByPeerIP.remove(ses.getPeerIP());
+ log.debug("Deleted Session with id "+sessionId +" with peer "+ses.getPeerIP().getHostAddress());
+ }else {
+ log.info("SESSION WAS NOT REGISTERED NULL");
+ }
+
+
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb=new StringBuffer(2000);
+ int counter = 1;
+ Enumeration sessions = sessionList.elements();
+
+ //Comprobar si ya existe la session con ese peer
+ while (sessions.hasMoreElements()){
+ sb.append("Session number "+(counter++)+"\n");
+ sb.append(sessions.nextElement().toString()+"\n");
+
+ }
+ return sb.toString();
+ }
+
+ public String printSession(long sessionId){
+ GenericBGP4Session ses=sessionList.get(new Long(sessionId));
+ if (ses!=null){
+ return ses.toString();
+ }else {
+ return "session "+sessionId+" does not exist";
+ }
+ }
+
+
+
+ public DataOutputStream getOut() {
+ return out;
+ }
+
+ public void setOut(DataOutputStream out) {
+ this.out = out;
+ }
+
+ public Hashtable getSessionList() {
+ return sessionList;
+ }
+ public void setSessionList(Hashtable sessionList) {
+ this.sessionList = sessionList;
+ }
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4StateSession.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4StateSession.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f426828b3bcb6b485a12c1966b5b760093bf9cf
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/BGP4StateSession.java
@@ -0,0 +1,28 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+/**
+ * The state session attribute indicates the current state of the BGP
+ FSM
+ * @author mcs
+ *
+ */
+public class BGP4StateSession {
+ public static final int BGP4_STATE_IDLE=0;
+ public static final int BGP4_STATE_TCP_PENDING=1;
+ public static final int BGP4_STATE_OPEN_WAIT=2;
+ public static final int BGP4_STATE_KEEP_WAIT=3;
+ public static final int BGP4_STATE_SESSION_UP=4;
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/ConnectRetryTimer.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/ConnectRetryTimer.java
new file mode 100644
index 0000000000000000000000000000000000000000..736c56fc57eb7c8fddb3e9566f94060a9b06866a
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/ConnectRetryTimer.java
@@ -0,0 +1,30 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import java.util.TimerTask;
+
+public class ConnectRetryTimer extends TimerTask {
+ int initialValue;
+ ConnectRetryTimer(int initialValue){
+ this.initialValue=initialValue;
+ }
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/DeadTimerThread.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/DeadTimerThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..f32f0218f751997fb15935ed457b252b9e39685e
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/DeadTimerThread.java
@@ -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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * BGP4 DeadTimer management Thread
+ *
+ */
+public class DeadTimerThread extends Thread {
+
+
+ private BGP4Session bgp4Session = null;
+ private int deadTimer = 0;
+ private Logger log;
+ private boolean running;
+
+ public DeadTimerThread(BGP4Session p, int d) {
+ this.deadTimer = d;
+ this.bgp4Session = p;
+ log=LoggerFactory.getLogger("BGP4Server");
+ }
+
+ public void run() {
+ running=true;
+ while (running) {
+ try {
+ sleep(deadTimer * 1000);
+ /*
+ * Time's over, close PCEP Session
+ */
+ log.warn("DeadTimer OVER");
+ this.bgp4Session.close(/*ObjectParameters.REASON_DEADTIMER*/);
+ return;
+ } catch (InterruptedException e) {
+ //return;
+ if (running==false){
+ log.debug("Ending DeadTimerThread");
+ return;
+ }
+ else {
+ log.debug("Reseting Dead Timer");
+ }
+ } catch (Exception e) {
+ //FIXME: Ver que hacer aqui, por ahora, solo saco un log
+ log.warn("Unhandled exception: " + e.getMessage());
+ }
+
+ }
+
+
+ }
+
+ public void stopRunning(){
+ running=false;
+ }
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/GenericBGP4Session.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/GenericBGP4Session.java
new file mode 100644
index 0000000000000000000000000000000000000000..45636a2fe4e54bc212406bf1bab2a63e2cb5ea78
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/GenericBGP4Session.java
@@ -0,0 +1,908 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import es.tid.bgp.bgp4.messages.BGP4Keepalive;
+import es.tid.bgp.bgp4.messages.BGP4Message;
+import es.tid.bgp.bgp4.messages.BGP4MessageTypes;
+import es.tid.bgp.bgp4.messages.BGP4Open;
+import es.tid.bgp.bgp4.open.BGP4CapabilitiesOptionalParameter;
+import es.tid.bgp.bgp4.open.BGP4OctetsASByteCapabilityAdvertisement;
+import es.tid.bgp.bgp4.open.MultiprotocolExtensionCapabilityAdvertisement;
+import es.tid.bgp.bgp4.update.fields.pathAttributes.AFICodes;
+import es.tid.bgp.bgp4.update.fields.pathAttributes.SAFICodes;
+import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Socket;
+import java.util.Timer;
+
+
+/**
+ * Generic BGP4 Session.
+ * Implements the basics of a BGP4 Session
+ * Any particular session must inherit this one
+ *
+ * @author ogondio
+ *
+ */
+public abstract class GenericBGP4Session extends Thread implements BGP4Session {
+
+ /**
+ * PCEP Session Manager
+ */
+ protected BGP4SessionsInformation BGP4SessionsInformation;
+
+ /**
+ * Thread to send periodic Keepalives
+ */
+ protected KeepAliveThread keepAliveT = null;
+
+ /**
+ * Value of the Keepalive timer set by the Local PCE. Used to send keepalives
+ */
+
+ protected int keepAliveLocal;
+
+ /**
+ * Value of the Keepalive timer of the peer PCC. It is not used in the server!!!
+ */
+ protected int keepAlivePeer;
+
+ /**
+ * Thread to check if the connection is still alive.
+ * If in this time the PCE has not received anything, it closes the session
+ * It is set by the PCC (in this case, the remote peer)
+ */
+ protected DeadTimerThread deadTimerT = null;
+
+ /**
+ * Value of the deadtimer that the PCC sends. It is used in the PCC in the thread
+ */
+ protected int deadTimerPeer;
+
+ /**
+ * Socket of the communication between BGP peers
+ */
+ protected Socket socket = null;
+
+ /**
+ * Remote Peer IP Address
+ * Obtained from the socket for convenience
+ */
+ protected Inet4Address remotePeerIP=null;
+
+ /**
+ * DataOutputStream to send messages to the peer
+ */
+ protected DataOutputStream out=null;
+
+
+
+ /**
+ * DataInputStream to receive messages from PCC
+ */
+ protected DataInputStream in=null;//
+ /**
+ * Queue to send the Computing Path Requests
+ */
+ //protected RequestQueueSend req;
+
+ /**
+ * Logger to write the Parent PCE server log
+ */
+ protected Logger log;
+
+ /**
+ * Timer to schedule KeepWait and OpenWait Timers
+ */
+ protected Timer timer;
+
+ /**
+ * Finite State Machine of the PCEP protocol
+ */
+ protected int FSMstate;
+
+ /**
+ * Remote Domain ID
+ * null if not sent
+ */
+ protected Inet4Address remoteDomainId=null;
+
+ /**
+ * Remote List of OF Codes
+ * If sent by the peer PCE
+ */
+ //private LinkedList remoteOfCodes;//FIME: What do we do with them?
+
+ /**
+ * RemoteOK: a boolean that is set to 1 if the system has received an
+ acceptable Open message.
+ */
+ private boolean remoteOK=false;
+
+ /**
+ *
+ */
+ private boolean localOK=false;
+
+ /**
+ *
+ */
+ private int openRetry=0;
+
+ /**
+ * Byte array to store the last PCEP message read.
+ */
+ protected byte[] msg = null;
+
+ /**
+ * Initial number of the session ID (internal use only)
+ */
+ public static long sessionIdCounter=0;
+
+ /**
+ *
+ */
+ protected Boolean updateFrom;
+ protected boolean sendTo;
+
+ /**
+ * Session ID (internal use only)
+ */
+ private long sessionId;
+ /**************** PARAMETROS DE LA SESION ********************/
+ private int ConnectRetryCounter=0;
+ private ConnectRetryTimer connectRetryTimer = null;
+ private int connectRetryTime; //FIXME: esto aun no se que es.
+
+ /**************PARAMETROS OPEN MESSAGE************************/
+ protected int holdTime;
+ /**
+ * Time between sending keepalives
+ */
+ protected int keepAliveTimer;
+ /**
+ * IP address that is assigned to that BGP speaker
+ */
+ protected Inet4Address BGPIdentifier;
+ /**
+ * Autonomous System number of the sender
+ */
+ protected int myAutonomousSystem;
+ /**
+ * version indicates the protocol version number of the message
+ * it must be 4
+ */
+ protected int version;
+
+
+ public GenericBGP4Session(BGP4SessionsInformation bgp4SessionsInformation,int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem,int mykeepAliveTimer) {
+ log=LoggerFactory.getLogger("BGP4Parser");
+ this.BGP4SessionsInformation=bgp4SessionsInformation;
+ this.holdTime=holdTime;
+ this.BGPIdentifier=BGPIdentifier;
+ this.version = version;
+ this.myAutonomousSystem=myAutonomousSystem;
+ this.keepAliveTimer = mykeepAliveTimer;
+ this.newSessionId();
+
+ }
+
+ /**
+ * Read PCE message from TCP stream
+ * @param in InputStream
+ * @return byte array with a BGP4 Message
+ * @throws IOException Execption thrown trying to read message
+ */
+ protected byte[] readBGP4Msg(DataInputStream in) throws IOException{
+ byte[] ret = null;
+
+ byte[] hdr = new byte[BGP4Message.getBGPHeaderLength()];
+ byte[] temp = null;
+ boolean endHdr = false;
+ int r = 0;
+ int length = 0;
+ boolean endMsg = false;
+ int offset = 0;
+
+ while (!endMsg) {
+ try {
+ if (endHdr) {
+ r = in.read(temp, offset, 1);
+ }
+ else {
+ r = in.read(hdr, offset, 1);
+ }
+ } catch (IOException e){
+ log.warn("Error reading data: "+ e.getMessage());
+ throw e;
+ }catch (Exception e) {
+ log.warn("readMsg Oops: " + e.getMessage());
+ throw new IOException();
+ }
+
+ if (r > 0) {
+ if (offset == BGP4Message.getBGPMarkerLength()) {
+ length = ((int)hdr[offset]&0xFF) << 8;
+ }
+ if (offset == BGP4Message.getBGPMarkerLength() + 1) {
+ length = length | (((int)hdr[offset]&0xFF));
+ temp = new byte[length];
+ endHdr = true;
+ System.arraycopy(hdr, 0, temp, 0, BGP4Message.getBGPHeaderLength());
+ }
+ if ((length > 0) && (offset == length - 1)) {
+ endMsg = true;
+ }
+ offset++;
+ }
+ else if (r==-1){
+ log.debug("End of stream has been reached");
+ throw new IOException();
+ }
+ }
+ if (length > 0) {
+ ret = new byte[length];
+ System.arraycopy(temp, 0, ret, 0, length);
+ }
+ return ret;
+ }
+
+ /**
+ * Read PCE message from TCP stream
+ * @param in InputStream
+ * @return byte array with a BGP4 Message
+ * @throws IOException Execption thrown trying to read message
+ */
+ protected byte[] readMsgOptimized(DataInputStream in) throws IOException{
+ byte[] ret = null;
+
+ byte[] hdr = new byte[4];
+ byte[] temp = null;
+ boolean endHdr = false;
+ int r = 0;
+ int length = 0;
+ boolean endMsg = false;
+ int offset = 0;
+
+
+ while (!endMsg) {
+ try {
+ if (endHdr) {
+ //log.info("Vamos a leer datos ");
+ r = in.read(temp, offset, length-offset);
+ if (r>0){
+ if ((offset+r)>=length){
+ //log.info("Bien ");
+ endMsg=true;
+ }else {
+ offset=offset+r;
+ }
+
+ }
+ else if (r<0){
+ log.error("End of stream has been reached reading data");
+ throw new IOException();
+ }
+ }
+ else {
+ //log.info("Vamos a leer la cabecera ");
+ r = in.read(hdr, offset, 4-offset);
+ if (r < 0) {
+ log.error("End of stream has been reached reading header");
+ throw new IOException();
+ }else if (r >0){
+ if ((offset+r)>=4){
+ length = ( (hdr[offset+2]&0xFF) << 8) | ((hdr[offset+3]&0xFF));
+ offset=4;
+ temp = new byte[length];
+ endHdr = true;
+ System.arraycopy(hdr, 0, temp, 0, 4);
+ if (length==4){
+ endMsg=true;
+ }
+ }else {
+ offset=offset+r;
+ }
+
+ }
+
+ }
+ } catch (IOException e){
+ log.error("Error reading data: "+ e.getMessage());
+ throw e;
+ }catch (Exception e) {
+ log.error("readMsg Oops: " + e.getMessage());
+ log.error("Failure reason : "+e.getStackTrace());
+ throw new IOException();
+ }
+
+ }
+ if (length > 0) {
+ ret = new byte[length];
+ System.arraycopy(temp, 0, ret, 0, length);
+ }
+ return ret;
+ }
+
+
+ // /**
+ // *
Close the PCE session
+ // *
List of reasons (RFC 5440):
+ // * Value Meaning
+ // 1 No explanation provided
+ // 2 DeadTimer expired
+ // 3 Reception of a malformed PCEP message
+ // 4 Reception of an unacceptable number of unknown
+ // requests/replies
+ // 5 Reception of an unacceptable number of unrecognized
+ // PCEP messages
+ // * @param reason Reason for closing the PCEP Session
+ // * @return PCEP Session closed OK
+ // */
+ // public void close(int reason){
+ // log.info("Closing PCEP Session");
+ // BGP4Close p_close=new BGP4Close();
+ // p_close.setReason(reason);
+ // sendPCEPMessage(p_close);
+ // killSession();
+ // }
+ public DataOutputStream getOut() {
+ return out;
+ }
+
+ public void setOut(DataOutputStream out) {
+ this.out = out;
+ }
+
+ /**
+ * Starts the deadTimerThread
+ */
+ protected void startDeadTimer() {
+ this.deadTimerT.start();
+ }
+ /**
+ * Resets the DeadTimerThread
+ * To be called every time a message in the session is received
+ */
+ protected void resetDeadTimer() {
+ if (this.deadTimerT != null) {
+ this.deadTimerT.interrupt();
+ }
+ }
+
+ public Socket getSocket() {
+ return socket;
+ }
+
+ /**
+ * Ends the DeadTimer Thread
+ */
+ protected void cancelDeadTimer() {
+ log.debug("Cancelling DeadTimer");
+ if (this.deadTimerT != null) {
+ this.deadTimerT.stopRunning();
+ this.deadTimerT.interrupt();
+ this.deadTimerT=null;
+ }
+ }
+
+ /**
+ * Starts the Keep Alive Thread
+ */
+ public void startKeepAlive() {
+ this.keepAliveT.start();
+ }
+
+ /**
+ * Ends the KeepAlive Thread
+ */
+ public void cancelKeepAlive() {
+ log.debug("Cancelling KeepAliveTimer");
+ if (this.keepAliveT != null) {
+ this.keepAliveT.stopRunning();
+ this.keepAliveT.interrupt();
+ this.keepAliveT=null;
+ }
+ }
+
+ /**
+ * Ends current connections
+ */
+ protected void endConnections(){
+ try {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (this.socket != null) {
+ log.warn("Closing socket");
+ this.socket.close();
+ }
+
+ } catch (Exception e) {
+ log.warn("Error closing connections: " + e.getMessage());
+ }
+ }
+
+ public int getFSMstate() {
+ return FSMstate;
+ }
+
+ protected void setFSMstate(int fSMstate) {
+ FSMstate = fSMstate;
+ }
+
+ public void killSession(){
+ log.warn("Killing Session");
+ timer.cancel();
+ this.endConnections();
+ this.cancelDeadTimer();
+ this.cancelKeepAlive();
+ this.endSession();
+ this.BGP4SessionsInformation.deleteSession(this.sessionId);
+ log.warn("Interrupting thread!!!!");
+ this.interrupt();
+ }
+
+ /**
+ * DO HERE ANYTHING NEEDED AT CLOSING??
+ * STATISTICS, ETC
+ */
+ protected abstract void endSession();
+
+ protected void initializeBGP4Session() throws BGP4Exception {
+ this.BGP4SessionsInformation.addSession(this.getSessionId(), this);
+
+ /**
+ * Byte array to store the last PCEP message read.
+ */
+ byte[] msg = null;
+ //First get the input and output stream
+ try {
+ out = new DataOutputStream(socket.getOutputStream());
+ in = new DataInputStream(socket.getInputStream());
+ } catch (IOException e) {
+ log.warn("Problem in the sockets, ending BGP4Session");
+ killSession();
+ return;
+ }
+ //- Starts the ConnectRetryTimer with initial value
+ int initialValue=1000;//FIXME: no tengo ni idea de este parametro aun
+ connectRetryTimer= new ConnectRetryTimer(initialValue) ;
+
+ //STARTING PCEP SESSION ESTABLISHMENT PHASE
+ //It begins in Open Wait State
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_OPEN_WAIT);
+ log.debug("Entering BGP4_STATE_OPEN_WAIT, Scheduling Open Wait Timer");
+
+ //Create the 60 seconds Open Wait Timer to wait for an OPEN message
+ OpenWaitTimerTask owtt= new OpenWaitTimerTask(this);
+ this.timer.schedule(owtt, 60000);
+ //Define (Not use yet), the keepwait timer
+ KeepWaitTimerTask kwtt=new KeepWaitTimerTask(this);
+ BGP4Open open_msg=new BGP4Open();
+ //Rellenar:
+ // - My autonomous system
+ // - holdTime
+ // - BGPIdentifier
+ open_msg.setMyAutonomousSystem(myAutonomousSystem);
+ open_msg.setBGPIdentifier(BGPIdentifier);
+ open_msg.setHoldTime(holdTime);
+ //Chek optional parameters
+ BGP4CapabilitiesOptionalParameter cop = new BGP4CapabilitiesOptionalParameter();
+ open_msg.getParametersList().add(cop);
+ MultiprotocolExtensionCapabilityAdvertisement multProtExtCapAdv = new MultiprotocolExtensionCapabilityAdvertisement();
+ multProtExtCapAdv.setAFI(AFICodes.AFI_BGP_LS);
+ multProtExtCapAdv.setSAFI(SAFICodes.SAFI_BGP_LS);
+ cop.getCapabilityList().add(multProtExtCapAdv);
+ BGP4OctetsASByteCapabilityAdvertisement fouroctects = new BGP4OctetsASByteCapabilityAdvertisement();
+ fouroctects.setAS(myAutonomousSystem);
+ cop.getCapabilityList().add(fouroctects);
+
+ //Send the OPEN message
+ this.sendBGP4Message(open_msg);
+ //Now, read messages until we are in SESSION UP
+ while (this.FSMstate!=BGP4StateSession.BGP4_STATE_SESSION_UP){
+ //log.info("State session "+this.FSMstate);
+ try {
+ //Read a new message
+ msg = readBGP4Msg(in);
+
+ }catch (IOException e){
+ log.warn("Error reading message, ending session"+e.getMessage());
+ killSession();
+ return;
+ }
+ if (msg != null) {//If null, it is not a valid PCEP message
+ //log.info("Read a message");
+ switch(BGP4Message.getMessageType(msg)) {
+ case BGP4MessageTypes.MESSAGE_OPEN:
+ //log.info("OPEN Message Received");
+ if (this.FSMstate==BGP4StateSession.BGP4_STATE_OPEN_WAIT){
+ log.debug("FSMstate = BGP4_STATE_OPEN_WAIT");
+ BGP4Open open_received;
+ // try {
+ open_received=new BGP4Open(msg);
+ log.debug("**** Open received ****\n"+ open_received.toString());//FIXME!!! Cambiar a finest
+ owtt.cancel();
+ //Check parameters
+ if (openRetry==1){
+ boolean checkOK=true;
+ this.version = open_received.getVersion();
+ if (this.version != 4){
+ checkOK=false;
+ }
+ // this.deadTimerPeer=open_received.getDeadTimer();
+ // this.keepAlivePeer=open_received.getKeepalive();
+ //
+ // if (this.deadTimerPeer>maxDeadTimerAccepted){
+ // checkOK=false;
+ // }
+ // if (this.deadTimerPeer==0){
+ // if(zeroDeadTimerAccepted==false){
+ // checkOK=false;
+ // }
+ // }
+ // if (this.keepAlivePeer perrobjlist=new LinkedList();
+ // perrobjlist.add(perrorObject);
+ // perror.setErrorObjList(perrobjlist);
+ // perror.setOpen(open_received.getOpen());
+ // log.info("Sending Error with new proposal");
+ // this.sendPCEPMessage(perror);
+ // this.openRetry=this.openRetry+1;
+ /**
+ * o If LocalOK=1, the system restarts the OpenWait timer and stays in
+ the OpenWait state.
+ o If LocalOK=0, the system clears the OpenWait timer, starts the
+ KeepWait timer, and moves to the KeepWait state.
+ */
+ if (localOK==true){
+ //log.info("Local ok esta a true, vamos a open wait");
+ owtt.cancel();
+ owtt= new OpenWaitTimerTask(this);
+ this.timer.schedule(owtt, 60000);
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_OPEN_WAIT);
+ }
+ else {
+ //log.info("Local ok esta a false, vamos a keep wait");
+ owtt.cancel();
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_KEEP_WAIT);
+ this.timer.schedule(kwtt, 60000);
+ }
+ }
+ else {
+ /*
+ * If no errors are detected, and the session characteristics are
+ acceptable to the local system, the system:
+ o Sends a Keepalive message to the PCEP peer,
+ o Starts the Keepalive timer,
+ o Sets the RemoteOK variable to 1.
+ If LocalOK=1, the system clears the OpenWait timer and moves to the
+ UP state.
+ If LocalOK=0, the system clears the OpenWait timer, starts the
+ KeepWait timer, and moves to the KeepWait state.
+ */
+ this.BGPIdentifier=open_received.getBGPIdentifier();
+ this.myAutonomousSystem=open_received.getMyAutonomousSystem();
+ this.holdTime=open_received.getHoldTime();
+// if (open_received.getOptionalParameterLength() != 0){
+// log.info("Tiene parametros opcionales");
+// }
+ //this.BGP4SessionsInformation.addSession(this.getSessionId(), this);
+ BGP4Keepalive p_ka= new BGP4Keepalive();
+ //log.info("Sending Keepalive message");
+ sendBGP4Message(p_ka); //Creates the Keep Wait Timer to wait for a KA to acknowledge the OPEN sent
+ //FIXME: START KA TIMER!
+ this.remoteOK=true;
+ if(this.localOK==true){
+ //log.info("Entering STATE_SESSION_UP");
+ //He conseguido establecer sesion. Hay que matar el otro hilo
+
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_SESSION_UP);
+ //La sesion se ha establecido
+
+ }
+ else {
+ //log.info("Entering STATE_KEEP_WAIT");
+ //log.fine("Scheduling KeepwaitTimer");
+ timer.schedule(kwtt, 60000);
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_KEEP_WAIT);
+ }
+ }
+ }
+ }
+ else{
+ log.debug("Ignore OPEN message, already one received!!");
+ }
+
+ break;
+ case BGP4MessageTypes.MESSAGE_KEEPALIVE:
+ //log.info("KeepAlive Message Received");
+ this.localOK=true;
+ if(this.FSMstate==BGP4StateSession.BGP4_STATE_KEEP_WAIT){
+ // If RemoteOK=1, the system clears the KeepWait timer and moves to
+ // the UP state.
+ // If RemoteOK=0, the system clears the KeepWait timer, starts the
+ // OpenWait timer, and moves to the OpenWait State.
+
+ if (remoteOK==true){
+ kwtt.cancel();
+ //log.info("Entering STATE_SESSION_UP");
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_SESSION_UP);
+ }
+ else{
+ kwtt.cancel();
+ //log.info("Entering OPEN WAIT STATE");
+ owtt=new OpenWaitTimerTask(this);
+ this.timer.schedule(owtt, 60000);
+ this.setFSMstate(BGP4StateSession.BGP4_STATE_OPEN_WAIT);
+ }
+
+ }
+ //If not... seguimos igual que estabamos
+ //Mas KA no hacen mal...
+ break;
+
+ default:
+ log.error("UNEXPECTED Message Received");
+ if (this.FSMstate!=BGP4StateSession.BGP4_STATE_OPEN_WAIT){
+ log.debug("Ignore OPEN message, already one received!!");
+ }
+ else {
+ log.error("Unexpected message RECEIVED, closing");
+
+ }
+ break;
+ }
+ }
+ else {
+ if (this.FSMstate!=BGP4StateSession.BGP4_STATE_OPEN_WAIT){
+ log.info("Ignore message, already one received!!");
+ }
+ else {
+ log.error("Unexpected message RECEIVED, closing");
+
+ }
+ }//Fin del else
+ }//Fin del WHILE
+ }
+
+
+ @Override
+ public void sendBGP4Message(BGP4Message message) {
+ message.encode();
+ try {
+ out.write(message.getBytes());
+ out.flush();
+ } catch (Exception e) {
+ log.error("Problem writing message, finishing session "+e.getMessage());
+ killSession();
+ }
+
+ }
+
+
+ public Inet4Address getRemotePeerIP() {
+ return remotePeerIP;
+ }
+
+
+ public Inet4Address getBGPIdentifier() {
+ return BGPIdentifier;
+ }
+
+ public void setBGPIdentifier(Inet4Address bGPIdentifier) {
+ BGPIdentifier = bGPIdentifier;
+ }
+
+ public Boolean getUpdateFrom() {
+ return updateFrom;
+ }
+
+ public void setUpdateFrom(Boolean updateFrom) {
+ this.updateFrom = updateFrom;
+ }
+
+ public Boolean getSendTo(){
+ return sendTo;
+ }
+
+ public void setSendTo(boolean sendTo) {
+ this.sendTo = sendTo;
+ }
+
+ public int getMyAutonomousSystem() {
+ return myAutonomousSystem;
+ }
+
+ public void setMyAutonomousSystem(int myAutonomousSystem) {
+ this.myAutonomousSystem = myAutonomousSystem;
+ }
+
+
+
+ public String shortInfo(){
+ StringBuffer sb=new StringBuffer(1000);
+ if (this.socket!=null){
+ sb.append("remAddr: ");
+ sb.append(this.socket.getRemoteSocketAddress());
+ sb.append(" state: ");
+ if (this.FSMstate==BGP4StateSession.BGP4_STATE_OPEN_WAIT){
+ sb.append("OPEN_WAIT");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_IDLE){
+ sb.append("IDLE");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_KEEP_WAIT){
+ sb.append("KEEP_WAIT");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
+ sb.append("SESSION_UP");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
+ sb.append("TCP_PENDING");
+ }else {
+ sb.append("UNKNOWN");
+ }
+
+ }
+
+ return sb.toString();
+ }
+
+ public String toString(){
+ StringBuffer sb=new StringBuffer(1000);
+ sb.append("\t> Session ID: "+this.sessionId+"\n");
+ sb.append("\t> BGP Remote Peer: "+this.remotePeerIP+"\n");
+ sb.append("\t> BGPIdentifier: "+this.BGPIdentifier+"\n");
+ if (this.socket!=null){
+ sb.append("\t> remAddr: ");
+ sb.append(this.socket.getRemoteSocketAddress()+"\n");
+ sb.append("\t> state: ");
+ if (this.FSMstate==BGP4StateSession.BGP4_STATE_OPEN_WAIT){
+ sb.append("OPEN_WAIT\n");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_IDLE){
+ sb.append("IDLE\n");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_KEEP_WAIT){
+ sb.append("KEEP_WAIT\n");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
+ sb.append("SESSION_UP\n");
+ }else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
+ sb.append("TCP_PENDING\n");
+ }else {
+ sb.append("UNKNOWN");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ public synchronized void newSessionId(){
+ this.sessionId=GenericBGP4Session.sessionIdCounter+1;
+ sessionIdCounter=sessionIdCounter+1;
+ }
+
+ public long getSessionId() {
+ return sessionId;
+ }
+
+
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (remotePeerIP != null){
+ if (this.remotePeerIP.equals(((GenericBGP4Session)obj).getBGPIdentifier())){
+ return true;
+ }
+ }
+ else {
+ log.info("TODO NUL!! en el equals!");
+ }
+ return false;
+ }
+
+
+ public Inet4Address getPeerIP(){
+ return (Inet4Address)this.socket.getInetAddress();
+ }
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/KeepAliveThread.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/KeepAliveThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..70ebe101f4674582e62ed1c7607947e9ae2e3c33
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/KeepAliveThread.java
@@ -0,0 +1,98 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+import es.tid.bgp.bgp4.messages.BGP4Keepalive;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+
+public class KeepAliveThread extends Thread {
+
+ private int keepAlive = 0;
+ private boolean running;
+ private Logger log;
+ private DataOutputStream out=null; //Use this to send messages to peer
+
+ /*
+ * @param p
+ * @param k
+ */
+ public KeepAliveThread(DataOutputStream out, int k) {
+ this.keepAlive = k;
+ this.out = out;
+ log=LoggerFactory.getLogger("BGP4Server");
+ }
+
+ /**
+ * Starts the Keepalive process
+ */
+ public void run() {
+ running=true;
+ while (running) {
+ try {
+ if (keepAlive > 0) {
+ sleep(keepAlive * 1000);
+ sendKeepAlive();
+ }
+ else {
+ log.debug("Ending KEEPALIVE mechanism");
+ return;
+ }
+ } catch (InterruptedException e) {
+ if (running==false){
+ log.debug("Ending KeepAliveThread");
+ return;
+ }
+ else {
+ //Keepalive Timer is reseted
+ log.debug("Reseting Keepalive timer");
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the running variable to false. After this, an interrupt will cause
+ * the KeepaliveThread to end.
+ */
+ public void stopRunning(){
+ running=false;
+ }
+ /**
+ * Sends KeepAlive Message. It does not wait for any response.
+ */
+ private void sendKeepAlive() {
+ BGP4Keepalive p_ka= new BGP4Keepalive();
+ //try {
+ p_ka.encode();
+// } catch (PCEPProtocolViolationException e1) {
+// // TODO Auto-generated catch block
+// e1.printStackTrace();
+// }
+ try {
+ log.debug("Sending Keepalive message");
+ out.write(p_ka.getBytes());
+ out.flush();
+ } catch (IOException e) {
+ log.warn("Error sending KEEPALIVE: " + e.getMessage());
+ }
+ }
+
+ }
+
+
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/KeepWaitTimerTask.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/KeepWaitTimerTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..3bc72c84d608db79cc28185b63e6ade8d4e1305e
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/KeepWaitTimerTask.java
@@ -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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+
+import java.util.TimerTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * If no Open message is received before the expiration of the OpenWait
+ timer, the PCEP peer sends a PCErr message with Error-Type=1 and
+ Error-value=2, the system releases the PCEP resources for the PCEP
+ peer, closes the TCP connection, and moves to the Idle state.
+
+ * @author Oscar Gonzalez de Dios
+ *
+ */
+public class KeepWaitTimerTask extends TimerTask {
+
+// private DataOutputStream out=null; //Use this to send messages to peer
+ private BGP4Session bgp4Session;
+ private Logger log;
+
+ public KeepWaitTimerTask(BGP4Session bgp4Session){
+ this.bgp4Session=bgp4Session;
+ log=LoggerFactory.getLogger("PCEServer");
+ }
+
+
+ public void run() {
+ log.warn("KEEP WAIT Timer OVER");
+// PCEPError perror=new PCEPError();
+// PCEPErrorObject perrorObject=new PCEPErrorObject();
+// perrorObject.setErrorType(ObjectParameters.ERROR_ESTABLISHMENT);
+// perrorObject.setErrorValue(ObjectParameters.ERROR_ESTABLISHMENT_NO_KA_OR_ERROR_KEEPWAIT_TIMER);
+// ErrorConstruct error_c=new ErrorConstruct();
+// error_c.getErrorObjList().add(perrorObject);
+// perror.setError(error_c);
+// bgp4Session.sendBGP4Message(perror);
+ this.bgp4Session.killSession();
+ return;
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/OpenWaitTimerTask.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/OpenWaitTimerTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..20b77ce4ee14821073bab2bf7b95aabef5fb8cea
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/bgp4session/OpenWaitTimerTask.java
@@ -0,0 +1,59 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.bgp4session;
+
+import java.util.TimerTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * If no Open message is received before the expiration of the OpenWait
+ timer, the PCEP peer sends a PCErr message with Error-Type=1 and
+ Error-value=2, the system releases the PCEP resources for the PCEP
+ peer, closes the TCP connection, and moves to the Idle state.
+
+ * @author Oscar Gonzalez de Dios
+ *
+ */
+public class OpenWaitTimerTask extends TimerTask {
+
+// private DataOutputStream out=null; //Use this to send messages to peer
+ private BGP4Session bgp4Session;
+ private Logger log;
+
+ public OpenWaitTimerTask(BGP4Session bgp4Session){
+ this.bgp4Session=bgp4Session;
+ log=LoggerFactory.getLogger("PCEServer");
+ }
+
+
+ public void run() {
+ log.warn("OPEN WAIT Timer OVER");
+// PCEPError perror=new PCEPError();
+// PCEPErrorObject perrorObject=new PCEPErrorObject();
+// perrorObject.setErrorType(ObjectParameters.ERROR_ESTABLISHMENT);
+// perrorObject.setErrorValue(ObjectParameters.ERROR_ESTABLISHMENT_NO_OPEN_MESSAGE);
+// ErrorConstruct error_c=new ErrorConstruct();
+// error_c.getErrorObjList().add(perrorObject);
+// perror.setError(error_c);
+// log.info("Sending Error");
+// bgp4Session.sendPCEPMessage(perror);
+ this.bgp4Session.killSession();
+ return;
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/grpcApp.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/grpcApp.java
new file mode 100644
index 0000000000000000000000000000000000000000..329404668263441348fa3583adb2b5b107ff71f3
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/grpcApp.java
@@ -0,0 +1,38 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.grpc;
+
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+
+public class grpcApp {
+
+ public static void main( String[] args ) throws Exception
+ {
+ // Create a new server to listen on port 8080
+ Server server = ServerBuilder.forPort(2021)
+ .addService(new updateServiceImpl())
+ .build();
+
+ // Start the server
+ server.start();
+
+ // Server threads are running in the background.
+ System.out.println("Server started");
+ // Don't exit the main thread. Wait until server is terminated.
+ server.awaitTermination();
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/grpcClient.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/grpcClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb1d2354368099c76e69aafab03407295ca2faa2
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/grpcClient.java
@@ -0,0 +1,368 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.grpc;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.net.InetAddresses;
+
+import eu.teraflow.tid.bgp4Peer.models.LinkNLRIMsg;
+import eu.teraflow.tid.bgp4Peer.models.NodeNLRIMsg;
+import eu.teraflow.tid.bgp4Peer.models.UpdateMsg;
+import eu.teraflow.tid.bgp4Peer.models.UpdateMsgList;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo;
+import src.main.proto.GrpcService.linkInfo;
+import src.main.proto.GrpcService.nodeInfo;
+import src.main.proto.GrpcService.NodeDescriptors;
+import src.main.proto.GrpcService.updateRequest;
+import src.main.proto.GrpcService.updateResponse;
+import src.main.proto.updateServiceGrpc;
+import src.main.proto.updateServiceGrpc.updateServiceBlockingStub;
+import src.main.proto.updateServiceGrpc.updateServiceStub;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+public class grpcClient {
+
+ private static final Logger logger = Logger.getLogger(grpcClient.class.getName());
+
+ public static void sendGrpcUpdateMsg(UpdateMsg update) throws Exception{
+
+ updateRequest request=null;
+ nodeInfo n=null;
+ linkInfo unic=null;
+ List l = new ArrayList<>();
+ List nodes = new ArrayList<>();
+ if(update.nodeCheck()==false && update.linkCheck()==false){
+ return;
+ }
+// Build node for grpc message
+ if(update.nodeCheck()!=false) {
+ for(NodeNLRIMsg node : update.getNodeList()){
+ n = nodeInfo.newBuilder().setNodeName(node.getNodeName()).
+ setIgpID(node.getRouterID()).
+ setBgplsID(node.getLocalBgplsID()).
+ setAsID(InetAddresses.coerceToInteger(node.getAs_number())).
+ setLearntFrom(node.getLearntFrom()).
+ buildPartial();
+ nodes.add(n);
+ }
+ }
+ for(LinkNLRIMsg link : update.getLinkList()) {
+
+// String strIPlocal;
+// String strIPremote;
+ String strIgpR;
+ String strIgpL;
+ // LinkNLRIMsg link=update.getLink();
+
+// if(link.getiPv4RouterIDLocalNodeLATLV()==null)
+// strIPlocal="-";
+// else {
+// strIPlocal=link.getiPv4RouterIDLocalNodeLATLV();
+// }
+// if(link.getiPv4RouterIDNeighborNodeLATLV()==null)
+// strIPremote="-";
+// else {
+// strIPremote=link.getiPv4RouterIDNeighborNodeLATLV();
+// }
+
+ if(link.getRemoteNodeIGPId()==null)
+ strIgpR="-";
+ else {
+ strIgpR=link.getRemoteNodeIGPId().toString();
+ }
+ if(link.getLocalNodeIGPId()==null)
+ strIgpL="-";
+ else {
+ strIgpL=link.getLocalNodeIGPId().toString();
+ }
+ String ipv4R;
+ if(link.getiPv4RouterIDNeighborNodeLATLV()==null)
+ ipv4R="-";
+ else {
+ ipv4R=link.getiPv4RouterIDNeighborNodeLATLV();
+ }
+ String ipv4L;
+ if(link.getiPv4RouterIDLocalNodeLATLV()==null)
+ ipv4L="-";
+ else {
+ ipv4L=link.getiPv4RouterIDLocalNodeLATLV();
+ }
+
+// Build link for grpc message. need non null values in some cases
+
+ unic = linkInfo.newBuilder().setLocalID(strIgpR).
+ setLocalIPv4ID(ipv4L).
+ setRemoteID(strIgpL).
+ setRemoteIPv4ID(ipv4R).
+ setLocal(NodeDescriptors.newBuilder().
+ setAsNumber(link.getLocalDomainID().toString()).
+ setBgplsID(link.getLocalBgplsID())).
+ setRemote(NodeDescriptors.newBuilder().
+ setAsNumber(link.getRemoteDomainID().toString()).
+ setBgplsID(link.getRemoteBgplsID())).
+ setAvailableBw(link.getAvailableBw()).
+ setResidualBw(link.getResidualBw()).setUtilized(link.getUtilizedBw()).
+ setMinLinkDelay(link.getMinDelay()).setMaxLinkDelay(link.getMaxDelay()).
+ setDelayVariation(link.getLinkDelayVar()).setDelay(link.getLinkDelay()).
+ setTEDefaultMetric(1).setAdjacencySid("0").setLearntFrom(link.getLearntFrom()).buildPartial();
+
+ l.add(unic);
+ }
+
+ if(nodes.size()==0 && l.size()>0) {
+ request=updateRequest.newBuilder().
+ setNextHop(update.getNextHop().toString()).
+ setAddressFamilyID(Integer.toString(update.getAFI())).
+ setAsPathSegment(Integer.toString(update.getAsPathSegment())).
+ addAllLink(l).build();
+ }else if(nodes.size()>0&& l.size()==0) {
+ // logger.debug("ADDING NODE");
+ request=updateRequest.newBuilder().
+ setNextHop(update.getNextHop().toString()).
+ setAddressFamilyID(Integer.toString(update.getAFI())).
+ setAsPathSegment(Integer.toString(update.getAsPathSegment())).
+ addAllNode(nodes).build();
+ }else {
+ //Error if node name is null
+ // TODO: handle seng grpc error?
+ // logger.debug("ADDING NODE AND LINK");
+ request=updateRequest.newBuilder().
+ setNextHop("-"+update.getNextHop().toString()).
+ setAddressFamilyID(Integer.toString(update.getAFI())).
+ setAsPathSegment(Integer.toString(update.getAsPathSegment())).
+ addAllNode(nodes).addAllLink(l).build();
+
+ }
+ final ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost",2021).usePlaintext().build();
+ updateServiceBlockingStub stub = updateServiceGrpc.newBlockingStub(channel);
+
+ //TODO: this to a function
+ System.out.println("grpcClient request: "+request.toString());
+
+ // channel.awaitTermination(20, TimeUnit.SECONDS);
+ // updateResponse response = stub.update(request);
+ // Espera hasta que el canal esté inactivo
+ updateResponse response = stub.update(request);
+
+ System.out.println("\nRESPUESTA RECIBIDA");
+ System.out.println(response);
+ }
+ // private void shutdownManagedChannel(ManagedChannel managedChannel) {
+ // managedChannel.shutdown();
+ // try {
+ // managedChannel.awaitTermination(mChannelShutdownTimeoutMs, TimeUnit.MILLISECONDS);
+ // } catch (InterruptedException e) {
+ // Thread.currentThread().interrupt();
+ // // Allow thread to exit.
+ // } finally {
+ // managedChannel.shutdownNow();
+ // }
+ // Verify.verify(managedChannel.isShutdown());
+ // }
+ // stub.update(request, new StreamObserver () {
+
+ // public void onNext(updateResponse response) {
+ // System.out.println("respuesta del server: "+response);
+ // }
+ // public void onError(Throwable t) {
+ // System.out.println("error: "+t.getMessage());
+ // latch.countDown();
+ // }
+ // public void onCompleted() {
+ // // Typically you'll shutdown the channel somewhere else.
+ // // But for the purpose of the lab, we are only making a single
+ // // request. We'll shutdown as soon as this request is done.
+ // latch.countDown();
+ // logger.info("gRPC call completed");
+ // System.out.println("OnCompleted");
+ // // channel.shutdownNow();
+ // // try{
+ // // channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
+ // // }catch (InterruptedException e){
+ // // System.out.println("channel error"+e.toString());
+ // // }
+
+ // }
+ // });
+ // latch.await(5, TimeUnit.SECONDS);
+ // channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
+
+ public static void sendGrpc(UpdateMsgList update) {
+ //construir mensaje
+ //update get node,lin,path
+ //getname,ids,as
+ final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:2021").usePlaintext().build();
+ updateServiceStub stub = updateServiceGrpc.newStub(channel);
+
+
+ if(update.getNodeList().isEmpty()&&update.getLinkList().isEmpty()) {
+ return;
+ }
+ updateRequest request=null;
+ nodeInfo n=null;
+ linkInfo l=null;
+ if(!update.getNodeList().isEmpty()) {
+
+ for(NodeNLRIMsg node: update.getNodeList()) {
+
+ n = nodeInfo.newBuilder().setNodeName(node.getNodeName()).setIgpID(node.getLocalBgplsID()).
+ setBgplsID(node.getBgplsID().toString()).setAsID(InetAddresses.coerceToInteger(node.getAs_number())).
+ buildPartial();
+ }
+
+
+ }
+ if(!update.getLinkList().isEmpty()) {
+
+ String strIPlocal;
+ String strIPremote;
+ String strIgpR;
+ String strIgpL;
+
+ for(LinkNLRIMsg link: update.getLinkList()) {
+
+ if(link.getiPv4RouterIDLocalNodeLATLV()==null)
+ strIPlocal="-";
+ else {
+ strIPlocal=link.getiPv4RouterIDLocalNodeLATLV();
+ }
+ if(link.getiPv4RouterIDNeighborNodeLATLV()==null)
+ strIPremote="-";
+ else {
+ strIPremote=link.getiPv4RouterIDNeighborNodeLATLV();
+ }
+
+ if(link.getRemoteNodeIGPId()==null)
+ strIgpR="-";
+ else {
+ strIgpR=link.getRemoteNodeIGPId().toString();
+ }
+ if(link.getLocalNodeIGPId()==null)
+ strIgpL="-";
+ else {
+ strIgpL=link.getLocalNodeIGPId().toString();
+ }
+ String ipv4R;
+ if(link.getiPv4RouterIDNeighborNodeLATLV()==null)
+ ipv4R="-";
+ else {
+ ipv4R=link.getiPv4RouterIDNeighborNodeLATLV();
+ }
+ String ipv4L;
+ if(link.getiPv4RouterIDLocalNodeLATLV()==null)
+ ipv4L="-";
+ else {
+ ipv4L=link.getiPv4RouterIDLocalNodeLATLV();
+ }
+
+// NodeDescriptors local= NodeDescriptors.newBuilder().
+// setAsNumber(link.getLocalDomainID().toString()).
+// setBgplsID(link.getLocalBgplsID()).buildPartial();
+
+
+ l = linkInfo.newBuilder().setLocalID(strIgpR).
+ setLocalIPv4ID(ipv4L).
+ setRemoteID(strIgpL).
+ setRemoteIPv4ID(ipv4R).
+ setLocal(NodeDescriptors.newBuilder().
+ setAsNumber(link.getLocalDomainID().toString()).
+ setBgplsID(link.getLocalBgplsID())).
+ setRemote(NodeDescriptors.newBuilder().
+ setAsNumber(link.getRemoteDomainID().toString()).
+ setBgplsID(link.getRemoteBgplsID())).
+ setAvailableBw(link.getAvailableBw()).
+ setResidualBw(link.getResidualBw()).setUtilized(link.getUtilizedBw()).
+ setMinLinkDelay(link.getMinDelay()).setMaxLinkDelay(link.getMaxDelay()).
+ setDelayVariation(link.getLinkDelayVar()).setDelay(link.getLinkDelay()).
+ setTEDefaultMetric(1).setAdjacencySid("0").buildPartial();
+ }
+
+ }
+ if(n==null) {
+ request = updateRequest.newBuilder().addLink(l).build();
+ }else if(l==null) {
+ request = updateRequest.newBuilder().addNode(n).build();
+ }else {
+ request = updateRequest.newBuilder().addNode(n).addLink(l).build();
+ }
+
+
+
+
+
+ stub.update(request, new StreamObserver () {
+
+ public void onNext(updateResponse response) {
+ System.out.println("respuesta del server: "+response);
+ }
+ public void onError(Throwable t) {
+ System.out.println("error: "+t.getMessage());
+ }
+ public void onCompleted() {
+ // Typically you'll shutdown the channel somewhere else.
+ // But for the purpose of the lab, we are only making a single
+ // request. We'll shutdown as soon as this request is done.
+ System.out.println("channel shutdown");
+ channel.shutdownNow();
+ }
+ });
+
+
+
+
+
+ }
+ public static void main( String[] args ) throws Exception
+ {
+ final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:2021").usePlaintext().build();
+
+ // Replace the previous synchronous code with asynchronous code.
+ // This time use an async stub:
+ updateServiceStub stub = updateServiceGrpc.newStub(channel);
+
+ // Construct a request
+ int a = 123;
+ nodeInfo n = nodeInfo.newBuilder().setNodeName("router 3").setIgpID("1341234").buildPartial();
+ updateRequest request =
+ updateRequest.newBuilder().addNode(n).build();
+
+ // Make an Asynchronous call. Listen to responses w/ StreamObserver
+ stub.update(request, new StreamObserver () {
+
+ public void onNext(updateResponse response) {
+ System.out.println("respuesta del server: "+response);
+ }
+ public void onError(Throwable t) {
+ System.out.println("error: "+t.getMessage());
+ }
+ public void onCompleted() {
+ // Typically you'll shutdown the channel somewhere else.
+ // But for the purpose of the lab, we are only making a single
+ // request. We'll shutdown as soon as this request is done.
+ System.out.println("channel shutdown");
+ channel.shutdownNow();
+ }
+ });
+ }
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/updateServiceImpl.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/updateServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..3010cbbfb9c29e7233adf3110db02192b2c6a1ff
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/grpc/updateServiceImpl.java
@@ -0,0 +1,42 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.grpc;
+
+import io.grpc.stub.StreamObserver;
+import src.main.proto.GrpcService.updateRequest;
+import src.main.proto.GrpcService.updateResponse;
+import src.main.proto.updateServiceGrpc.updateServiceImplBase;
+
+
+public class updateServiceImpl extends updateServiceImplBase{
+
+public void update(updateRequest request, StreamObserver responseObserver) {
+
+ System.out.println(request);
+
+ updateResponse response = updateResponse.newBuilder()
+ .setAck("Update procesado, " + request )
+ .build();
+
+ // Use responseObserver to send a single response back
+ responseObserver.onNext(response);
+
+
+ // When you are done, you must call onCompleted.
+ responseObserver.onCompleted();
+
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/json/bgpMarshal.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/json/bgpMarshal.java
new file mode 100644
index 0000000000000000000000000000000000000000..87d141222e79c454a66d7002ae67bfe5767a998f
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/json/bgpMarshal.java
@@ -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.
+
+package eu.teraflow.tid.bgp4Peer.json;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.codehaus.jackson.JsonEncoding;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+import eu.teraflow.tid.bgp4Peer.models.LinkNLRIMsg;
+import eu.teraflow.tid.bgp4Peer.models.NodeNLRIMsg;
+import eu.teraflow.tid.bgp4Peer.models.PathAttributeMsg;
+import eu.teraflow.tid.bgp4Peer.models.UpdateMsg;
+import eu.teraflow.tid.bgp4Peer.models.UpdateMsgList;
+
+public class bgpMarshal {
+
+
+ ObjectMapper mapper = new ObjectMapper();
+ JsonGenerator g;
+ FileWriter fWriter;
+ public void bgpMarshaller() throws IOException{
+
+
+ mapper.setSerializationInclusion(Inclusion.NON_NULL);
+ mapper.setSerializationInclusion(Inclusion.NON_EMPTY);
+
+
+
+// String jsonStr = mapper.writeValueAsString(node);
+// mapper.writeValue(new File("target/node.json"), nodeList);
+// System.out.println(jsonStr);
+
+ }
+ public void writeFile(UpdateMsgList update) throws JsonGenerationException, JsonMappingException, IOException {
+
+ g = mapper.getJsonFactory().createJsonGenerator(new File("node.json"), JsonEncoding.UTF8);
+// update=update.id2Name();
+ mapper.writeValue(g, update);
+ String temp = mapper.writeValueAsString(update)+"\n";
+// FileOutputStream fos = new FileOutputStream("target/update.json", true);
+// fos.write(temp.getBytes());
+// fos.close();
+ fWriter = new FileWriter("updateWriter.json");
+// if(temp.length()>2)
+ fWriter.write(temp);
+
+
+
+ }
+ public void closeFile() throws IOException {
+ g.close();
+ fWriter.close();
+ }
+
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/management/BGP4ManagementServer.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/management/BGP4ManagementServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f135a446d9f453cae51986fd5ee42666a80418a5
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/management/BGP4ManagementServer.java
@@ -0,0 +1,85 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.management;
+
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionsInformation;
+import eu.teraflow.tid.bgp4Peer.peer.SendTopology;
+import eu.teraflow.tid.tedb.MultiDomainTEDB;
+import eu.teraflow.tid.tedb.TEDB;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.ServerSocket;
+import java.util.Hashtable;
+/**
+ * To manage the server
+ *
+ * @author mcs
+ *
+ */
+public class BGP4ManagementServer extends Thread {
+ private Logger log;
+ private int BGP4ManagementPort = 8888;
+ private BGP4SessionsInformation bgp4SessionsInformation;
+ /**
+ * Topology database for interDomain Links.
+ */
+ private MultiDomainTEDB multiTEDB;
+ /**
+ * Topology database for intradomain Links. It owns several domains.
+ */
+ private Hashtable intraTEDBs;
+
+ /**
+ * Class to send the topology. It is needes to set the parameters sendTopology to true or false.
+ */
+ private SendTopology sendTopology;
+
+ public BGP4ManagementServer(int BGP4ManagementPort, MultiDomainTEDB multiTEDB, Hashtable intraTEDBs, BGP4SessionsInformation bgp4SessionsInformation, SendTopology sendTopology){
+ log =LoggerFactory.getLogger("BGP4Server");
+ this.BGP4ManagementPort = BGP4ManagementPort;
+ this.multiTEDB=multiTEDB;
+ this.intraTEDBs=intraTEDBs;
+ this.bgp4SessionsInformation =bgp4SessionsInformation;
+ this.sendTopology=sendTopology;
+
+ }
+ /**
+ * RUN
+ */
+ public void run(){
+ ServerSocket serverSocket = null;
+ boolean listening=true;
+ try {
+ log.debug("Listening management on port "+BGP4ManagementPort);
+ serverSocket = new ServerSocket(BGP4ManagementPort);
+ }
+ catch (Exception e){
+ log.error("Could not listen management on port "+BGP4ManagementPort);
+ e.printStackTrace();
+ return;
+ }
+
+ try {
+ while (listening) {
+ new BGP4ManagementSession(serverSocket.accept(),multiTEDB,intraTEDBs,bgp4SessionsInformation, sendTopology).start();
+ }
+ serverSocket.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/management/BGP4ManagementSession.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/management/BGP4ManagementSession.java
new file mode 100644
index 0000000000000000000000000000000000000000..18a433e400e593cc66876c3ac264a6c668dd4f80
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/management/BGP4ManagementSession.java
@@ -0,0 +1,199 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.management;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.Inet4Address;
+import java.net.Socket;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionsInformation;
+import eu.teraflow.tid.bgp4Peer.peer.SendTopology;
+import eu.teraflow.tid.bgp4Peer.tedb.IntraTEDBS;
+import eu.teraflow.tid.tedb.DomainTEDB;
+import eu.teraflow.tid.tedb.MultiDomainTEDB;
+import eu.teraflow.tid.tedb.SimpleTEDB;
+import eu.teraflow.tid.tedb.TEDB;
+
+/**
+ *
+ * @author mcs
+ *
+ */
+public class BGP4ManagementSession extends Thread {
+ /**
+ * The socket of the management session
+ */
+ private Socket socket;
+
+ /**
+ * Logger
+ */
+ private Logger log;
+
+ /**
+ * Output Stream of the managament session, to write the answers.
+ */
+ private PrintStream out;
+ /**
+ * Topology database for interDomain Links.
+ */
+ private MultiDomainTEDB multiTEDB;
+ /**
+ * Topology database for intradomain Links. It owns several domains.
+ */
+ private Hashtable intraTEDBs;
+
+ /**
+ * The infomation of all the active sessions
+ */
+ private BGP4SessionsInformation bgp4SessionsInformation;
+ /**
+ * Class to send the topology. It is needes to set the parameters sendTopology to true or false.
+ */
+ private SendTopology sendTopology;
+
+ public BGP4ManagementSession(Socket s,MultiDomainTEDB multiTEDB, Hashtable intraTEDBs,BGP4SessionsInformation bgp4SessionsInformation, SendTopology sendTopology){
+ this.socket=s;
+ log=LoggerFactory.getLogger("BGP4Server");
+ this.multiTEDB=multiTEDB;
+ this.intraTEDBs=intraTEDBs;
+ this.bgp4SessionsInformation= bgp4SessionsInformation;
+ this.sendTopology=sendTopology;
+ }
+
+ public void run(){
+ log.info("Starting Management session");
+ boolean running=true;
+ try {
+ out=new PrintStream(socket.getOutputStream());
+ } catch (IOException e) {
+ log.warn("Management session cancelled: "+e.getMessage());
+ return;
+ }
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ while (running) {
+ //out.print("BGP4:>");
+
+
+
+ out.print("Available commands:\r\n");
+ out.print(" > show topology\r\n");
+ out.print(" > show sessions\r\n");
+ out.print(" > set traces on\r\n");
+ out.print(" > set traces off\r\n");
+ out.print(" > send topology on\r\n");
+ out.print(" > send topology off\r\n");
+ out.print(" > quit\r\n");
+
+
+ String command = null;
+ try {
+ command = br.readLine();
+ } catch (IOException ioe) {
+ log.warn("IO error trying to read your command");
+ return;
+ }
+ if (command.equals("quit")) {
+ log.info("Ending Management Session");
+ out.println("bye!");
+ try {
+ out.close();
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ try {
+ br.close();
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ return;
+ }
+
+// else if (command.equals("help")){
+// out.print("Available commands:\r\n");
+// out.print(" > show topology\r\n");
+// out.print(" > show sessions\r\n");
+// out.print(" > set traces on\r\n");
+// out.print(" > set traces off\r\n");
+// out.print(" > send topology on\r\n");
+// out.print(" > send topology off\r\n");
+// out.print(" > quit\r\n");
+//
+// }
+ else if (command.equals("show sessions")){
+ //Print intradomain and interDomain links
+ out.print(bgp4SessionsInformation.toString());
+ }
+ else if (command.equals("show topology")){
+ //Print intradomain and interDomain links
+ if (multiTEDB != null)
+ out.println(multiTEDB.printTopology());
+ Enumeration domainTedbs=intraTEDBs.keys();
+ while (domainTedbs.hasMoreElements()){
+ String domainID=domainTedbs.nextElement();
+ TEDB ted=intraTEDBs.get(domainID);
+ if (ted instanceof DomainTEDB) {
+ out.println("Intradomain TEDB with ID "+domainID);
+ out.println(ted.printTopology());
+ }
+
+ }
+
+ }
+ else if (command.equals("set traces on")) {
+ //log.setLevel(Level.ALL);
+ Logger log2=LoggerFactory.getLogger("BGP4Parser");
+ //log2.setLevel(Level.ALL);
+ Logger log3=LoggerFactory.getLogger("BGP4Client");
+ //log3.setLevel(Level.ALL);
+ out.print("traces on!\r\n");
+ }
+ else if (command.equals("set traces off")) {
+ //log.setLevel(Level.SEVERE);
+ Logger log2=LoggerFactory.getLogger("BGP4Parser");
+ //log2.setLevel(Level.SEVERE);
+ Logger log3=LoggerFactory.getLogger("BGP4Client");
+ //log3.setLevel(Level.SEVERE);
+ out.print("traces off!\r\n");
+ }
+ else if (command.equals("send topology on")) {
+ sendTopology.setSendTopology(true);
+ }
+ else if (command.equals("send topology off")) {
+ sendTopology.setSendTopology(false);
+ }
+ else{
+ out.print("invalid command\n");
+ out.print("\n");
+ }
+
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/LinkNLRIMsg.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/LinkNLRIMsg.java
new file mode 100644
index 0000000000000000000000000000000000000000..9455ccd1cb9e55ecb85925db19bf62f97cf12703
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/LinkNLRIMsg.java
@@ -0,0 +1,298 @@
+
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.models;
+
+import java.net.Inet4Address;
+import java.util.ArrayList;
+
+import org.slf4j.Logger;
+
+import es.tid.bgp.bgp4.update.fields.LinkNLRI;
+import es.tid.bgp.bgp4.update.tlv.node_link_prefix_descriptor_subTLVs.NodeDescriptorsSubTLV;
+
+public class LinkNLRIMsg {
+
+ private ArrayList nodeDescriptorsSubTLV;
+ // Dominios
+ private Inet4Address localDomainID;
+ private Inet4Address remoteDomainID;
+
+ private Inet4Address areaID;
+ private Inet4Address bgplsID;
+
+ private Inet4Address LocalNodeIGPId;
+ private Inet4Address RemoteNodeIGPId;
+
+ private int linkDelay;
+ private int linkDelayVar;
+ private int minDelay;
+ private int maxDelay;
+ private int linkLoss;
+ private int residualBw;
+ private int availableBw;
+ private int utilizedBw;
+
+ private Inet4Address iPv4RouterIDLocalNodeLATLV;
+ private Inet4Address iPv4RouterIDNeighborNodeLATLV;
+
+ private int IGP_type;
+ private String localIGPID = null;
+ private String remoteIGPID = null;
+ private String localBgplsID;
+ private String remoteBgplsID;
+ private Logger log;
+ private String learntFrom;
+
+ public LinkNLRIMsg(LinkNLRI linkNLRI, String learntFrom) {
+
+ // LinkState vs Link??
+ this.learntFrom = learntFrom;
+
+ if (linkNLRI.getLocalNodeDescriptors().getAutonomousSystemSubTLV() != null) {
+ localDomainID = linkNLRI.getLocalNodeDescriptors().getAutonomousSystemSubTLV().getAS_ID();
+ }
+ if (linkNLRI.getLocalNodeDescriptors().getAreaID() != null) {
+ areaID = linkNLRI.getLocalNodeDescriptors().getAreaID().getAREA_ID();
+ }
+ if (linkNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV() != null) {
+ bgplsID = linkNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV().getBGPLS_ID();
+ }
+ if (linkNLRI.getLocalNodeDescriptors().getIGPRouterID() != null) {
+ LocalNodeIGPId = linkNLRI.getLocalNodeDescriptors().getIGPRouterID().getIpv4AddressOSPF();
+ }
+
+ if (linkNLRI.getRemoteNodeDescriptorsTLV().getAutonomousSystemSubTLV() != null) {
+ remoteDomainID = linkNLRI.getRemoteNodeDescriptorsTLV().getAutonomousSystemSubTLV().getAS_ID();
+ }
+ if (linkNLRI.getRemoteNodeDescriptorsTLV().getAreaID() != null) {
+ areaID = linkNLRI.getRemoteNodeDescriptorsTLV().getAreaID().getAREA_ID();
+ }
+ if (linkNLRI.getRemoteNodeDescriptorsTLV().getBGPLSIDSubTLV() != null) {
+ bgplsID = linkNLRI.getRemoteNodeDescriptorsTLV().getBGPLSIDSubTLV().getBGPLS_ID();
+ }
+ if (linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID() != null) {
+ RemoteNodeIGPId = linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID().getIpv4AddressOSPF();
+ }
+ if (linkNLRI.getUndirectionalLinkDelayTLV() != null) {
+ linkDelay = linkNLRI.getUndirectionalLinkDelayTLV().getDelay();
+ }
+ if (linkNLRI.getUndirectionalDelayVariationTLV() != null) {
+ linkDelayVar = linkNLRI.getUndirectionalDelayVariationTLV().getDelayVar();
+ }
+ if (linkNLRI.getMinMaxUndirectionalLinkDelayTLV() != null) {
+ maxDelay = linkNLRI.getMinMaxUndirectionalLinkDelayTLV().getHighDelay();
+ minDelay = linkNLRI.getMinMaxUndirectionalLinkDelayTLV().getLowDelay();
+ }
+ if (linkNLRI.getUndirectionalLinkLossTLV() != null) {
+ linkLoss = linkNLRI.getUndirectionalLinkLossTLV().getLinkLoss();
+ }
+ if (linkNLRI.getUndirectionalResidualBwTLV() != null) {
+ residualBw = linkNLRI.getUndirectionalResidualBwTLV().getResidualBw();
+ }
+ if (linkNLRI.getUndirectionalAvailableBwTLV() != null) {
+ availableBw = linkNLRI.getUndirectionalAvailableBwTLV().getAvailableBw();
+ }
+ if (linkNLRI.getUndirectionalUtilizedBwTLV() != null) {
+ utilizedBw = linkNLRI.getUndirectionalUtilizedBwTLV().getUtilizedBw();
+ }
+ if (linkNLRI.getIpv4InterfaceAddressTLV() != null) {
+ iPv4RouterIDLocalNodeLATLV = linkNLRI.getIpv4InterfaceAddressTLV().getIpv4Address();
+ }
+ if (linkNLRI.getIpv4NeighborAddressTLV() != null) {
+ iPv4RouterIDNeighborNodeLATLV = linkNLRI.getIpv4NeighborAddressTLV().getIpv4Address();
+ }
+ if (linkNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV().getBGPLS_ID() != null) {// alguna condicion?
+ localBgplsID = linkNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV().getBGPLS_ID().toString();
+ }
+ if (linkNLRI.getRemoteNodeDescriptorsTLV().getBGPLSIDSubTLV().getBGPLS_ID() != null) {// alguna condicion?
+ remoteBgplsID = linkNLRI.getRemoteNodeDescriptorsTLV().getBGPLSIDSubTLV().getBGPLS_ID().toString();
+ }
+ if (linkNLRI.getLocalNodeDescriptors().getIGPRouterID() != null) {
+ IGP_type = linkNLRI.getLocalNodeDescriptors().getIGPRouterID().getIGP_router_id_type();
+ switch (IGP_type) {
+ case 1:
+ localIGPID = Integer.toString(linkNLRI.getLocalNodeDescriptors().getIGPRouterID().getISIS_ISO_NODE_ID());
+ break;
+ case 2:
+ localIGPID = Integer.toString(linkNLRI.getLocalNodeDescriptors().getIGPRouterID().getISIS_ISO_NODE_ID());
+ break;
+ case 3:
+ localIGPID = linkNLRI.getLocalNodeDescriptors().getIGPRouterID().getIpv4AddressOSPF().toString();
+
+ break;
+ default:
+ log.info("añadir este tipo de IGP Identifier por implementar ");
+ }
+ }
+ if (linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID() != null) {
+ IGP_type = linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID().getIGP_router_id_type();
+ switch (IGP_type) {
+ case 1:
+ remoteBgplsID = Integer.toString(linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID().getISIS_ISO_NODE_ID());
+ break;
+ case 2:
+ remoteBgplsID = Integer.toString(linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID().getISIS_ISO_NODE_ID());
+ case 3:
+ remoteIGPID = linkNLRI.getRemoteNodeDescriptorsTLV().getIGPRouterID().getIpv4AddressOSPF().toString();
+ break;
+ default:
+ log.info("añadir este tipo de IGP Identifier por implementar ");
+ }
+ }
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + localBgplsID.hashCode();
+ result = 31 * result + iPv4RouterIDLocalNodeLATLV.hashCode();
+ result = 31 * result + iPv4RouterIDNeighborNodeLATLV.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+ if (!(o instanceof LinkNLRIMsg)) {
+ return false;
+ }
+ LinkNLRIMsg linkCk = (LinkNLRIMsg) o;
+ return linkCk.localBgplsID == localBgplsID && linkCk.iPv4RouterIDLocalNodeLATLV == iPv4RouterIDLocalNodeLATLV
+ && linkCk.localBgplsID == localBgplsID
+ && linkCk.iPv4RouterIDLocalNodeLATLV == iPv4RouterIDLocalNodeLATLV;
+ }
+
+ public String toString() {// check type
+ String out = "";
+ if (this.localBgplsID != null)
+ out = out + "ID: " + this.localBgplsID + " ";// esto es id router??
+ if (this.iPv4RouterIDLocalNodeLATLV != null)
+ out = out + this.iPv4RouterIDLocalNodeLATLV.toString();
+ if(this.localIGPID!=null)
+ out = out + " localIGPID: "+ this.localIGPID;
+ if (this.iPv4RouterIDNeighborNodeLATLV != null)
+ out = out + "---->" + this.iPv4RouterIDNeighborNodeLATLV.toString();
+ if(this.remoteIGPID!=null)
+ out = out + " remoteIGPID: "+ this.remoteIGPID;
+ if (this.remoteBgplsID != null)
+ out = out + "ID: " + this.remoteBgplsID + " ";
+ if (this.localDomainID != null)
+ out = out + "\n AS_ID local: " + this.localDomainID.toString() + " ";
+ if (this.remoteDomainID != null)
+ out = out + "\n AS_ID remote: " + this.remoteDomainID.toString() + " ";
+ if (this.availableBw != 0)
+ out = out + "\n availableBW: " + this.availableBw + " ";
+ if (this.residualBw != 0)
+ out = out + "\n residualBw: " + this.residualBw + " ";
+ if (this.linkDelay != 0)
+ out = out + "\n linkDelay: " + this.linkDelay + " ";
+ return out;
+
+ }
+
+ public String getLearntFrom() {
+ return learntFrom;
+ }
+
+ public void setLearntFrom(String learntFrom) {
+ this.learntFrom = learntFrom;
+ }
+
+ public String getiPv4RouterIDLocalNodeLATLV() {
+ if (iPv4RouterIDLocalNodeLATLV != null)
+ return iPv4RouterIDLocalNodeLATLV.toString();
+ else
+ return null;// NO DEBERIA SER NULL
+ }
+
+ public void setiPv4RouterIDLocalNodeLATLV(Inet4Address iPv4RouterIDLocalNodeLATLV) {
+ this.iPv4RouterIDLocalNodeLATLV = iPv4RouterIDLocalNodeLATLV;
+ }
+
+ public String getiPv4RouterIDNeighborNodeLATLV() {
+ if (iPv4RouterIDNeighborNodeLATLV != null)
+ return iPv4RouterIDNeighborNodeLATLV.toString();
+ else
+ return null;// NO DEBERIA SER NULL
+ }
+
+ public void setiPv4RouterIDNeighborNodeLATLV(Inet4Address iPv4RouterIDNeighborNodeLATLV) {
+ this.iPv4RouterIDNeighborNodeLATLV = iPv4RouterIDNeighborNodeLATLV;
+ }
+
+ public Inet4Address getLocalDomainID() {
+ return localDomainID;
+ }
+
+ public Inet4Address getRemoteDomainID() {
+ return remoteDomainID;
+ }
+
+ public String getLocalBgplsID() {
+ return this.localBgplsID;
+ }
+
+ public void setLocalBgplsID(String localBgplsID) {
+ this.localBgplsID = localBgplsID;
+ }
+
+ public String getRemoteBgplsID() {
+ return this.remoteBgplsID;
+ }
+
+ public void setRemoteBgplsID(String remoteBgplsID) {
+ this.remoteBgplsID = remoteBgplsID;
+ }
+
+ public Inet4Address getLocalNodeIGPId() {
+ return LocalNodeIGPId;
+ }
+
+ public Inet4Address getRemoteNodeIGPId() {
+ return RemoteNodeIGPId;
+ }
+
+ public int getLinkDelay() {
+ return linkDelay;
+ }
+
+ public int getLinkDelayVar() {
+ return linkDelayVar;
+ }
+
+ public int getMinDelay() {
+ return minDelay;
+ }
+
+ public int getMaxDelay() {
+ return maxDelay;
+ }
+
+ public int getResidualBw() {
+ return residualBw;
+ }
+
+ public int getAvailableBw() {
+ return availableBw;
+ }
+
+ public int getUtilizedBw() {
+ return utilizedBw;
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/NodeNLRIMsg.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/NodeNLRIMsg.java
new file mode 100644
index 0000000000000000000000000000000000000000..958544f63b30a81480e25e78ae3ea3e578a9a7cd
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/NodeNLRIMsg.java
@@ -0,0 +1,197 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.models;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.net.InetAddresses;
+
+import es.tid.bgp.bgp4.update.fields.LinkNLRI;
+import es.tid.bgp.bgp4.update.fields.NodeNLRI;
+import es.tid.bgp.bgp4.update.tlv.node_link_prefix_descriptor_subTLVs.NodeDescriptorsSubTLV;
+
+public class NodeNLRIMsg {
+
+ private ArrayList nodeDescriptorsSubTLV;
+ // Dominios
+ private Inet4Address localDomainID;
+ private Inet4Address remoteDomainID;
+ private Inet4Address areaID;
+ private Inet4Address bgplsID;
+
+ private Inet4Address LocalNodeBGPId;
+
+ private Inet4Address iPv4RouterIDLocalNodeLATLV;
+ private Inet4Address iPv4RouterIDNeighborNodeLATLV;
+
+ private String localBgplsID;
+ private int remoteBgplsID;
+
+ private Inet4Address as_number;
+
+ private int IGP_type;
+ private Inet4Address IGPID = null;
+ private Logger log;
+ private String nodeName;
+ private String ISIS_ID_str;
+ private String router_id="-";
+
+ private String learntFrom;
+
+ public NodeNLRIMsg(NodeNLRI nodeNLRI, String learntFrom, String nodeName) {
+
+ log = LoggerFactory.getLogger("BGP4Server");// prueba logger
+
+ this.learntFrom = learntFrom;
+
+ if (nodeNLRI.getLocalNodeDescriptors().getAutonomousSystemSubTLV() != null) {
+ // inetAddr???
+ as_number = nodeNLRI.getLocalNodeDescriptors().getAutonomousSystemSubTLV().getAS_ID();
+ }
+ if (nodeNLRI.getLocalNodeDescriptors().getAreaID() != null) {
+ areaID = nodeNLRI.getLocalNodeDescriptors().getAreaID().getAREA_ID();
+ }
+ if (nodeNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV() != null) {
+ localBgplsID=nodeNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV().getBGPLS_ID().toString();
+ }
+
+ if (nodeNLRI.getLocalNodeDescriptors().getIGPRouterID() != null) {
+ IGP_type = nodeNLRI.getLocalNodeDescriptors().getIGPRouterID().getIGP_router_id_type();
+ switch (IGP_type) {
+ case 1:
+ ISIS_ID_str = Integer.toString(nodeNLRI.getLocalNodeDescriptors().getIGPRouterID().getISIS_ISO_NODE_ID());
+ router_id=ISIS_ID_str;
+ case 2:
+ ISIS_ID_str = Integer.toString(nodeNLRI.getLocalNodeDescriptors().getIGPRouterID().getISIS_ISO_NODE_ID());
+ router_id=ISIS_ID_str;
+ case 3:
+ IGPID = nodeNLRI.getLocalNodeDescriptors().getIGPRouterID().getIpv4AddressOSPF();
+ if(IGPID!=null){
+ router_id=IGPID.toString();
+ }else{
+ System.out.println("Null IGPID (type OSPF)");
+ }
+ break;
+ default:
+ log.info("añadir este tipo de IGP Identifier por implementar ");
+ }
+ }
+
+ if (nodeNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV() != null) {
+ if (nodeNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV().getBGPLS_ID() != null) {
+ LocalNodeBGPId = nodeNLRI.getLocalNodeDescriptors().getBGPLSIDSubTLV().getBGPLS_ID();
+ }
+ }
+
+ if (nodeName != null) {
+ this.nodeName = nodeName;
+ }else{
+ this.nodeName= this.router_id;
+ }
+ log.info("End node processing");
+ }
+
+ public String toString() {// check type
+ // TODO: concatenate with stringBuffer
+
+ String out = "";
+ if (this.router_id != null)
+ out = out + "ID: " + this.router_id + " ";// esto es id router??
+ if (this.iPv4RouterIDLocalNodeLATLV != null)
+ out = out + this.iPv4RouterIDLocalNodeLATLV.toString();
+ if (this.iPv4RouterIDNeighborNodeLATLV != null)
+ out = out + "---->" + this.iPv4RouterIDNeighborNodeLATLV.toString();
+ if(this.LocalNodeBGPId!=null)
+ out=out+"BGP_ID: "+this.LocalNodeBGPId+" ";
+ if(this.as_number!=null)
+ out=out+"AS_number: "+InetAddresses.coerceToInteger(this.as_number)+" ";
+ if (this.nodeName != null)
+ out = out + "Name node attribute: " + nodeName + " ";
+ if (this.ISIS_ID_str != null)
+ out = out + "ID node: " + this.ISIS_ID_str + " ";
+ if (this.as_number != null)
+ out = out + "AS number: " + this.as_number.toString() + " ";
+ return out;
+
+ }
+
+ public String getLearntFrom() {
+ return learntFrom;
+ }
+
+ public void setLearntFrom(String learntFrom) {
+ this.learntFrom = learntFrom;
+ }
+
+ public String getLocalBgplsID() {
+ return this.localBgplsID;
+ }
+
+ public void setLocalBgplsID(String localBgplsID) {
+ this.localBgplsID = localBgplsID;
+ }
+
+ public String getNodeName() {
+ return nodeName;
+ }
+
+ public Inet4Address getIGPID() {
+ return IGPID;
+ }
+
+ public Inet4Address getBgplsID() {
+ return bgplsID;
+ }
+
+ public String getRouterID(){
+ return router_id;
+ }
+
+ public void setBgplsID(Inet4Address bgplsID) {
+ this.bgplsID = bgplsID;
+ }
+
+ public Inet4Address getAs_number() {
+ return as_number;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + localBgplsID.hashCode();
+ result = 31 * result + iPv4RouterIDLocalNodeLATLV.hashCode();
+ result = 31 * result + iPv4RouterIDNeighborNodeLATLV.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+ if (!(o instanceof NodeNLRIMsg)) {
+ return false;
+ }
+ NodeNLRIMsg nodeCk = (NodeNLRIMsg) o;
+ return nodeCk.localBgplsID == localBgplsID && nodeCk.iPv4RouterIDLocalNodeLATLV == iPv4RouterIDLocalNodeLATLV
+ && nodeCk.localBgplsID == localBgplsID
+ && nodeCk.iPv4RouterIDLocalNodeLATLV == iPv4RouterIDLocalNodeLATLV;
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/PathAttributeMsg.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/PathAttributeMsg.java
new file mode 100644
index 0000000000000000000000000000000000000000..11bf355d06af41b76eac9fc63f1df7c63628c5df
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/PathAttributeMsg.java
@@ -0,0 +1,89 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.models;
+
+import java.net.Inet4Address;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+import es.tid.bgp.bgp4.update.fields.pathAttributes.LinkStateAttribute;
+import es.tid.bgp.bgp4.update.tlv.BGP4TLVFormat;
+import es.tid.bgp.bgp4.update.tlv.linkstate_attribute_tlvs.IPv4RouterIDLocalNodeLinkAttribTLV;
+import es.tid.bgp.bgp4.update.tlv.linkstate_attribute_tlvs.NodeNameNodeAttribTLV;
+
+public class PathAttributeMsg {
+
+
+ private NodeNameNodeAttribTLV nodeNameTLV;
+ private byte[] data;
+ private String nodeName;
+ private Inet4Address addrLocal;
+
+
+ public PathAttributeMsg(LinkStateAttribute att) {
+
+
+ if(att.getNodeNameTLV()!=null) {
+
+ nodeNameTLV=att.getNodeNameTLV();
+ data=nodeNameTLV.getTlv_bytes();
+ int b = nodeNameTLV.getTotalTLVLength();
+ int c = nodeNameTLV.getTLVValueLength();
+ byte [] fin= Arrays.copyOfRange(data, b - c, b);
+ nodeName = new String(fin , StandardCharsets.UTF_8);
+ }
+ if(att.getIPv4RouterIDLocalNodeLATLV()!=null) {
+ addrLocal=att.getIPv4RouterIDLocalNodeLATLV().getIpv4Address();
+ }
+
+ }
+ public String toString() {
+ String out="";
+ if(this.nodeName!=null)
+ out=out+"NODE name "+nodeName;
+ if(this.addrLocal!=null)
+ out=out+"NODE IP "+addrLocal.toString();
+
+ return out;
+ }
+
+ public String getNodeName() {
+ return nodeName;
+ }
+ public void setNodeName(String nodeName) {
+ this.nodeName = nodeName;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + nodeName.hashCode();
+ return result;
+ }
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof PathAttributeMsg)) {
+ return false;
+ }
+ PathAttributeMsg pathCk = (PathAttributeMsg) o;
+ return pathCk.nodeName == nodeName;
+ }
+ public Inet4Address getAddrLocal() {
+ return addrLocal;
+ }
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/UpdateMsg.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/UpdateMsg.java
new file mode 100644
index 0000000000000000000000000000000000000000..37d87e6836734989ec38d08741f51495262c7d3b
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/UpdateMsg.java
@@ -0,0 +1,99 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.models;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+public class UpdateMsg {
+
+ private int AFI;
+ private int asPathSegment;
+ private InetAddress nextHop;
+ private String learntFrom;
+
+ private NodeNLRIMsg node;
+ private LinkNLRIMsg link;
+ private PathAttributeMsg path;
+ private List linkList = new ArrayList<>();
+ private List nodeList = new ArrayList<>();
+
+ public List getLinkList(){
+ return this.linkList;
+ }
+ public List getNodeList(){
+ return this.nodeList;
+ }
+ public void addNode(NodeNLRIMsg node) {
+ this.nodeList.add(node);
+ }
+ public int getAFI() {
+ return AFI;
+ }
+ public String getLearntFrom() {
+ return learntFrom;
+ }
+ public void setLearntFrom(String learntFrom) {
+ this.learntFrom = learntFrom;
+ }
+ public void setAFI(int aFI) {
+ AFI = aFI;
+ }
+ public int getAsPathSegment() {
+ return asPathSegment;
+ }
+ public void setAsPathSegment(int asPathSegment) {
+ this.asPathSegment = asPathSegment;
+ }
+ public InetAddress getNextHop() {
+ return nextHop;
+ }
+ public void setNextHop(InetAddress nextHop) {
+ this.nextHop = nextHop;
+ }
+ public NodeNLRIMsg getNode() {
+ return node;
+ }
+ public void setNode(NodeNLRIMsg node) {
+ this.node = node;
+ }
+ // public LinkNLRIMsg getLink() {
+ // return link;
+ // }
+ public boolean linkCheck(){
+ return linkList.size()>0;
+ }
+ public boolean nodeCheck(){
+ return nodeList.size()>0;
+ }
+ public void setLink(LinkNLRIMsg link) {
+ this.link = link;
+ }
+ public void addLink(LinkNLRIMsg link) {
+ this.linkList.add(link);
+ }
+ public PathAttributeMsg getPath() {
+ return path;
+ }
+ public void setPath(PathAttributeMsg path) {
+ this.path = path;
+ }
+
+
+
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/UpdateMsgList.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/UpdateMsgList.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fd30c6cbf5f080676cc43eceaf267e6d2faedff
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/models/UpdateMsgList.java
@@ -0,0 +1,151 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.models;
+
+import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+
+public class UpdateMsgList {
+
+
+ /* Print purposes and debug*/
+ List nodeList = new LinkedList<>();
+ List linkList = new LinkedList<>();
+ List pathList = new LinkedList<>();
+ /**/
+ public UpdateMsgList() {
+ }
+
+
+ public String toString() {
+
+ String out ="Update Message: ";
+ if(nodeList!=null) {
+ out=out+nodeList.toString()+"\n";
+ }
+ if(linkList!=null) {
+ out=out+linkList.toString()+"\n";
+ }
+ if(pathList!=null) {
+ out=out+pathList.toString()+"\n";
+ }
+
+ return out;
+
+ }
+ public void addLinkToJson(LinkNLRIMsg link) {
+
+ if(link==null)
+ return;
+ boolean exists = false;
+ for (LinkNLRIMsg linkInList : linkList) { // list being the LinkedList
+ if (link.equals(linkInList)) {
+ exists = true;
+ break;
+ }
+ }
+ if (!exists) {
+ linkList.add(link);
+ }
+ }
+ public void addNodeToJson(NodeNLRIMsg node, String currentName) {//comprobar que existe?
+
+ if(node==null)
+ return;
+ boolean exists = false;
+ for (NodeNLRIMsg nodeInList : nodeList) { // list being the LinkedList
+ if (node.equals(nodeInList)) {
+ exists = true;
+ break;
+ }
+ }
+ if (!exists) {
+ nodeList.add(node);
+ }
+
+ }
+ public void addpathToJson(PathAttributeMsg path) {
+
+ boolean exists = false;
+ if(path.getNodeName()==null) {
+ return;
+ }
+ for (PathAttributeMsg pathInList : pathList) { // list being the LinkedList
+ if (path.equals(pathInList) ) {
+ exists = true;
+ break;
+ }
+ }
+ if (!exists) {
+ pathList.add(path);
+ }
+
+ }
+
+ public List getNodeList() {
+ return nodeList;
+ }
+
+ public List getLinkList() {
+ return linkList;
+ }
+
+ public List getPathList() {
+ return pathList;
+ }
+
+ public void addNodeToList(NodeNLRIMsg node) {
+ nodeList.add(node);
+ }
+ public void addLinkToList(LinkNLRIMsg link) {
+ linkList.add(link);
+ }
+ public void addPathToList(PathAttributeMsg path) {
+ pathList.add(path);
+ }
+
+ public UpdateMsgList id2Name() {
+
+ UpdateMsgList update=new UpdateMsgList();
+ update.nodeList=this.nodeList;
+ update.pathList=this.pathList;
+ List newLinkList = new LinkedList<>();
+
+ for (LinkNLRIMsg linkInList : linkList) {
+ LinkNLRIMsg link=linkInList;
+
+ for(NodeNLRIMsg nodeInList: update.nodeList) {
+ if((linkInList.getLocalBgplsID().equals(nodeInList.getLocalBgplsID()))) {
+ link.setLocalBgplsID(nodeInList.getNodeName());
+ }
+ }
+
+ for(NodeNLRIMsg nodeInList: update.nodeList) {
+ if((linkInList.getRemoteBgplsID().equals(nodeInList.getLocalBgplsID()))) {
+ link.setRemoteBgplsID(nodeInList.getNodeName());
+ }
+ }
+
+
+ newLinkList.add(link);
+ }
+ update.linkList=newLinkList;
+
+ return update;
+
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4Exception.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4Exception.java
new file mode 100644
index 0000000000000000000000000000000000000000..736f6cd3eee8e9ebac12875dcc30407a0e63e8de
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4Exception.java
@@ -0,0 +1,20 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+public class BGP4Exception extends Exception {
+
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4LSPeerInfo.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4LSPeerInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..768e4a87b4d85e7355d3359b78e140880f2792d0
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4LSPeerInfo.java
@@ -0,0 +1,85 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+import java.net.Inet4Address;
+
+public class BGP4LSPeerInfo {
+ /**
+ * IP Address of the remote Peer
+ */
+ private Inet4Address peerIP;
+
+ /**
+ * Experimental USE Only
+ * Default port is 179
+ * For testing and development, alternative ports are allowed.
+ */
+ private int peerPort;
+
+ /**
+ * If the remote peer is a consumer and we need to send the topology
+ */
+ private boolean sendToPeer;
+
+ /**
+ * If the remote peer is a generator of topology and we are consumers
+ */
+ private boolean updateFromPeer;
+
+
+
+ public BGP4LSPeerInfo() {
+ this.peerPort=179;
+ }
+
+ public Inet4Address getPeerIP() {
+ return peerIP;
+ }
+
+ public void setPeerIP(Inet4Address peerIP) {
+ this.peerIP = peerIP;
+ }
+
+ public int getPeerPort() {
+ return peerPort;
+ }
+
+ public void setPeerPort(int peerPort) {
+ this.peerPort = peerPort;
+ }
+
+ public boolean isSendToPeer() {
+ return sendToPeer;
+ }
+
+ public void setSendToPeer(boolean sendToPeer) {
+ this.sendToPeer = sendToPeer;
+ }
+
+ public boolean isUpdateFromPeer() {
+ return updateFromPeer;
+ }
+
+ public void setUpdateFromPeer(boolean updateFromPeer) {
+ this.updateFromPeer = updateFromPeer;
+ }
+
+
+
+
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4Parameters.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4Parameters.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8958d306e3d11e7a3a569d59773ad4351770eea
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4Parameters.java
@@ -0,0 +1,540 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+
+/**
+ * Parameters to configure the BGP4 session
+ * @author mcs
+ *
+ */
+public class BGP4Parameters {
+
+ private Logger log = LoggerFactory.getLogger("BGP4Peer");
+ /**
+ * TCP port where the BGP is listening for incoming bgp4 connections
+ * Experimental use only. Default and standard is 179
+ */
+ private int BGP4Port = 179;
+
+ /**
+ * TCP port to connect to manage the BGP connection
+ */
+ private int BGP4ManagementPort = 1112;
+ /**
+ * Local BGP4 address of this peer
+ */
+ private String localBGPAddress = "127.0.0.1";
+ /**
+ * Local port to connect with BGP Peer.
+ */
+ private int localBGPPort = 0;
+ /**
+ * Log file
+ */
+ private String BGP4LogFile="BGP4Parser.log";
+ /**
+ * Log file Client
+ */
+ private String BGP4LogFileClient="BGP4Client.log";
+
+
+ /**
+ * Log file Client
+ */
+ private String BGP4LogFileServer="BGP4Server.log";
+
+
+ /**
+ * Name of the configuration file
+ */
+ private String confFile;
+
+ /**
+ * If the tcp no delay option is used or not.
+ */
+ private boolean nodelay=false;
+ /**
+ * Waiting Time to connect to clients
+ */
+ long delay = 6000;
+ /**
+ * List of peers to establish connection.
+ */
+ private LinkedList peersToConnect;
+
+ /**
+ * Parameter used to set traces meanwhile the execution.
+ */
+ private boolean setTraces=true;
+ /**
+ * OPEN PARAMENTERS
+ */
+ int holdTime=90;
+ /**
+ * OPEN PARAMENTERS
+ */
+
+ private boolean isTest=false;
+
+ /**
+ * Time between sending keepalives
+ */
+ int keepAliveTimer=30;
+
+ /**
+ * Time between topology updates
+ */
+ long sendTopoDelay=30000;
+
+ private boolean saveTopologyDB=false;
+
+ private Inet4Address topologyDBIP;
+
+ private int topologyDBport;
+
+ public int getKeepAliveTimer() {
+ return keepAliveTimer;
+ }
+ public void setKeepAliveTimer(int keepAliveTimer) {
+ this.keepAliveTimer = keepAliveTimer;
+ }
+ String BGPIdentifier = null;
+ int myAutonomousSystem=1;
+ int version=0x04;
+
+ /**
+ * This parameter can have three options: fromXML, fromOSPF, fromBGP
+ * Explain the way the topology module learns the topology
+ */
+ private String learnTopology="fromBGP";
+ /**
+ * XML File to read and generate the topology
+ */
+ private String topologyFile;
+
+
+ private int numberTriesToConnect=3;
+ /**
+ * True: This peer sends the interdomain links of the topology to other peers
+ * False: This peer does NOT send the topology to other peers
+ */
+ private boolean sendTopology=false;
+ /**
+ * True: This peer sends the whole topology to other peers
+ * False: This peer does NOT send the intradomain linksto other peers
+ */
+ private boolean sendIntradomainLinks=false;
+
+
+
+ /**
+ * Instance identifier for NodeNLRI (Types defined in class InstanceIDTypes)
+ */
+ private int instanceID=0;
+ /**
+ * Constructor
+ */
+ BGP4Parameters(){
+ confFile="BGP4Parameters.xml";
+ peersToConnect =new LinkedList();
+ }
+ /**
+ * Constructor
+ */
+ BGP4Parameters(String confFile){
+ peersToConnect =new LinkedList();
+
+ if (confFile!=null){
+ this.confFile=confFile;
+ }else {
+ confFile="BGP4Parameters.xml";
+ }
+
+ }
+
+
+
+ public void initialize(){
+
+ try {
+
+ System.out.println("Parsing Config File::"+confFile);
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser saxParser = factory.newSAXParser();
+
+
+ DefaultHandler handler = new DefaultHandler() {
+ boolean peer = false;
+ boolean send = false;
+ boolean receive = false;
+ boolean peerPort = false;
+ BGP4LSPeerInfo peerInfo=null;
+
+ String tempVal;
+
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes)
+ throws SAXException {
+
+ if (qName.equalsIgnoreCase("configPeer")){
+ log.debug("Found peer configuration");
+ }
+ else if (qName.equalsIgnoreCase("peer")){
+ peer = true;
+ }
+ else if (qName.equalsIgnoreCase("export")){
+ send = true;
+ }
+ else if (qName.equalsIgnoreCase("import")){
+ receive = true;
+ }else if (qName.equalsIgnoreCase("peerPort")){
+ peerPort = true;
+ }
+
+ }
+
+ public void endElement(String uri, String localName,
+ String qName)
+ throws SAXException {
+ if(qName.equalsIgnoreCase("BGP4Port")) {
+ BGP4Port=Integer.parseInt(tempVal.trim());
+
+ }
+ else if (qName.equalsIgnoreCase("BGP4ManagementPort")){
+ BGP4ManagementPort = Integer.parseInt(tempVal.trim());
+ }
+
+ else if (qName.equalsIgnoreCase("BGP4LogFile")) {
+ BGP4LogFile=tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("BGP4LogFileClient")) {
+ BGP4LogFileClient=tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("BGP4LogFileServer")) {
+ BGP4LogFileServer=tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("nodelay")) {
+ nodelay=Boolean.parseBoolean(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("isTest")) {
+ isTest=Boolean.parseBoolean(tempVal.trim());
+ }
+
+ else if (qName.equalsIgnoreCase("setTraces")) {
+ setTraces=Boolean.parseBoolean(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("saveTopologyDB")) {
+ saveTopologyDB=Boolean.parseBoolean(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("topologyDBIP")) {
+ try {
+ topologyDBIP =(Inet4Address)Inet4Address.getByName(tempVal.trim());
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ else if (qName.equalsIgnoreCase("topologyDBport")) {
+ topologyDBport=Integer.parseInt(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("sendTopology")) {
+ sendTopology=Boolean.parseBoolean(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("sendIntradomainLinks")) {
+ sendIntradomainLinks=Boolean.parseBoolean(tempVal.trim());
+ sendTopology = true;//si se envian los intradomain entonces se enviara la topologia entera
+ }
+
+
+ else if(qName.equalsIgnoreCase("holdTime")) {
+ holdTime=Integer.parseInt(tempVal.trim());
+ }
+ else if(qName.equalsIgnoreCase("keepAliveTimer")) {
+ keepAliveTimer=Integer.parseInt(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("version")){
+ version = Integer.parseInt(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("myAutonomousSystem")){
+ myAutonomousSystem = Integer.parseInt(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("localBGPAddress")){//El BGP Identifier es la local BGP Address.
+ //BGPIdentifier = tempVal.trim();
+ localBGPAddress=tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("BGPIdentifier")){//El BGP Identifier es la local BGP Address.
+ BGPIdentifier = tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("delay")){
+ delay = Long.parseLong(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("sendTopoDelay")){
+ sendTopoDelay = Long.parseLong(tempVal.trim());
+ }
+ /*
+ else if (qName.equalsIgnoreCase("peer")){
+ String peerBGP_IPaddress = tempVal.trim();
+ peersToConnect.add(peerBGP_IPaddress);
+ }*/
+ else if (qName.equalsIgnoreCase("TopologyFile")) {
+ topologyFile=tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("learnTopology")) {
+ learnTopology=tempVal.trim();
+ }
+ else if (qName.equalsIgnoreCase("numberTriesToConnect")){
+ numberTriesToConnect = Integer.parseInt(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("instanceID")){
+ instanceID = Integer.parseInt(tempVal.trim());
+ }
+ else if (qName.equalsIgnoreCase("localBGPPort")){
+ localBGPPort = Integer.parseInt(tempVal.trim());
+ }
+// else if (qName.equalsIgnoreCase("configPeer")){
+// log.info("peers....." + peersToConnect.toString());
+// }
+ }
+
+
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ tempVal = new String(ch,start,length);
+
+ if(peer){
+ peerInfo= new BGP4LSPeerInfo();
+
+ String peerBGP_IPaddress = new String(ch, start, length);
+ Inet4Address peerBGPIP;
+ try {
+ peerBGPIP=(Inet4Address)Inet4Address.getByName(peerBGP_IPaddress.trim());
+ peerInfo.setPeerIP(peerBGPIP);
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ peersToConnect.add(peerInfo);
+ peer = false;
+ }
+ else if(send){
+ String sendInfo = new String(ch, start, length);
+ peerInfo.setSendToPeer(Boolean.parseBoolean(sendInfo.trim()));
+ send = false;
+ }
+ else if(receive){
+ String update_from = new String(ch, start, length);
+ peerInfo.setUpdateFromPeer(Boolean.parseBoolean(update_from.trim()));
+ receive = false;
+ }else if (peerPort){
+ String peer_port = new String(ch, start, length);
+ peerInfo.setPeerPort(Integer.parseInt(peer_port.trim()));
+ peerPort = false;
+ }
+ }
+ };
+ saxParser.parse(confFile, handler);
+
+ }catch (Exception e) {
+ log.error("Problems reading config");
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ }
+ public int getBGP4Port() {
+ return BGP4Port;
+ }
+ public void setBGP4Port(int bGP4Port) {
+ BGP4Port = bGP4Port;
+ }
+ public int getBGP4ManagementPort() {
+ return BGP4ManagementPort;
+ }
+ public void setBGP4ManagementPort(int bGP4ManagementPort) {
+ BGP4ManagementPort = bGP4ManagementPort;
+ }
+ public String getBGP4LogFile() {
+ return BGP4LogFile;
+ }
+ public void setBGP4LogFile(String bGP4LogFile) {
+ BGP4LogFile = bGP4LogFile;
+ }
+ public boolean isSetTraces() {
+ return setTraces;
+ }
+ public void setSetTraces(boolean setTraces) {
+ this.setTraces = setTraces;
+ }
+ public boolean isTest() {
+ return isTest;
+ }
+ public void setisTest(boolean test) {
+ this.isTest = test;
+ }
+
+ public String getConfFile() {
+ return confFile;
+ }
+ public void setConfFile(String confFile) {
+ this.confFile = confFile;
+ }
+ public boolean isNodelay() {
+ return nodelay;
+ }
+ public void setNodelay(boolean nodelay) {
+ this.nodelay = nodelay;
+ }
+ public int getHoldTime() {
+ return holdTime;
+ }
+ public void setHoldTime(int holdTime) {
+ this.holdTime = holdTime;
+ }
+ public String getBGPIdentifier() {
+ return BGPIdentifier;
+ }
+ public void setBGPIdentifier(String bGPIdentifier) {
+ BGPIdentifier = bGPIdentifier;
+ }
+ public int getMyAutonomousSystem() {
+ return myAutonomousSystem;
+ }
+ public void setMyAutonomousSystem(int myAutonomousSystem) {
+ this.myAutonomousSystem = myAutonomousSystem;
+ }
+ public int getVersion() {
+ return version;
+ }
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public LinkedList getPeersToConnect() {
+ return peersToConnect;
+ }
+ public void setPeersToConnect(LinkedList peersToConnect) {
+ this.peersToConnect = peersToConnect;
+ }
+
+ public String getLearnTopology() {
+ return learnTopology;
+ }
+ public void setLearnTopology(String learnTopology) {
+ this.learnTopology = learnTopology;
+ }
+ public String getTopologyFile() {
+ return topologyFile;
+ }
+ public void setTopologyFile(String topologyFile) {
+ this.topologyFile = topologyFile;
+ }
+
+ public int getNumberTriesToConnect() {
+ return numberTriesToConnect;
+ }
+ public void setNumberTriesToConnect(int numberTriesToConnect) {
+ this.numberTriesToConnect = numberTriesToConnect;
+ }
+ public long getDelay() {
+ return delay;
+ }
+ public void setDelay(long delay) {
+ this.delay = delay;
+ }
+ public boolean isSendTopology() {
+ return sendTopology;
+ }
+ public void setSendTopology(boolean sendTopology) {
+ this.sendTopology = sendTopology;
+ }
+ public String getBGP4LogFileClient() {
+ return BGP4LogFileClient;
+ }
+ public void setBGP4LogFileClient(String bGP4LogFileClient) {
+ BGP4LogFileClient = bGP4LogFileClient;
+ }
+ public String getBGP4LogFileServer() {
+ return BGP4LogFileServer;
+ }
+ public void setBGP4LogFileServer(String bGP4LogFileServer) {
+ BGP4LogFileServer = bGP4LogFileServer;
+ }
+ public int getInstanceID() {
+ return instanceID;
+ }
+ public void setInstanceID(int instanceID) {
+ this.instanceID = instanceID;
+ }
+ public boolean isSendIntradomainLinks() {
+ return sendIntradomainLinks;
+ }
+
+ public void setSendIntradomainLinks(boolean sendIntradomainLinks) {
+ this.sendIntradomainLinks = sendIntradomainLinks;
+ }
+
+
+ public String getLocalBGPAddress() {
+ return localBGPAddress;
+ }
+ public void setLocalBGPAddress(String localBGPAddress) {
+ this.localBGPAddress = localBGPAddress;
+ }
+ public int getLocalBGPPort() {
+ return localBGPPort;
+ }
+
+ public long getSendTopoDelay() {
+ return sendTopoDelay;
+ }
+ public void setSendTopoDelay(long sendTopoDelay) {
+ this.sendTopoDelay = sendTopoDelay;
+ }
+ public boolean isSaveTopologyDB() {
+ return saveTopologyDB;
+ }
+ public void setSaveTopologyDB(boolean saveTopologyDB) {
+ this.saveTopologyDB = saveTopologyDB;
+ }
+ public Inet4Address getTopologyDBIP() {
+ return topologyDBIP;
+ }
+ public void setTopologyDBIP(Inet4Address topologyDBIP) {
+ this.topologyDBIP = topologyDBIP;
+ }
+ public int getTopologyDBport() {
+ return topologyDBport;
+ }
+ public void setTopologyDBport(int topologyDBport) {
+ this.topologyDBport = topologyDBport;
+ }
+
+
+
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4SessionClientManager.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4SessionClientManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..75694e90c9ffac9f5760943975f4a437d5fb9863
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4SessionClientManager.java
@@ -0,0 +1,160 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionClient;
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionExistsException;
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionsInformation;
+import eu.teraflow.tid.bgp4Peer.updateTEDB.UpdateDispatcher;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.Inet4Address;
+
+/**
+ * Client session manager
+ * @author mcs
+ *
+ */
+public class BGP4SessionClientManager implements Runnable{
+
+
+
+ private BGP4SessionClient bgp4SessionClient;
+ private Logger log;
+
+ BGP4SessionsInformation bgp4SessionInformation;
+ /**
+ * peer contains the IP address and port where the peer listens.
+ */
+ private BGP4LSPeerInfo peer;
+ private Inet4Address peerIP;
+ private String localBGP4Address;
+ private int localBGP4Port;
+ private int holdTime;
+ private int keepAliveTimer;
+ private Inet4Address BGPIdentifier;
+ private int version = 4;
+ private int myAutonomousSystem;
+ private UpdateDispatcher ud;
+ private Boolean updateFrom;
+ private Boolean sendTo;
+
+ public BGP4SessionClientManager(BGP4SessionsInformation bgp4SessionInformation,UpdateDispatcher ud, BGP4LSPeerInfo peer,int bgp4Port,String my_IPAddress,int my_bgp4Port , int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem, int my_keepAliveTimer){
+ log=LoggerFactory.getLogger("BGP4Peer");
+ this.bgp4SessionInformation=bgp4SessionInformation;
+ this.holdTime=holdTime;
+ this.BGPIdentifier=BGPIdentifier;
+ this.version = version;
+ this.myAutonomousSystem=myAutonomousSystem;
+ this.peer = peer;
+ this.ud=ud;
+ this.localBGP4Address=my_IPAddress;
+ this.localBGP4Port=my_bgp4Port;
+ this.keepAliveTimer = my_keepAliveTimer;
+ this.peerIP=peer.getPeerIP();
+ this.setSendTo(peer.isSendToPeer());
+ this.setUpdateFrom(peer.isUpdateFromPeer());
+
+ }
+
+ /**
+ *
+ *
+ *
+ */
+ public void run(){
+ if(bgp4SessionClient != null){
+ if (bgp4SessionClient.isAlive()){
+ if (bgp4SessionClient.isInterrupted()){
+ log.debug("Thread alive... backup session dead");
+
+ }
+ log.debug("Session alive and not interrupted");
+ return;
+ }
+ else{
+ try{
+ bgp4SessionInformation.notifySessionStart(peerIP);
+ log.debug("Session with BGP-LS peer"+peer +" dead, trying to establish new session");
+ bgp4SessionClient= new BGP4SessionClient(bgp4SessionInformation,ud,peer.getPeerIP(),peer.getPeerPort(),holdTime,BGPIdentifier,version,myAutonomousSystem,localBGP4Address, localBGP4Port,keepAliveTimer);
+ bgp4SessionClient.setSendTo(sendTo);
+ bgp4SessionClient.setUpdateFrom(updateFrom);
+ bgp4SessionClient.start();
+ } catch(BGP4SessionExistsException e){
+ log.debug("Checked that there is already a peer initiated session with "+this.peerIP);
+ }
+
+ return;
+ }
+ } else {
+ try{
+ bgp4SessionInformation.notifySessionStart(peerIP);
+ log.info("Trying to establish new session with peer "+ peer.getPeerIP()+" on port "+peer.getPeerPort());
+ bgp4SessionClient = new BGP4SessionClient(bgp4SessionInformation,ud, peer.getPeerIP(), peer.getPeerPort(), holdTime, BGPIdentifier,
+ version,myAutonomousSystem,localBGP4Address, localBGP4Port ,keepAliveTimer);
+ bgp4SessionClient.setSendTo(sendTo);
+ bgp4SessionClient.setUpdateFrom(updateFrom);
+ bgp4SessionClient.start();
+
+ } catch(BGP4SessionExistsException e){
+ log.debug("No need to start new connection with "+this.peerIP);
+ }
+
+
+ return;
+
+ }
+
+ }
+ public BGP4SessionClient getBgp4SessionClient() {
+ return bgp4SessionClient;
+ }
+
+ public void setBgp4SessionClient(BGP4SessionClient bgp4SessionClient) {
+ this.bgp4SessionClient = bgp4SessionClient;
+ }
+
+ public void killBGP4Session(){
+ bgp4SessionClient.killSession();
+ }
+
+ public void closeBGP4Session(){
+ log.info("Closing BGP4Session");
+ if (bgp4SessionClient.isAlive()){
+ //FIXME reason for close????
+ bgp4SessionClient.close();
+ }
+
+ }
+
+ public Boolean getUpdateFrom() {
+ return updateFrom;
+ }
+
+ public void setUpdateFrom(Boolean updateFrom) {
+ this.updateFrom = updateFrom;
+ }
+
+ public Boolean getSendTo() {
+ return sendTo;
+ }
+
+ public void setSendTo(Boolean sendTo) {
+ this.sendTo = sendTo;
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4SessionServerManager.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4SessionServerManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccb59fa2e1ace06f3cf4586a3325bbec1f5f2794
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGP4SessionServerManager.java
@@ -0,0 +1,160 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4PeerInitiatedSession;
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionsInformation;
+import eu.teraflow.tid.bgp4Peer.updateTEDB.UpdateDispatcher;
+import eu.teraflow.tid.tedb.TEDB;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.LinkedList;
+
+public class BGP4SessionServerManager implements Runnable {
+ private BGP4PeerInitiatedSession bgp4SessionServer;
+ private Logger log;
+ BGP4SessionsInformation bgp4SessionsInformation;
+ int bgp4Port;
+ private int holdTime;
+ private int keepAliveTimer;
+ private Inet4Address BGPIdentifier;
+ private int version = 4;
+ private int myAutonomousSystem;
+ private boolean noDelay;
+ private boolean isTest=false;
+ private TEDB tedb;
+ private UpdateDispatcher ud;
+ Inet4Address localBGP4Address;
+ private Boolean updateFrom;
+ private Boolean sendTo;
+
+ private LinkedList peersToConnect;
+
+ public BGP4SessionServerManager(BGP4SessionsInformation bgp4SessionInformation, TEDB tedb,UpdateDispatcher ud, int bgp4Port,int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem,boolean noDelay,Inet4Address localAddress ,int mykeepAliveTimer, LinkedList peersToConnect ){
+ log = LoggerFactory.getLogger("BGP4Peer");
+ this.holdTime=holdTime;
+ this.BGPIdentifier=BGPIdentifier;
+ this.version = version;
+ this.myAutonomousSystem=myAutonomousSystem;
+ this.bgp4SessionsInformation=bgp4SessionInformation;
+ this.bgp4Port=bgp4Port;
+ this.noDelay=noDelay;
+ this.tedb=tedb;
+ this.ud=ud;
+ this.localBGP4Address=localAddress;
+ this.keepAliveTimer = mykeepAliveTimer;
+ this.peersToConnect=peersToConnect;
+ }
+
+ public BGP4SessionServerManager(BGP4SessionsInformation bgp4SessionInformation, TEDB tedb,UpdateDispatcher ud, int bgp4Port,int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem,boolean noDelay,Inet4Address localAddress ,int mykeepAliveTimer, LinkedList peersToConnect, boolean test){
+ log = LoggerFactory.getLogger("BGP4Peer");
+ this.holdTime=holdTime;
+ this.BGPIdentifier=BGPIdentifier;
+ this.version = version;
+ this.myAutonomousSystem=myAutonomousSystem;
+ this.bgp4SessionsInformation=bgp4SessionInformation;
+ this.bgp4Port=bgp4Port;
+ this.noDelay=noDelay;
+ this.tedb=tedb;
+ this.ud=ud;
+ this.localBGP4Address=localAddress;
+ this.keepAliveTimer = mykeepAliveTimer;
+ this.peersToConnect=peersToConnect;
+ this.isTest=test;
+ }
+
+
+ public Boolean getSendTo() {
+ return sendTo;
+ }
+
+ public void setSendTo(Boolean sendTo) {
+ this.sendTo = sendTo;
+ }
+
+ public Boolean getUpdateFrom() {
+ return updateFrom;
+ }
+
+ public void setUpdateFrom(Boolean updateFrom) {
+ this.updateFrom = updateFrom;
+ }
+
+ @Override
+ public void run() {
+
+
+
+ ServerSocket serverSocket = null;
+ boolean listening = true;
+ try {
+ log.debug("SERVER Listening on port: "+ bgp4Port);
+ log.debug("SERVER Listening on address: "+ localBGP4Address);
+ serverSocket = new ServerSocket( bgp4Port,0,localBGP4Address);
+ } catch (IOException e) {
+ log.error("Could not listen on port: "+ bgp4Port);
+ System.exit(-1);
+ }
+ while (listening) {
+ try {
+ Socket sock=serverSocket.accept();
+ bgp4SessionServer = new BGP4PeerInitiatedSession(sock,bgp4SessionsInformation,ud,holdTime,BGPIdentifier,version,myAutonomousSystem,noDelay,keepAliveTimer);
+ if (isTest){
+ log.info("isTest");
+ bgp4SessionServer.setSendTo(true);
+ bgp4SessionServer.start();
+ }
+ else {
+ log.info("Not Test");
+ for (int i = 0; i < this.peersToConnect.size(); i++) {
+ try {
+ Inet4Address add = peersToConnect.get(i).getPeerIP();
+ if (add == null) {
+ log.warn("peer IP address shouldn't be null");
+ } else {
+ if (add.equals(sock.getInetAddress())) {
+ log.debug("FOUND " + add);
+ bgp4SessionServer.setSendTo(this.peersToConnect.get(i).isSendToPeer());
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ bgp4SessionServer.start();
+ }
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ log.info("Closing the socket");
+ serverSocket.close();
+
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGPPeer.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGPPeer.java
new file mode 100644
index 0000000000000000000000000000000000000000..bdddd4379af58b998b0236e701ea17bcecc14997
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGPPeer.java
@@ -0,0 +1,407 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+import eu.teraflow.tid.bgp4Peer.bgp4session.BGP4SessionsInformation;
+import eu.teraflow.tid.bgp4Peer.management.BGP4ManagementServer;
+import eu.teraflow.tid.bgp4Peer.updateTEDB.UpdateDispatcher;
+import eu.teraflow.tid.tedb.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * BGP-LS Speaker.
+ * This class is a BGP-LS peer which has two modes:
+ * - Listens to incoming connections
+ * - Launches new BGP session with a list of peers.
+ * It can send periodically its learnt topology to other peers.
+ * TEDB can be initialized from:
+ * - XML file with the topolgoy
+ * - Other BGP-LS Sessions
+ *
+ * @author pac ogondio
+ *
+ */
+public class BGPPeer {
+ /**
+ * Session server. It opens a socket to listen to new connections.
+ */
+ private BGP4SessionServerManager bgp4SessionServer;
+ /**
+ * Session client. It connects to peers.
+ */
+ private BGP4SessionClientManager bgp4SessionClientManager;
+ /**
+ * BGP4 parameters. Needed to configure the connections.
+ */
+ private BGP4Parameters params;
+
+ /**
+ * List of opened BGP4 sessions.
+ */
+ private BGP4SessionsInformation bgp4SessionsInformation;
+
+ /**
+ * Topology database only for interDomain Links.
+ */
+ private MultiDomainTEDB multiDomainTEDB;
+
+ /**
+ * Table with domainID - TEDB.
+ * The BGP-LS Peer can have several domains
+ */
+ private Hashtable intraTEDBs;
+
+ /**
+ * Full TEDB with all Links
+ */
+
+ private SimpleTEDB fullTEDB;
+
+
+ /**
+ * Class to send periodically the topology
+ */
+ //private DomainTEDB readDomainTEDB;
+
+ /**
+ * True: This peer sends the topology to other peers
+ * False: This peer does NOT send the topology to other peers
+ */
+ private boolean sendTopology;
+ /**
+ *
+ */
+ private SendTopology sendTopologyTask;
+ /**
+ *
+ */
+ private boolean saveTopology;
+
+ private SaveTopologyinDB saveTopologyDB;
+
+ /**
+ *
+ */
+ /**
+ * List of peers to establish connections.
+ */
+ private LinkedList peersToConnect;
+
+ //Whitelist and blacklist not yet implemented
+
+ /**
+ * Loggers
+ */
+ private Logger logParser;
+ private Logger logClient;
+ private Logger logServer;
+ /**
+ * Class to read and process the BGP4 update messages
+ */
+ private UpdateDispatcher ud;
+ /**
+ * Executor. To execute the session server, to execute periodically the session client.
+ */
+ private ScheduledThreadPoolExecutor executor;
+
+ /**
+ * Function to configure the BGP4 Peer without specifying the file. It will read a file with name: BGP4Parameters.xml
+ */
+ public void configure (){
+ this.configure (null);
+ }
+
+ /**
+ * Function to configure the BGP4 peer.
+ * It created the loggers, the executor,
+ * @param nameParametersFile Name of the Parameters File
+ */
+ public void configure(String nameParametersFile){
+ configure(nameParametersFile, null, null);
+ }
+
+ /**
+ * Function to configure the BGP4 peer.
+ * It created the loggers, the executor,
+ * @param nameParametersFile Name of the Parameters File
+ * @param multiTEDB multidomain database
+ * @param iTEDBs internal domains database
+ */
+ public void configure(String nameParametersFile, MultiDomainTEDB multiTEDB, Hashtable iTEDBs){
+ //First of all, read the parameters
+ if (nameParametersFile != null){
+ params=new BGP4Parameters(nameParametersFile);
+ }else{
+ params=new BGP4Parameters();
+ }
+ params.initialize();
+ peersToConnect = params.getPeersToConnect();
+ sendTopology = params.isSendTopology();
+ saveTopology = params.isSaveTopologyDB();
+
+ //Initialize loggers
+// FileHandler fh;
+// FileHandler fh1;
+// FileHandler fh2;
+// try {
+// fh=new FileHandler(params.getBGP4LogFile());
+ logParser=LoggerFactory.getLogger("BGP4Parser");
+// logParser.addHandler(fh);
+// logParser.setLevel(Level.ALL);
+// fh1=new FileHandler(params.getBGP4LogFileClient());
+ logClient=LoggerFactory.getLogger("BGP4Client");
+// logClient.addHandler(fh1);
+// logClient.setLevel(Level.ALL);
+// fh2=new FileHandler(params.getBGP4LogFileServer());
+ logServer=LoggerFactory.getLogger("BGP4Peer");
+// logServer.addHandler(fh2);
+// logServer.setLevel(Level.ALL);
+//
+// } catch (Exception e1) {
+// e1.printStackTrace();
+// System.exit(1);
+// }
+ logServer.info("Inizializing BGP4 Peer");
+ if (iTEDBs!= null) intraTEDBs=iTEDBs;
+ else intraTEDBs=new Hashtable();
+
+ if (multiTEDB!= null) multiDomainTEDB = multiTEDB;
+ else multiDomainTEDB = new MDTEDB();
+
+ if (params.getLearnTopology().equals("fromXML")){
+ //intraTEDBs=new Hashtable();
+ //multiDomainTEDB = new MDTEDB();
+ //intraTEDBs = FileTEDBUpdater.readMultipleDomainSimpleNetworks(params.getTopologyFile(), null, false,0,Integer.MAX_VALUE, false);
+ logParser.info("BGPIdentifier: "+params.getBGPIdentifier());
+ intraTEDBs = FileTEDBUpdater.readMultipleDomainSimpleNetworks(params.getTopologyFile(), null, false,0,Integer.MAX_VALUE, false, params.getBGPIdentifier());
+
+ //multiDomainTEDB.initializeFromFile(params.getTopologyFile());
+ multiDomainTEDB.initializeFromFile(params.getTopologyFile(), params.getBGPIdentifier());
+
+ }
+ // Create Thread executor
+ //FIXME: Actualizar n�mero de threads que se crean
+ executor = new ScheduledThreadPoolExecutor(20);//1 para el servidor, 1 para el que lanza y vigila los clientes
+ // Information about all the sessions of the PCE
+ if (params.isTest()) {
+ bgp4SessionsInformation = new BGP4SessionsInformation(params.isTest());
+ }
+ else{
+ bgp4SessionsInformation = new BGP4SessionsInformation();
+ }
+ //Create the task to send the topology. It has to be created because you can start sending the topology in the management (wirting): send topology on.
+ sendTopologyTask = new SendTopology();
+ saveTopologyDB= new SaveTopologyinDB();
+ if (params.isSaveTopologyDB() == true){
+ saveTopologyDB.configure(intraTEDBs, multiDomainTEDB, params.isSaveTopologyDB(), params.getTopologyDBIP().getHostAddress(), params.getTopologyDBport());
+ }
+
+ }
+
+ public void setWriteMultiTEDB(MultiDomainTEDB multiTEDB) {
+
+ this.multiDomainTEDB = multiTEDB;
+ saveTopologyDB.setMultiDomainTEDB(multiTEDB);
+ }
+
+ /*
+ //new function from Andrea
+ public void setWriteMultiAndIntraTEDB(MultiDomainTEDB multiTEDB, Hashtable intraTEDBs) {
+
+ this.multiDomainTEDB = multiTEDB;
+ this.intraTEDBs = intraTEDBs;
+ saveTopologyDB.setMultiDomainTEDB(multiTEDB);
+ saveTopologyDB.setIntraTEDBs(intraTEDBs);
+ }
+ */
+
+
+ public void setReadDomainTEDB(DomainTEDB readDomainTEDB) {
+ //this.readDomainTEDB = readDomainTEDB;
+ //System.out.println("setReadDomain: readFomainTEDB().getDomainID()="+readDomainTEDB.getDomainID());
+ //System.out.println("setReadDomain: readFomainTEDB="+readDomainTEDB.printTopology());
+ if(readDomainTEDB.getDomainID() == null)
+ this.intraTEDBs.put("default", readDomainTEDB);
+ else
+ this.intraTEDBs.put(readDomainTEDB.getDomainID().toString(), readDomainTEDB);
+ }
+ public void createUpdateDispatcher(){
+ //Updater dispatcher
+ ud = new UpdateDispatcher(multiDomainTEDB,intraTEDBs);
+ }
+
+ /**
+ * Function to create the TEDBs of the peer.
+ * @param nameParametersFile Name of the Parameters File
+ */
+
+
+ /**
+ * Start the session for the management of the BGP4.
+ */
+ public void startManagementServer(){
+ logServer.debug("Initializing Management Server");
+ BGP4ManagementServer bms=new BGP4ManagementServer(params.getBGP4ManagementPort(),multiDomainTEDB,intraTEDBs,bgp4SessionsInformation,sendTopologyTask);
+ bms.start();
+ }
+ /**
+ * Function which start the peer as a client which try to establish new sessions with peers.
+ * It starts a new process for each peer.
+ */
+ public void startClient(){
+ logClient.debug("Initializing Session Manager to connect as client");
+ if (params.getBGPIdentifier() != null){
+ Inet4Address BGPIdentifier=null;
+ try {
+ BGPIdentifier = (Inet4Address) InetAddress.getByName(params.getBGPIdentifier());
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return;
+ }
+ for (int i =0;i.");
+ System.exit(1);
+ }
+
+ }
+ /**
+ * Function which starts the peer (listening BGP4 protocol) as a server.
+ * It starts once the session server manager.
+ */
+ public void startServer(){
+ logServer.info("Initializing Session Manager to connect as server");
+ Inet4Address localAddress=null;
+ Inet4Address BGPIdentifier=null;
+ if (params.getBGPIdentifier() != null){
+ try {
+ localAddress = (Inet4Address) InetAddress.getByName(params.getLocalBGPAddress());
+ BGPIdentifier = (Inet4Address) InetAddress.getByName(params.getBGPIdentifier());
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return;
+ }
+ if (params.isTest()) {
+ bgp4SessionServer = new BGP4SessionServerManager(bgp4SessionsInformation, multiDomainTEDB, ud, params.getBGP4Port(), params.getHoldTime(), BGPIdentifier, params.getVersion(), params.getMyAutonomousSystem(), params.isNodelay(), localAddress, params.getKeepAliveTimer(), peersToConnect, params.isTest());
+ executor.execute(bgp4SessionServer);
+ }
+ else {
+ bgp4SessionServer = new BGP4SessionServerManager(bgp4SessionsInformation, multiDomainTEDB, ud, params.getBGP4Port(), params.getHoldTime(), BGPIdentifier, params.getVersion(), params.getMyAutonomousSystem(), params.isNodelay(), localAddress, params.getKeepAliveTimer(), peersToConnect);
+ executor.execute(bgp4SessionServer);
+ }
+
+ }else{
+ logServer.error("ERROR: BGPIdentifier is not configured. To configure: XML file (BGP4Parameters.xml) .");
+ System.exit(1);
+ }
+ }
+
+ public void startSendTopology(){
+ if (params.isTest()) {
+ sendTopologyTask.configure(intraTEDBs, bgp4SessionsInformation, sendTopology, params.getInstanceID(),params.isSendIntradomainLinks(),this.multiDomainTEDB, params.isTest());
+ }
+ else{
+ sendTopologyTask.configure(intraTEDBs, bgp4SessionsInformation, sendTopology, params.getInstanceID(),params.isSendIntradomainLinks(),this.multiDomainTEDB);
+ }
+ executor.scheduleWithFixedDelay(sendTopologyTask, 0,params.getSendTopoDelay(), TimeUnit.MILLISECONDS);
+ }
+
+
+
+ public void startSaveTopology(){
+ //FIXME: ADD param to configure the delay
+ executor.scheduleWithFixedDelay(saveTopologyDB, 0,5000, TimeUnit.MILLISECONDS);
+ }
+
+
+ public SaveTopologyinDB getSaveTopologyDB() {
+ return saveTopologyDB;
+ }
+
+ public void setSaveTopologyDB(SaveTopologyinDB saveTopologyDB) {
+ this.saveTopologyDB = saveTopologyDB;
+ }
+
+ public boolean isSaveTopology() {
+ return saveTopology;
+ }
+
+ public void setSaveTopology(boolean saveTopology) {
+ this.saveTopology = saveTopology;
+ }
+
+ public UpdateDispatcher getUd() {
+ return ud;
+ }
+
+ public void setUd(UpdateDispatcher ud) {
+ this.ud = ud;
+ }
+
+ public void addSimpleTEDB(SimpleTEDB simpleTEDB, String domainID) {
+ this.intraTEDBs.put(domainID, simpleTEDB);
+ }
+
+ public void setSimpleTEDB(SimpleTEDB simpleTEDB) {
+ if(simpleTEDB.getDomainID() == null)
+ this.intraTEDBs.put("default", simpleTEDB);
+ else
+ this.intraTEDBs.put(simpleTEDB.getDomainID().toString(), simpleTEDB);
+ }
+
+
+ public void stopPeer(){
+ executor.shutdown();
+ }
+ public MultiDomainTEDB getMultiDomainTEDB() {
+ return multiDomainTEDB;
+ }
+
+
+ public Hashtable getIntraTEDBs() {
+ return intraTEDBs;
+ }
+
+ public void setIntraTEDBs(Hashtable intraTEDBs) {
+ this.intraTEDBs = intraTEDBs;
+ }
+
+ public void setMultiDomainTEDB(MultiDomainTEDB multiDomainTEDB) {
+ this.multiDomainTEDB = multiDomainTEDB;
+ }
+
+
+
+
+
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGPPeerMain.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGPPeerMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..97e2702f5485ca848d383e5939a330137c49711b
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/BGPPeerMain.java
@@ -0,0 +1,37 @@
+// 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.
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+public class BGPPeerMain {
+
+ /**
+ * @param args Command line arguments. First argument, config file.
+ */
+ public static void main(String[] args) {
+ BGPPeer bgpPeer = new BGPPeer();
+ if (args.length != 0)
+ bgpPeer.configure(args[0]);
+ else
+ bgpPeer.configure();
+
+ //bgpPeer.createTEDB("hola"); //did it in configure
+ bgpPeer.createUpdateDispatcher();
+ bgpPeer.startClient();
+ bgpPeer.startServer();
+ bgpPeer.startSaveTopology();
+ bgpPeer.startManagementServer();
+ bgpPeer.startSendTopology();
+ }
+}
diff --git a/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/SaveTopologyinDB.java b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/SaveTopologyinDB.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd27bb87ab0d193f4f7c7de0720aac1cdff1e61c
--- /dev/null
+++ b/src/bgpls_speaker/service/java/netphony-topology/src/main/java/eu/teraflow/tid/bgp4Peer/peer/SaveTopologyinDB.java
@@ -0,0 +1,300 @@
+// 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.
+
+
+package eu.teraflow.tid.bgp4Peer.peer;
+
+import java.net.Inet4Address;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.teraflow.tid.tedb.DatabaseControlSimplifiedLSA;
+import eu.teraflow.tid.tedb.DomainTEDB;
+import eu.teraflow.tid.tedb.InterDomainEdge;
+import eu.teraflow.tid.tedb.IntraDomainEdge;
+import eu.teraflow.tid.tedb.MultiDomainTEDB;
+import eu.teraflow.tid.tedb.TEDB;
+import eu.teraflow.tid.tedb.TE_Information;
+import redis.clients.jedis.Jedis;
+
+/**
+ * Class to save periodically the topology. It sends the topology to the active BGP4 sessions.
+ * @author pac
+ *
+ */
+public class SaveTopologyinDB implements Runnable {
+
+ //FIXME: Configure from file
+ private Jedis jedis;
+ private String host="localhost";
+ private int port=6379;
+
+ //TEDBs
+ private Hashtable intraTEDBs;
+
+ // Multi-domain TEDB to redistribute Multi-domain Topology
+ private MultiDomainTEDB multiDomainTEDB;
+
+ private boolean writeTopology;
+
+ private Logger log;
+
+
+ public SaveTopologyinDB(){
+ log = LoggerFactory.getLogger("BGP4Peer");
+ jedis = new Jedis(host,port);
+ }
+
+ public void configure( Hashtable intraTEDBs,MultiDomainTEDB multiTED, boolean writeTopology, String host, int port){
+ this.intraTEDBs=intraTEDBs;
+ this.writeTopology=writeTopology;
+ this.multiDomainTEDB=multiTED;
+ //rdh.setHost(host);
+ //rdh.setPort(port);
+
+
+ if (writeTopology){
+ jedis = new Jedis(host,port);
+ jedis.connect();
+ }
+ }
+
+ /**
+ * Function to send the topology database.
+ */
+
+
+ public void run(){
+ try {
+ if (writeTopology){
+ log.info("Going to save Topology in Redis DB");
+ if (jedis==null){
+ jedis = new Jedis(host,port);
+ jedis.connect();
+ }else if (jedis.isConnected()==false){
+ jedis.connect();
+ }
+ if (multiDomainTEDB!=null){
+ log.info("save Multi-Domain TEDB");
+ writeLinkDBInter( multiDomainTEDB.getInterDomainLinks());
+ }
+ else {
+ log.info("save form TEDB");
+ Enumeration iter = intraTEDBs.elements();
+ while (iter.hasMoreElements()){
+ writeLinkDBInter( iter.nextElement().getInterDomainLinks());
+ }
+ }
+
+ log.info("sendIntraDomainLinks activated");
+ Enumeration iter = intraTEDBs.keys();
+ while (iter.hasMoreElements()){
+ String domainID = iter.nextElement();
+ log.info("Sending TED from domain "+domainID);
+ DomainTEDB ted=(DomainTEDB)intraTEDBs.get(domainID);
+ //writeLinkDB( ted.getNetworkGraph().edgeSet(),domainID);
+ writeLinkDB(ted.getIntraDomainLinks(),domainID);
+ }
+
+
+ }
+ }catch (Exception e) {
+ e.printStackTrace();
+ log.error("PROBLEM Writing TOPOLOGY: "+e.toString());
+ }
+
+ }
+
+ /**
+ * This function write a BGP4 update message in Data Base for each link in the list
+ * @param intradomainLinks
+ */
+ private void writeLinkDB(Set intradomainLinks, String domainID){
+
+ Iterator edgeIt = intradomainLinks.iterator();
+
+ while (edgeIt.hasNext()){
+
+ IntraDomainEdge edge = edgeIt.next();
+
+ DatabaseControlSimplifiedLSA dcsl =createSimplifiedLSA(edge);
+ String jsonLSA = dcsl.logJsonSimplifiedLSA();
+
+ if (jedis == null)
+ log.info("JEDIS IS NULL");
+
+ String ret = jedis.set("LSA:"+dcsl.getAdvertisingRouter().getHostAddress()+":"+dcsl.getLinkId().getHostAddress(), jsonLSA);
+ }
+
+ }
+
+ private DatabaseControlSimplifiedLSA createSimplifiedLSA(IntraDomainEdge edge){
+ DatabaseControlSimplifiedLSA dcsl = new DatabaseControlSimplifiedLSA();
+
+ //Inet4Address source = (Inet4Address)edge.getSrc_router_id();
+ //Inet4Address dst = (Inet4Address)edge.getDst_router_id();
+
+ Inet4Address source = (Inet4Address)edge.getSource();
+ dcsl.setAdvertisingRouter(source);
+ Inet4Address dst = (Inet4Address)edge.getTarget();
+ dcsl.setLinkId(dst);
+
+ TE_Information te_info = ((IntraDomainEdge) edge).getTE_info();
+
+ if (te_info != null){
+
+ if (te_info.getLinkLocalRemoteIdentifiers() != null){
+ dcsl.linkLocalIdentifier = te_info.getLinkLocalRemoteIdentifiers().getLinkLocalIdentifier();
+ }
+
+ if (te_info.getLinkLocalRemoteIdentifiers() != null){
+ dcsl.linkRemoteIdentifier = te_info.getLinkLocalRemoteIdentifiers().getLinkRemoteIdentifier();
+ }
+
+ if (te_info.getMaximumBandwidth() != null) {
+ dcsl.maximumBandwidth = te_info.getMaximumBandwidth().getMaximumBandwidth();
+ }
+
+ if (te_info.getUnreservedBandwidth() != null) {
+ dcsl.unreservedBandwidth = te_info.getUnreservedBandwidth().getUnreservedBandwidth()[0];
+ }
+
+ if (te_info.getMaximumReservableBandwidth() != null)
+ dcsl.maximumReservableBandwidth = te_info.getMaximumReservableBandwidth().getMaximumReservableBandwidth();
+
+ String ret = "";
+
+ if (te_info.getAvailableLabels() != null){
+
+ if (te_info.getAvailableLabels().getLabelSet() != null){
+
+ ret=ret+" Bitmap: {";
+
+ for (int i=0;i interdomainLinks){
+
+ Iterator edgeIt = interdomainLinks.iterator();
+
+ while (edgeIt.hasNext()){
+
+ InterDomainEdge edge = edgeIt.next();
+
+ DatabaseControlSimplifiedLSA dcsl =createSimplifiedLSAInter(edge);
+ String jsonLSA = dcsl.logJsonSimplifiedLSA();
+ //rdh.write("LSA:"+dcsl.getAdvertisingRouter().getHostAddress()+":"+dcsl.getLinkId().getHostAddress(),jsonLSA);
+ String ret = jedis.set("LSA:"+dcsl.getAdvertisingRouter().getHostAddress()+":"+dcsl.getLinkId().getHostAddress(), jsonLSA);
+ }
+
+ }
+
+ private DatabaseControlSimplifiedLSA createSimplifiedLSAInter(InterDomainEdge edge){
+ DatabaseControlSimplifiedLSA dcsl = new DatabaseControlSimplifiedLSA();
+
+ //Inet4Address source = (Inet4Address)edge.getSrc_router_id();
+ //Inet4Address dst = (Inet4Address)edge.getDst_router_id();
+
+ Inet4Address source = (Inet4Address)edge.getSource();
+ dcsl.setAdvertisingRouter(source);
+ Inet4Address dst = (Inet4Address)edge.getTarget();
+ dcsl.setLinkId(dst);
+
+ TE_Information te_info = ((InterDomainEdge) edge).getTE_info();
+
+ if (te_info != null){
+
+ if (te_info.getLinkLocalRemoteIdentifiers() != null){
+ dcsl.linkLocalIdentifier = te_info.getLinkLocalRemoteIdentifiers().getLinkLocalIdentifier();
+ }
+
+ if (te_info.getLinkLocalRemoteIdentifiers() != null){
+ dcsl.linkRemoteIdentifier = te_info.getLinkLocalRemoteIdentifiers().getLinkRemoteIdentifier();
+ }
+
+ if (te_info.getMaximumBandwidth() != null) {
+ dcsl.maximumBandwidth = te_info.getMaximumBandwidth().getMaximumBandwidth();
+ }
+
+ if (te_info.getUnreservedBandwidth() != null) {
+ dcsl.unreservedBandwidth = te_info.getUnreservedBandwidth().getUnreservedBandwidth()[0];
+ }
+
+ if (te_info.getMaximumReservableBandwidth() != null)
+ dcsl.maximumReservableBandwidth = te_info.getMaximumReservableBandwidth().getMaximumReservableBandwidth();
+
+ String ret = "";
+
+ if (te_info.getAvailableLabels() != null){
+
+ if (te_info.getAvailableLabels().getLabelSet() != null){
+
+ ret=ret+" Bitmap: {";
+
+ for (int i=0;i intraTEDBs;
+
+ // Multi-domain TEDB to redistribute Multi-domain Topology
+ private MultiDomainTEDB multiDomainTEDB;
+
+ private boolean sendTopology;
+ private boolean isTest=false;
+ private BGP4SessionsInformation bgp4SessionsInformation;
+ private Logger log;
+ private int instanceId=1;
+ private boolean sendIntraDomainLinks=false;
+
+ private boolean send4AS=false;
+
+
+
+
+ private Inet4Address localBGPLSIdentifer;
+ private Inet4Address localAreaID;
+
+ public SendTopology(){
+ log = LoggerFactory.getLogger("BGP4Peer");
+ }
+
+ public void configure( Hashtable intraTEDBs,BGP4SessionsInformation bgp4SessionsInformation,boolean sendTopology,int instanceId,boolean sendIntraDomainLinks, MultiDomainTEDB multiTED){
+ this.intraTEDBs=intraTEDBs;
+ this.bgp4SessionsInformation=bgp4SessionsInformation;
+ this.sendTopology= sendTopology;
+ this.instanceId = instanceId;
+ this.sendIntraDomainLinks=sendIntraDomainLinks;
+ this.multiDomainTEDB=multiTED;
+ try {
+ this.localAreaID=(Inet4Address)Inet4Address.getByName("0.0.0.0");
+ this.localBGPLSIdentifer=(Inet4Address)Inet4Address.getByName("1.1.1.1");
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+
+ public void configure( Hashtable intraTEDBs,BGP4SessionsInformation bgp4SessionsInformation,boolean sendTopology,int instanceId,boolean sendIntraDomainLinks, MultiDomainTEDB multiTED, boolean test){
+ this.intraTEDBs=intraTEDBs;
+ this.bgp4SessionsInformation=bgp4SessionsInformation;
+ this.sendTopology= sendTopology;
+ this.instanceId = instanceId;
+ this.sendIntraDomainLinks=sendIntraDomainLinks;
+ this.multiDomainTEDB=multiTED;
+ this.isTest=test;
+ try {
+ this.localAreaID=(Inet4Address)Inet4Address.getByName("0.0.0.0");
+ this.localBGPLSIdentifer=(Inet4Address)Inet4Address.getByName("1.1.1.1");
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Function to send the topology database.
+ */
+
+
+ public void run(){
+ try {
+ if (sendTopology){
+ if (!(bgp4SessionsInformation.getSessionList().isEmpty())){
+ if (multiDomainTEDB!=null){
+ log.debug("Sending Multi-Domain TEDB");
+ sendLinkNLRI( multiDomainTEDB.getInterDomainLinks());
+ }
+ else {
+ log.debug("Sending from TEDB");
+ Enumeration iter = intraTEDBs.elements();
+ while (iter.hasMoreElements()){
+ sendLinkNLRI( iter.nextElement().getInterDomainLinks());
+ }
+ }
+
+ if (sendIntraDomainLinks){//Intradomain Links
+ log.debug("sendIntraDomainLinks activated");
+ Enumeration iter = intraTEDBs.keys();
+ while (iter.hasMoreElements()){
+ String domainID = iter.nextElement();
+ //Andrea
+ log.debug("Sending TED from domain "+domainID);
+
+ TEDB ted=intraTEDBs.get(domainID);
+ if (ted instanceof DomainTEDB) {
+ sendLinkNLRI( ((DomainTEDB)ted).getIntraDomainLinks(),domainID);
+ //log.info(" XXXX ted.getNodeTable():"+ted.getNodeTable());
+ sendNodeNLRI( ((DomainTEDB)ted).getIntraDomainLinksvertexSet(), ((DomainTEDB)ted).getNodeTable());
+ if (((DomainTEDB)ted).getItResources()!=null){
+ sendITNodeNLRI( domainID, ((DomainTEDB)ted).getItResources());
+ }
+
+ }
+
+
+
+ }
+
+ }
+
+ }
+ }
+ }catch (Exception e) {
+ e.printStackTrace();
+ log.error("PROBLEM SENDING TOPOLOGY: "+e.toString());
+ }
+
+ }
+ /**
+ * This function sends a BGP4 update message (encoded in a NodeNLRI) for each node in the set
+ * @param vertexIt
+ */
+ private void sendNodeNLRI(Set