Skip to content
Snippets Groups Projects
Commit e3c2a213 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Moved QKD App NBI to NBI Component

parent 7f00e623
No related branches found
No related tags found
2 merge requests!294Release TeraFlowSDN 4.0,!272Resolve: "(OPT) QKD Application Register (new component)" (enhancements and fixes)
...@@ -66,6 +66,6 @@ spec: ...@@ -66,6 +66,6 @@ spec:
pathType: Prefix pathType: Prefix
backend: backend:
service: service:
name: qkd-appservice name: nbiservice
port: port:
number: 8005 number: 8080
...@@ -28,36 +28,35 @@ spec: ...@@ -28,36 +28,35 @@ spec:
spec: spec:
terminationGracePeriodSeconds: 5 terminationGracePeriodSeconds: 5
containers: containers:
- name: server - name: server
image: labs.etsi.org:5050/tfs/controller/qkd_app:latest image: labs.etsi.org:5050/tfs/controller/qkd_app:latest
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- containerPort: 10060 - containerPort: 10060
- containerPort: 9192 - containerPort: 9192
- containerPort: 8005 env:
env: - name: LOG_LEVEL
- name: LOG_LEVEL value: "INFO"
value: "DEBUG" - name: CRDB_DATABASE
- name: CRDB_DATABASE_APP value: "qkd_app"
value: "qkd_app" envFrom:
envFrom: - secretRef:
- secretRef: name: crdb-data
name: crdb-data - secretRef:
- secretRef: name: nats-data
name: nats-data readinessProbe:
readinessProbe: exec:
exec: command: ["/bin/grpc_health_probe", "-addr=:10060"]
command: ["/bin/grpc_health_probe", "-addr=:10060"] livenessProbe:
livenessProbe: exec:
exec: command: ["/bin/grpc_health_probe", "-addr=:10060"]
command: ["/bin/grpc_health_probe", "-addr=:10060"] resources:
resources: requests:
requests: cpu: 150m
cpu: 150m memory: 128Mi
memory: 128Mi limits:
limits: cpu: 500m
cpu: 500m memory: 512Mi
memory: 512Mi
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
...@@ -70,14 +69,11 @@ spec: ...@@ -70,14 +69,11 @@ spec:
selector: selector:
app: qkd-appservice app: qkd-appservice
ports: ports:
- name: grpc - name: grpc
protocol: TCP protocol: TCP
port: 10060 port: 10060
targetPort: 10060 targetPort: 10060
- name: metrics - name: metrics
protocol: TCP protocol: TCP
port: 9192 port: 9192
targetPort: 9192 targetPort: 9192
- name: http
port: 8005
targetPort: 8005
...@@ -114,15 +114,12 @@ DEFAULT_SERVICE_GRPC_PORTS = { ...@@ -114,15 +114,12 @@ DEFAULT_SERVICE_GRPC_PORTS = {
# Default HTTP/REST-API service ports # Default HTTP/REST-API service ports
DEFAULT_SERVICE_HTTP_PORTS = { DEFAULT_SERVICE_HTTP_PORTS = {
ServiceNameEnum.CONTEXT .value : 8080, ServiceNameEnum.NBI .value : 8080,
ServiceNameEnum.NBI .value : 8080, ServiceNameEnum.WEBUI.value : 8004,
ServiceNameEnum.WEBUI .value : 8004,
ServiceNameEnum.QKD_APP .value : 8005,
} }
# Default HTTP/REST-API service base URLs # Default HTTP/REST-API service base URLs
DEFAULT_SERVICE_HTTP_BASEURLS = { DEFAULT_SERVICE_HTTP_BASEURLS = {
ServiceNameEnum.NBI .value : None, ServiceNameEnum.NBI .value : None,
ServiceNameEnum.WEBUI .value : None, ServiceNameEnum.WEBUI.value : None,
ServiceNameEnum.QKD_APP .value : None,
} }
...@@ -15,9 +15,11 @@ ...@@ -15,9 +15,11 @@
import logging, os, re, time import logging, os, re, time
from typing import Dict, List from typing import Dict, List
from common.Constants import ( from common.Constants import (
DEFAULT_GRPC_BIND_ADDRESS, DEFAULT_GRPC_GRACE_PERIOD, DEFAULT_GRPC_MAX_WORKERS, DEFAULT_HTTP_BIND_ADDRESS, DEFAULT_GRPC_BIND_ADDRESS, DEFAULT_GRPC_GRACE_PERIOD,
DEFAULT_LOG_LEVEL, DEFAULT_METRICS_PORT, DEFAULT_SERVICE_GRPC_PORTS, DEFAULT_SERVICE_HTTP_BASEURLS, DEFAULT_GRPC_MAX_WORKERS, DEFAULT_HTTP_BIND_ADDRESS,
DEFAULT_SERVICE_HTTP_PORTS, ServiceNameEnum DEFAULT_LOG_LEVEL, DEFAULT_METRICS_PORT, DEFAULT_SERVICE_GRPC_PORTS,
DEFAULT_SERVICE_HTTP_BASEURLS, DEFAULT_SERVICE_HTTP_PORTS,
ServiceNameEnum
) )
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
......
...@@ -16,9 +16,10 @@ import logging, signal, sys, threading ...@@ -16,9 +16,10 @@ import logging, signal, sys, threading
from prometheus_client import start_http_server from prometheus_client import start_http_server
from common.Constants import ServiceNameEnum from common.Constants import ServiceNameEnum
from common.Settings import ( from common.Settings import (
ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port, ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC,
wait_for_environment_variables) get_env_var_name, get_log_level, get_metrics_port,
wait_for_environment_variables
)
from .NbiService import NbiService from .NbiService import NbiService
from .rest_server.RestServer import RestServer from .rest_server.RestServer import RestServer
from .rest_server.nbi_plugins.etsi_bwm import register_etsi_bwm_api from .rest_server.nbi_plugins.etsi_bwm import register_etsi_bwm_api
...@@ -28,6 +29,7 @@ from .rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn ...@@ -28,6 +29,7 @@ from .rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn
from .rest_server.nbi_plugins.ietf_network import register_ietf_network from .rest_server.nbi_plugins.ietf_network import register_ietf_network
from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss
from .rest_server.nbi_plugins.ietf_acl import register_ietf_acl from .rest_server.nbi_plugins.ietf_acl import register_ietf_acl
from .rest_server.nbi_plugins.qkd_app import register_qkd_app
from .rest_server.nbi_plugins.tfs_api import register_tfs_api from .rest_server.nbi_plugins.tfs_api import register_tfs_api
terminate = threading.Event() terminate = threading.Event()
...@@ -72,6 +74,7 @@ def main(): ...@@ -72,6 +74,7 @@ def main():
register_ietf_network(rest_server) register_ietf_network(rest_server)
register_ietf_nss(rest_server) # Registering NSS entrypoint register_ietf_nss(rest_server) # Registering NSS entrypoint
register_ietf_acl(rest_server) register_ietf_acl(rest_server)
register_qkd_app(rest_server)
register_tfs_api(rest_server) register_tfs_api(rest_server)
rest_server.start() rest_server.start()
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
...@@ -12,19 +12,18 @@ ...@@ -12,19 +12,18 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from qkd_app.service.rest_server.RestServer import RestServer from nbi.service.rest_server.RestServer import RestServer
from .Resources import ( from .Resources import CreateQKDApp, Index
CreateQKDApp, Index)
URL_PREFIX = '/qkd_app' URL_PREFIX = '/qkd_app'
# Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type. # Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type.
RESOURCES = [ RESOURCES = [
# (endpoint_name, resource_class, resource_url) # (endpoint_name, resource_class, resource_url)
('api.index', Index, '/'), ('api.index', Index, '/'),
('api.register_qkd_app', CreateQKDApp, '/create_qkd_app'), ('api.register_qkd_app', CreateQKDApp, '/create_qkd_app'),
] ]
def register_qkd_app(app_server : RestServer): def register_qkd_app(rest_server : RestServer):
for endpoint_name, resource_class, resource_url in RESOURCES: for endpoint_name, resource_class, resource_url in RESOURCES:
app_server.add_resource(resource_class, URL_PREFIX + resource_url, endpoint=endpoint_name) rest_server.add_resource(resource_class, URL_PREFIX + resource_url, endpoint=endpoint_name)
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
...@@ -17,21 +17,21 @@ import signal ...@@ -17,21 +17,21 @@ import signal
import sys import sys
import threading import threading
from prometheus_client import start_http_server from prometheus_client import start_http_server
#from common.Constants import ServiceNameEnum from common.Settings import get_log_level, get_metrics_port
from common.Settings import (
#ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name,
get_log_level, get_metrics_port, wait_for_environment_variables)
from qkd_app.service.QKDAppService import AppService from qkd_app.service.QKDAppService import AppService
from qkd_app.service.rest_server.RestServer import RestServer
from qkd_app.service.rest_server.qkd_app import register_qkd_app
#from common.message_broker.Factory import get_messagebroker_backend
#from common.message_broker.MessageBroker import MessageBroker
from qkd_app.service.database.Engine import Engine from qkd_app.service.database.Engine import Engine
from qkd_app.service.database.models._Base import rebuild_database from qkd_app.service.database.models._Base import rebuild_database
# Set up logging
LOG_LEVEL = get_log_level()
logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
LOGGER = logging.getLogger(__name__)
#LOGGER.addHandler(logging.StreamHandler(stream=sys.stderr))
#LOGGER.setLevel(logging.WARNING)
# Event for terminating the service gracefully # Event for terminating the service gracefully
terminate = threading.Event() terminate = threading.Event()
LOGGER: logging.Logger = None
def signal_handler(signum, frame): def signal_handler(signum, frame):
""" """
...@@ -41,25 +41,11 @@ def signal_handler(signum, frame): ...@@ -41,25 +41,11 @@ def signal_handler(signum, frame):
terminate.set() terminate.set()
def main(): def main():
global LOGGER # Required due to global scope LOGGER.info('Starting...')
# Set up logging
log_level = get_log_level()
logging.basicConfig(level=log_level, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
LOGGER = logging.getLogger(__name__)
# Ensure necessary environment variables are set
wait_for_environment_variables([
#get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST ),
#get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
])
# Register signal handlers for graceful shutdown # Register signal handlers for graceful shutdown
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGTERM, signal_handler)
LOGGER.info('Starting...')
# Start Prometheus metrics server # Start Prometheus metrics server
metrics_port = get_metrics_port() metrics_port = get_metrics_port()
start_http_server(metrics_port) start_http_server(metrics_port)
...@@ -90,13 +76,9 @@ def main(): ...@@ -90,13 +76,9 @@ def main():
grpc_service = AppService(db_engine, messagebroker) grpc_service = AppService(db_engine, messagebroker)
grpc_service.start() grpc_service.start()
# Start the REST server and register QKD apps
rest_server = RestServer()
register_qkd_app(rest_server)
rest_server.start()
LOGGER.info('Services started. Waiting for termination signal...') LOGGER.info('Services started. Waiting for termination signal...')
# Wait for Ctrl+C or termination signal
# Keep the process running until a termination signal is received # Keep the process running until a termination signal is received
while not terminate.wait(timeout=1.0): while not terminate.wait(timeout=1.0):
pass pass
...@@ -104,8 +86,6 @@ def main(): ...@@ -104,8 +86,6 @@ def main():
# Shutdown services gracefully on termination # Shutdown services gracefully on termination
LOGGER.info('Terminating services...') LOGGER.info('Terminating services...')
grpc_service.stop() grpc_service.stop()
rest_server.shutdown()
rest_server.join()
LOGGER.info('Shutdown complete. Exiting...') LOGGER.info('Shutdown complete. Exiting...')
return 0 return 0
......
...@@ -28,7 +28,7 @@ class Engine: ...@@ -28,7 +28,7 @@ class Engine:
if crdb_uri is None: if crdb_uri is None:
CRDB_NAMESPACE = get_setting('CRDB_NAMESPACE') CRDB_NAMESPACE = get_setting('CRDB_NAMESPACE')
CRDB_SQL_PORT = get_setting('CRDB_SQL_PORT') CRDB_SQL_PORT = get_setting('CRDB_SQL_PORT')
CRDB_DATABASE = get_setting('CRDB_DATABASE_APP') CRDB_DATABASE = get_setting('CRDB_DATABASE')
CRDB_USERNAME = get_setting('CRDB_USERNAME') CRDB_USERNAME = get_setting('CRDB_USERNAME')
CRDB_PASSWORD = get_setting('CRDB_PASSWORD') CRDB_PASSWORD = get_setting('CRDB_PASSWORD')
CRDB_SSLMODE = get_setting('CRDB_SSLMODE') CRDB_SSLMODE = get_setting('CRDB_SSLMODE')
......
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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 common.Constants import ServiceNameEnum
from common.Settings import get_service_baseurl_http, get_service_port_http
from common.tools.service.GenericRestServer import GenericRestServer
class RestServer(GenericRestServer):
"""
REST server class for handling HTTP requests related to QKD applications.
Productivity Improvements:
- Simplifies initialization by automatically fetching the required service details (base URL and port).
- Extends a generic REST server class, ensuring reusability and consistency across services.
"""
def __init__(self, cls_name: str = __name__) -> None:
"""
Initialize the REST server with service-specific configuration.
- Retrieves the port and base URL dynamically based on the QKD_APP service.
- Inherits from `GenericRestServer` for common REST functionality, reducing code duplication.
Arguments:
cls_name (str): Name of the current class (default: `__name__`).
"""
# Dynamically fetch the HTTP bind port and base URL for the QKD_APP service
bind_port = get_service_port_http(ServiceNameEnum.QKD_APP)
base_url = get_service_baseurl_http(ServiceNameEnum.QKD_APP)
# Pass these values to the parent `GenericRestServer` class for initialization
super().__init__(bind_port, base_url, cls_name=cls_name)
# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (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.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment