Loading src/context/Config.py +0 −17 Original line number Diff line number Diff line Loading @@ -12,22 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging # General settings LOG_LEVEL = logging.INFO # gRPC settings GRPC_SERVICE_PORT = 1010 GRPC_MAX_WORKERS = 200 # multiple clients might keep connections alive for Get*Events() RPC methods GRPC_GRACE_PERIOD = 60 # REST-API settings RESTAPI_SERVICE_PORT = 8080 RESTAPI_BASE_URL = '/api' # Prometheus settings METRICS_PORT = 9192 # Autopopulate the component with fake data for testing purposes? POPULATE_FAKE_DATA = False src/context/client/ContextClient.py +8 −4 Original line number Diff line number Diff line Loading @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Iterator import grpc, logging from typing import Iterator from common.Constants import ServiceNameEnum from common.Settings import get_service_host, get_service_port_grpc from common.tools.client.RetryDecorator import retry, delay_exponential from common.tools.grpc.Tools import grpc_message_to_json_string from context.proto.context_pb2 import ( Loading @@ -29,9 +31,11 @@ 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 ContextClient: def __init__(self, address, port): self.endpoint = '{:s}:{:s}'.format(str(address), str(port)) LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint)) def __init__(self, host=None, port=None): if not host: host = get_service_host(ServiceNameEnum.CONTEXT) if not port: port = get_service_port_grpc(ServiceNameEnum.CONTEXT) self.endpoint = '{:s}:{:s}'.format(str(host), str(port)) LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint))) self.channel = None self.stub = None self.connect() Loading src/context/service/Populate.py +2 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,8 @@ from context.tests.Objects import ( LINK_R1_R2, LINK_R1_R2_ID, LINK_R1_R3, LINK_R1_R3_ID, LINK_R2_R3, LINK_R2_R3_ID, SERVICE_R1_R2, SERVICE_R1_R3, SERVICE_R2_R3) def populate(address, port): client = ContextClient(address=address, port=port) def populate(host=None, port=None): client = ContextClient(host=host, port=port) client.SetContext(Context(**CONTEXT)) client.SetTopology(Topology(**TOPOLOGY)) Loading src/context/service/__main__.py +10 −19 Original line number Diff line number Diff line Loading @@ -14,17 +14,15 @@ import logging, signal, sys, threading from prometheus_client import start_http_server from common.Settings import get_setting from common.Settings import get_log_level, get_metrics_port, get_setting from common.orm.Database import Database from common.orm.Factory import get_database_backend from common.message_broker.Factory import get_messagebroker_backend from common.message_broker.MessageBroker import MessageBroker from context.Config import ( GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, POPULATE_FAKE_DATA, RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL, METRICS_PORT) from context.Config import POPULATE_FAKE_DATA from .grpc_server.ContextService import ContextService from .rest_server.Resources import RESOURCES from .rest_server.Server import Server from .rest_server.RestServer import RestServer from .Populate import populate terminate = threading.Event() Loading @@ -37,16 +35,7 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name def main(): global LOGGER # pylint: disable=global-statement grpc_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT ) max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD ) log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) restapi_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_HTTP', default=RESTAPI_SERVICE_PORT) restapi_base_url = get_setting('RESTAPI_BASE_URL', default=RESTAPI_BASE_URL ) metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) populate_fake_data = get_setting('POPULATE_FAKE_DATA', default=POPULATE_FAKE_DATA ) if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'}) log_level = get_log_level() logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) Loading @@ -56,6 +45,7 @@ def main(): LOGGER.info('Starting...') # Start metrics server metrics_port = get_metrics_port() start_http_server(metrics_port) # Get database instance Loading @@ -65,18 +55,19 @@ def main(): messagebroker = MessageBroker(get_messagebroker_backend()) # Starting context service grpc_service = ContextService( database, messagebroker, port=grpc_service_port, max_workers=max_workers, grace_period=grace_period) grpc_service = ContextService(database, messagebroker) grpc_service.start() rest_server = Server(port=restapi_service_port, base_url=restapi_base_url) rest_server = RestServer() for endpoint_name, resource_class, resource_url in RESOURCES: rest_server.add_resource(resource_class, resource_url, endpoint=endpoint_name, resource_class_args=(database,)) rest_server.start() populate_fake_data = get_setting('POPULATE_FAKE_DATA', default=POPULATE_FAKE_DATA) if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'}) if populate_fake_data: LOGGER.info('Populating fake data...') populate('127.0.0.1', grpc_service_port) populate(host='127.0.0.1', port=grpc_service.bind_port) LOGGER.info('Fake Data populated') # Wait for Ctrl+C or termination signal Loading src/context/service/grpc_server/ContextService.py +13 −52 Original line number Diff line number Diff line Loading @@ -12,61 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. import grpc import logging from concurrent import futures from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH from grpc_health.v1.health_pb2 import HealthCheckResponse from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD from common.Constants import ServiceNameEnum from common.Settings import get_service_port_grpc from common.message_broker.MessageBroker import MessageBroker from common.orm.Database import Database from common.tools.service.GenericGrpcService import GenericGrpcService from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server from .ContextServiceServicerImpl import ContextServiceServicerImpl BIND_ADDRESS = '0.0.0.0' LOGGER = logging.getLogger(__name__) # Custom gRPC settings GRPC_MAX_WORKERS = 200 # multiple clients might keep connections alive for Get*Events() RPC methods class ContextService: def __init__( self, database, messagebroker, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD): class ContextService(GenericGrpcService): def __init__(self, database : Database, messagebroker : MessageBroker, cls_name: str = __name__) -> None: port = get_service_port_grpc(ServiceNameEnum.CONTEXT) super().__init__(port, max_workers=GRPC_MAX_WORKERS, cls_name=cls_name) self.context_servicer = ContextServiceServicerImpl(database, messagebroker) self.database = database self.messagebroker = messagebroker self.address = address self.port = port self.endpoint = None self.max_workers = max_workers self.grace_period = grace_period self.context_servicer = None self.health_servicer = None self.pool = None self.server = None def start(self): self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port)) LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format( str(self.endpoint), str(self.max_workers))) self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers) self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,)) self.context_servicer = ContextServiceServicerImpl(self.database, self.messagebroker) def install_servicers(self): add_ContextServiceServicer_to_server(self.context_servicer, self.server) self.health_servicer = HealthServicer( experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1)) add_HealthServicer_to_server(self.health_servicer, self.server) port = self.server.add_insecure_port(self.endpoint) self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port)) LOGGER.info('Listening on {:s}...'.format(str(self.endpoint))) self.server.start() self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member LOGGER.debug('Service started') def stop(self): LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period))) self.health_servicer.enter_graceful_shutdown() self.server.stop(self.grace_period) LOGGER.debug('Service stopped') Loading
src/context/Config.py +0 −17 Original line number Diff line number Diff line Loading @@ -12,22 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging # General settings LOG_LEVEL = logging.INFO # gRPC settings GRPC_SERVICE_PORT = 1010 GRPC_MAX_WORKERS = 200 # multiple clients might keep connections alive for Get*Events() RPC methods GRPC_GRACE_PERIOD = 60 # REST-API settings RESTAPI_SERVICE_PORT = 8080 RESTAPI_BASE_URL = '/api' # Prometheus settings METRICS_PORT = 9192 # Autopopulate the component with fake data for testing purposes? POPULATE_FAKE_DATA = False
src/context/client/ContextClient.py +8 −4 Original line number Diff line number Diff line Loading @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Iterator import grpc, logging from typing import Iterator from common.Constants import ServiceNameEnum from common.Settings import get_service_host, get_service_port_grpc from common.tools.client.RetryDecorator import retry, delay_exponential from common.tools.grpc.Tools import grpc_message_to_json_string from context.proto.context_pb2 import ( Loading @@ -29,9 +31,11 @@ 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 ContextClient: def __init__(self, address, port): self.endpoint = '{:s}:{:s}'.format(str(address), str(port)) LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint)) def __init__(self, host=None, port=None): if not host: host = get_service_host(ServiceNameEnum.CONTEXT) if not port: port = get_service_port_grpc(ServiceNameEnum.CONTEXT) self.endpoint = '{:s}:{:s}'.format(str(host), str(port)) LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint))) self.channel = None self.stub = None self.connect() Loading
src/context/service/Populate.py +2 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,8 @@ from context.tests.Objects import ( LINK_R1_R2, LINK_R1_R2_ID, LINK_R1_R3, LINK_R1_R3_ID, LINK_R2_R3, LINK_R2_R3_ID, SERVICE_R1_R2, SERVICE_R1_R3, SERVICE_R2_R3) def populate(address, port): client = ContextClient(address=address, port=port) def populate(host=None, port=None): client = ContextClient(host=host, port=port) client.SetContext(Context(**CONTEXT)) client.SetTopology(Topology(**TOPOLOGY)) Loading
src/context/service/__main__.py +10 −19 Original line number Diff line number Diff line Loading @@ -14,17 +14,15 @@ import logging, signal, sys, threading from prometheus_client import start_http_server from common.Settings import get_setting from common.Settings import get_log_level, get_metrics_port, get_setting from common.orm.Database import Database from common.orm.Factory import get_database_backend from common.message_broker.Factory import get_messagebroker_backend from common.message_broker.MessageBroker import MessageBroker from context.Config import ( GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, POPULATE_FAKE_DATA, RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL, METRICS_PORT) from context.Config import POPULATE_FAKE_DATA from .grpc_server.ContextService import ContextService from .rest_server.Resources import RESOURCES from .rest_server.Server import Server from .rest_server.RestServer import RestServer from .Populate import populate terminate = threading.Event() Loading @@ -37,16 +35,7 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name def main(): global LOGGER # pylint: disable=global-statement grpc_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT ) max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD ) log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) restapi_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_HTTP', default=RESTAPI_SERVICE_PORT) restapi_base_url = get_setting('RESTAPI_BASE_URL', default=RESTAPI_BASE_URL ) metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) populate_fake_data = get_setting('POPULATE_FAKE_DATA', default=POPULATE_FAKE_DATA ) if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'}) log_level = get_log_level() logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) Loading @@ -56,6 +45,7 @@ def main(): LOGGER.info('Starting...') # Start metrics server metrics_port = get_metrics_port() start_http_server(metrics_port) # Get database instance Loading @@ -65,18 +55,19 @@ def main(): messagebroker = MessageBroker(get_messagebroker_backend()) # Starting context service grpc_service = ContextService( database, messagebroker, port=grpc_service_port, max_workers=max_workers, grace_period=grace_period) grpc_service = ContextService(database, messagebroker) grpc_service.start() rest_server = Server(port=restapi_service_port, base_url=restapi_base_url) rest_server = RestServer() for endpoint_name, resource_class, resource_url in RESOURCES: rest_server.add_resource(resource_class, resource_url, endpoint=endpoint_name, resource_class_args=(database,)) rest_server.start() populate_fake_data = get_setting('POPULATE_FAKE_DATA', default=POPULATE_FAKE_DATA) if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'}) if populate_fake_data: LOGGER.info('Populating fake data...') populate('127.0.0.1', grpc_service_port) populate(host='127.0.0.1', port=grpc_service.bind_port) LOGGER.info('Fake Data populated') # Wait for Ctrl+C or termination signal Loading
src/context/service/grpc_server/ContextService.py +13 −52 Original line number Diff line number Diff line Loading @@ -12,61 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. import grpc import logging from concurrent import futures from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH from grpc_health.v1.health_pb2 import HealthCheckResponse from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD from common.Constants import ServiceNameEnum from common.Settings import get_service_port_grpc from common.message_broker.MessageBroker import MessageBroker from common.orm.Database import Database from common.tools.service.GenericGrpcService import GenericGrpcService from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server from .ContextServiceServicerImpl import ContextServiceServicerImpl BIND_ADDRESS = '0.0.0.0' LOGGER = logging.getLogger(__name__) # Custom gRPC settings GRPC_MAX_WORKERS = 200 # multiple clients might keep connections alive for Get*Events() RPC methods class ContextService: def __init__( self, database, messagebroker, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD): class ContextService(GenericGrpcService): def __init__(self, database : Database, messagebroker : MessageBroker, cls_name: str = __name__) -> None: port = get_service_port_grpc(ServiceNameEnum.CONTEXT) super().__init__(port, max_workers=GRPC_MAX_WORKERS, cls_name=cls_name) self.context_servicer = ContextServiceServicerImpl(database, messagebroker) self.database = database self.messagebroker = messagebroker self.address = address self.port = port self.endpoint = None self.max_workers = max_workers self.grace_period = grace_period self.context_servicer = None self.health_servicer = None self.pool = None self.server = None def start(self): self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port)) LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format( str(self.endpoint), str(self.max_workers))) self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers) self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,)) self.context_servicer = ContextServiceServicerImpl(self.database, self.messagebroker) def install_servicers(self): add_ContextServiceServicer_to_server(self.context_servicer, self.server) self.health_servicer = HealthServicer( experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1)) add_HealthServicer_to_server(self.health_servicer, self.server) port = self.server.add_insecure_port(self.endpoint) self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port)) LOGGER.info('Listening on {:s}...'.format(str(self.endpoint))) self.server.start() self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member LOGGER.debug('Service started') def stop(self): LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period))) self.health_servicer.enter_graceful_shutdown() self.server.stop(self.grace_period) LOGGER.debug('Service stopped')