From be0e1527930f67011bd9b2c040944eff95cae5fc Mon Sep 17 00:00:00 2001 From: Lluis Gifre <lluis.gifre@cttc.es> Date: Fri, 13 Aug 2021 16:13:40 +0200 Subject: [PATCH] Added REST-API to Context service and updated service manifest files. --- manifests/contextservice.yaml | 25 ++++++++++++++ manifests/deviceservice.yaml | 1 + manifests/monitoringservice.yaml | 1 + manifests/redis.yaml | 16 +++++++++ manifests/serviceservice.yaml | 1 + src/context/Config.py | 5 +-- src/context/requirements.in | 1 + src/context/service/__main__.py | 33 ++++++++++++------- src/context/service/rest_server/Server.py | 30 +++++++++++++++++ src/context/service/rest_server/__init__.py | 0 .../service/rest_server/resources/Context.py | 9 +++++ .../service/rest_server/resources/__init__.py | 0 src/device/service/__main__.py | 18 +++++----- src/service/service/__main__.py | 18 +++++----- 14 files changed, 127 insertions(+), 31 deletions(-) create mode 100644 src/context/service/rest_server/Server.py create mode 100644 src/context/service/rest_server/__init__.py create mode 100644 src/context/service/rest_server/resources/Context.py create mode 100644 src/context/service/rest_server/resources/__init__.py diff --git a/manifests/contextservice.yaml b/manifests/contextservice.yaml index 75406da08..cf7da7e43 100644 --- a/manifests/contextservice.yaml +++ b/manifests/contextservice.yaml @@ -18,6 +18,7 @@ spec: imagePullPolicy: Always ports: - containerPort: 1010 + - containerPort: 8080 env: - name: DB_ENGINE value: "redis" @@ -51,3 +52,27 @@ spec: - name: grpc port: 1010 targetPort: 1010 + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: contextservice-public + labels: + app: contextservice +spec: + type: NodePort + selector: + app: contextservice + ports: + - name: grpc + protocol: TCP + port: 1010 + targetPort: 1010 + - name: http + protocol: TCP + port: 8080 + targetPort: 8080 +--- diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml index 7aa02e815..5afd6c7c8 100644 --- a/manifests/deviceservice.yaml +++ b/manifests/deviceservice.yaml @@ -49,5 +49,6 @@ spec: app: deviceservice ports: - name: grpc + protocol: TCP port: 2020 targetPort: 2020 diff --git a/manifests/monitoringservice.yaml b/manifests/monitoringservice.yaml index bf886f4f9..885e50adc 100644 --- a/manifests/monitoringservice.yaml +++ b/manifests/monitoringservice.yaml @@ -46,5 +46,6 @@ spec: app: monitoringservice ports: - name: grpc + protocol: TCP port: 8080 targetPort: 8080 diff --git a/manifests/redis.yaml b/manifests/redis.yaml index 4d6d6cbf2..9aaebb167 100644 --- a/manifests/redis.yaml +++ b/manifests/redis.yaml @@ -36,3 +36,19 @@ spec: port: 6379 targetPort: 6379 --- +apiVersion: v1 +kind: Service +metadata: + name: redis-public + labels: + app: redis +spec: + type: NodePort + selector: + app: redis + ports: + - name: redis + protocol: TCP + port: 6379 + targetPort: 6379 +--- diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index 3c673c7d5..72fd1c615 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -49,5 +49,6 @@ spec: app: serviceservice ports: - name: grpc + protocol: TCP port: 3030 targetPort: 3030 diff --git a/src/context/Config.py b/src/context/Config.py index 473db2850..2019cdd01 100644 --- a/src/context/Config.py +++ b/src/context/Config.py @@ -8,8 +8,9 @@ GRPC_SERVICE_PORT = 1010 GRPC_MAX_WORKERS = 10 GRPC_GRACE_PERIOD = 60 -# HTTP settings -HTTP_SERVICE_PORT = 8080 +# REST-API settings +RESTAPI_SERVICE_PORT = 8080 +RESTAPI_BASE_URL = '/api' # Prometheus settings METRICS_PORT = 9192 diff --git a/src/context/requirements.in b/src/context/requirements.in index 25abdad1b..398b8d3d8 100644 --- a/src/context/requirements.in +++ b/src/context/requirements.in @@ -1,3 +1,4 @@ +flask-restful grpcio-health-checking grpcio prometheus-client diff --git a/src/context/service/__main__.py b/src/context/service/__main__.py index 4335f9137..0bcdb8056 100644 --- a/src/context/service/__main__.py +++ b/src/context/service/__main__.py @@ -1,8 +1,11 @@ import logging, os, signal, sys, threading from prometheus_client import start_http_server from common.database.Factory import get_database +from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, RESTAPI_SERVICE_PORT, \ + RESTAPI_BASE_URL, METRICS_PORT from context.service.ContextService import ContextService -from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT +from context.service.rest_server.Server import Server +from context.service.rest_server.resources.Context import Context terminate = threading.Event() logger = None @@ -15,11 +18,13 @@ def signal_handler(signal, frame): def main(): global terminate, logger - service_port = os.environ.get('CONTEXTSERVICE_SERVICE_PORT_GRPC', GRPC_SERVICE_PORT) - max_workers = os.environ.get('MAX_WORKERS', GRPC_MAX_WORKERS ) - grace_period = os.environ.get('GRACE_PERIOD', GRPC_GRACE_PERIOD) - log_level = os.environ.get('LOG_LEVEL', LOG_LEVEL ) - metrics_port = os.environ.get('METRICS_PORT', METRICS_PORT) + grpc_service_port = os.environ.get('CONTEXTSERVICE_SERVICE_PORT_GRPC', GRPC_SERVICE_PORT ) + max_workers = os.environ.get('MAX_WORKERS', GRPC_MAX_WORKERS ) + grace_period = os.environ.get('GRACE_PERIOD', GRPC_GRACE_PERIOD ) + log_level = os.environ.get('LOG_LEVEL', LOG_LEVEL ) + restapi_service_port = os.environ.get('RESTAPI_SERVICE_PORT', RESTAPI_SERVICE_PORT) + restapi_base_url = os.environ.get('RESTAPI_BASE_URL', RESTAPI_BASE_URL ) + metrics_port = os.environ.get('METRICS_PORT', METRICS_PORT ) logging.basicConfig(level=log_level) logger = logging.getLogger(__name__) @@ -36,17 +41,23 @@ def main(): database = get_database() # Starting context service - service = ContextService(database, port=service_port, max_workers=max_workers, grace_period=grace_period) - service.start() + grpc_service = ContextService(database, port=grpc_service_port, max_workers=max_workers, grace_period=grace_period) + grpc_service.start() + + rest_server = Server(port=restapi_service_port, base_url=restapi_base_url) + rest_server.add_resource(Context, '/restconf/config/context', endpoint='api.context') + rest_server.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(0.1): pass + while not terminate.wait(timeout=0.1): pass logger.info('Terminating...') - service.stop() + grpc_service.stop() + rest_server.shutdown() + rest_server.join() logger.info('Bye') - return(0) + return 0 if __name__ == '__main__': sys.exit(main()) diff --git a/src/context/service/rest_server/Server.py b/src/context/service/rest_server/Server.py new file mode 100644 index 000000000..e51970612 --- /dev/null +++ b/src/context/service/rest_server/Server.py @@ -0,0 +1,30 @@ +import logging, threading +from flask import Flask +from flask_restful import Api +from werkzeug.serving import make_server +from context.Config import RESTAPI_BASE_URL, RESTAPI_SERVICE_PORT + +logging.getLogger('werkzeug').setLevel(logging.WARNING) + +BIND_ADDRESS = '0.0.0.0' +LOGGER = logging.getLogger(__name__) + +class Server(threading.Thread): + def __init__(self, host=BIND_ADDRESS, port=RESTAPI_SERVICE_PORT, base_url=RESTAPI_BASE_URL): + threading.Thread.__init__(self, daemon=True) + self.host = host + self.port = port + self.app = Flask(__name__) + self.api = Api(self.app, prefix=base_url) + + def add_resource(self, resource, *urls, **kwargs): + self.api.add_resource(resource, *urls, **kwargs) + + def run(self): + self.srv = make_server(self.host, self.port, self.app, threaded=True) + self.ctx = self.app.app_context() + self.ctx.push() + self.srv.serve_forever() + + def shutdown(self): + self.srv.shutdown() diff --git a/src/context/service/rest_server/__init__.py b/src/context/service/rest_server/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/context/service/rest_server/resources/Context.py b/src/context/service/rest_server/resources/Context.py new file mode 100644 index 000000000..421ad4a2a --- /dev/null +++ b/src/context/service/rest_server/resources/Context.py @@ -0,0 +1,9 @@ +from flask.json import jsonify +from flask_restful import Resource +from common.database.Factory import get_database +from common.database.api.context.Constants import DEFAULT_CONTEXT_ID + +class Context(Resource): + def get(self): + database = get_database() + return jsonify(database.context(DEFAULT_CONTEXT_ID).dump()) diff --git a/src/context/service/rest_server/resources/__init__.py b/src/context/service/rest_server/resources/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/device/service/__main__.py b/src/device/service/__main__.py index ae7db591c..3ac9893a1 100644 --- a/src/device/service/__main__.py +++ b/src/device/service/__main__.py @@ -16,10 +16,10 @@ def main(): global terminate, logger service_port = os.environ.get('DEVICESERVICE_SERVICE_PORT_GRPC', GRPC_SERVICE_PORT) - max_workers = os.environ.get('MAX_WORKERS', GRPC_MAX_WORKERS ) - grace_period = os.environ.get('GRACE_PERIOD', GRPC_GRACE_PERIOD) - log_level = os.environ.get('LOG_LEVEL', LOG_LEVEL ) - metrics_port = os.environ.get('METRICS_PORT', METRICS_PORT) + max_workers = os.environ.get('MAX_WORKERS', GRPC_MAX_WORKERS ) + grace_period = os.environ.get('GRACE_PERIOD', GRPC_GRACE_PERIOD) + log_level = os.environ.get('LOG_LEVEL', LOG_LEVEL ) + metrics_port = os.environ.get('METRICS_PORT', METRICS_PORT ) logging.basicConfig(level=log_level) logger = logging.getLogger(__name__) @@ -36,17 +36,17 @@ def main(): database = get_database() # Starting device service - service = DeviceService(database, port=service_port, max_workers=max_workers, grace_period=grace_period) - service.start() + grpc_service = DeviceService(database, port=service_port, max_workers=max_workers, grace_period=grace_period) + grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(0.1): pass + while not terminate.wait(timeout=0.1): pass logger.info('Terminating...') - service.stop() + grpc_service.stop() logger.info('Bye') - return(0) + return 0 if __name__ == '__main__': sys.exit(main()) diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py index 2eef35983..f492d9096 100644 --- a/src/service/service/__main__.py +++ b/src/service/service/__main__.py @@ -16,10 +16,10 @@ def main(): global terminate, logger service_port = os.environ.get('SERVICESERVICE_SERVICE_PORT_GRPC', GRPC_SERVICE_PORT) - max_workers = os.environ.get('MAX_WORKERS', GRPC_MAX_WORKERS ) - grace_period = os.environ.get('GRACE_PERIOD', GRPC_GRACE_PERIOD) - log_level = os.environ.get('LOG_LEVEL', LOG_LEVEL ) - metrics_port = os.environ.get('METRICS_PORT', METRICS_PORT) + max_workers = os.environ.get('MAX_WORKERS', GRPC_MAX_WORKERS ) + grace_period = os.environ.get('GRACE_PERIOD', GRPC_GRACE_PERIOD) + log_level = os.environ.get('LOG_LEVEL', LOG_LEVEL ) + metrics_port = os.environ.get('METRICS_PORT', METRICS_PORT ) logging.basicConfig(level=log_level) logger = logging.getLogger(__name__) @@ -36,17 +36,17 @@ def main(): database = get_database() # Starting service service - service = ServiceService(database, port=service_port, max_workers=max_workers, grace_period=grace_period) - service.start() + grpc_service = ServiceService(database, port=service_port, max_workers=max_workers, grace_period=grace_period) + grpc_service.start() # Wait for Ctrl+C or termination signal - while not terminate.wait(0.1): pass + while not terminate.wait(timeout=0.1): pass logger.info('Terminating...') - service.stop() + grpc_service.stop() logger.info('Bye') - return(0) + return 0 if __name__ == '__main__': sys.exit(main()) -- GitLab