From d8facaa17d35af37291192d09a783c620bc379c5 Mon Sep 17 00:00:00 2001 From: Edyta Krukowska Date: Thu, 25 Mar 2021 08:26:18 +0100 Subject: Run flask at image start Issue-ID: INT-1869 Signed-off-by: Edyta Krukowska Change-Id: I4fa3e16e5d4520b449274b67d8f7bca3c16f57a6 --- .../netconf_server/netconf_change_listener.py | 39 +++++++++++++++++ .../netconf_change_listener_factory.py | 40 +++++++++++++++++ src/python/netconf_server/netconf_rest_server.py | 50 ++++++++++++++++++++++ src/python/netconf_server/netconf_server.py | 39 ----------------- .../netconf_server/netconf_server_factory.py | 40 ----------------- src/python/netconf_server_application.py | 29 +++++++------ src/python/requirements.txt | 1 + .../tests/netconf_server/test_netconf_server.py | 6 +-- 8 files changed, 150 insertions(+), 94 deletions(-) create mode 100644 src/python/netconf_server/netconf_change_listener.py create mode 100644 src/python/netconf_server/netconf_change_listener_factory.py create mode 100644 src/python/netconf_server/netconf_rest_server.py delete mode 100644 src/python/netconf_server/netconf_server.py delete mode 100644 src/python/netconf_server/netconf_server_factory.py (limited to 'src') diff --git a/src/python/netconf_server/netconf_change_listener.py b/src/python/netconf_server/netconf_change_listener.py new file mode 100644 index 0000000..4bb748c --- /dev/null +++ b/src/python/netconf_server/netconf_change_listener.py @@ -0,0 +1,39 @@ +### +# ============LICENSE_START======================================================= +# Netconf Server +# ================================================================================ +# Copyright (C) 2021 Nokia. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +### +import logging + +from netconf_server.sysrepo_interface.config_change_data import ConfigChangeData + +logger = logging.getLogger("netconf_saver") + + +class NetconfChangeListener(object): + + def __init__(self, subscriptions: list): + self.subscriptions = subscriptions + + def run(self, session): + for subscription in self.subscriptions: + subscription.callback_function = self.__on_module_configuration_change + subscription.subscribe_on_model_change(session) + + @staticmethod + def __on_module_configuration_change(config_change_data: ConfigChangeData): + logger.info("Received module changed: %s , %s " % (config_change_data.event, config_change_data.changes)) diff --git a/src/python/netconf_server/netconf_change_listener_factory.py b/src/python/netconf_server/netconf_change_listener_factory.py new file mode 100644 index 0000000..00725dc --- /dev/null +++ b/src/python/netconf_server/netconf_change_listener_factory.py @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# Netconf Server +# ================================================================================ +# Copyright (C) 2021 Nokia. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +### +import logging + +from netconf_server.netconf_change_listener import NetconfChangeListener +from netconf_server.sysrepo_interface.config_change_subscriber import ConfigChangeSubscriber + +logger = logging.getLogger("netconf_saver") + + +class NetconfChangeListenerFactory(object): + + def __init__(self, modules_to_subscribe_names: list): + self.modules_to_subscribe_names = modules_to_subscribe_names + + def create(self) -> NetconfChangeListener: + subscriptions = list() + for module_name in self.modules_to_subscribe_names: + subscriptions.append( + ConfigChangeSubscriber(module_name) + ) + return NetconfChangeListener(subscriptions) + diff --git a/src/python/netconf_server/netconf_rest_server.py b/src/python/netconf_server/netconf_rest_server.py new file mode 100644 index 0000000..2c44029 --- /dev/null +++ b/src/python/netconf_server/netconf_rest_server.py @@ -0,0 +1,50 @@ +### +# ============LICENSE_START======================================================= +# Netconf Server +# ================================================================================ +# Copyright (C) 2021 Nokia. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +### + +import logging as sys_logging +from flask import Flask, logging, make_response, Response + + +class NetconfRestServer: + _rest_server: Flask = Flask("server") + sys_logging.basicConfig(level=sys_logging.DEBUG) + logger = logging.create_logger(_rest_server) + + def __init__(self, host='0.0.0.0', port=6555): + self._host = host + self._port = port + + def start(self): + Flask.run( + NetconfRestServer._rest_server, + host=self._host, + port=self._port + ) + + @staticmethod + @_rest_server.route("/healthcheck") + def __health_check(): + return "UP" + + @staticmethod + def __create_http_response(code, message): + return make_response( + Response(message, headers={'Content-Type': 'application/json'}), + code) diff --git a/src/python/netconf_server/netconf_server.py b/src/python/netconf_server/netconf_server.py deleted file mode 100644 index b790604..0000000 --- a/src/python/netconf_server/netconf_server.py +++ /dev/null @@ -1,39 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Netconf Server -# ================================================================================ -# Copyright (C) 2021 Nokia. All rights reserved. -# ================================================================================ -# 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. -# ============LICENSE_END========================================================= -### -import logging - -from netconf_server.sysrepo_interface.config_change_data import ConfigChangeData - -logger = logging.getLogger("netconf_saver") - - -class NetconfServer(object): - - def __init__(self, subscriptions: list): - self.subscriptions = subscriptions - - def run(self, session): - for subscription in self.subscriptions: - subscription.callback_function = self.__on_module_configuration_change - subscription.subscribe_on_model_change(session) - - @staticmethod - def __on_module_configuration_change(config_change_data: ConfigChangeData): - logger.info("Received module changed: %s , %s " % (config_change_data.event, config_change_data.changes)) diff --git a/src/python/netconf_server/netconf_server_factory.py b/src/python/netconf_server/netconf_server_factory.py deleted file mode 100644 index 28297ad..0000000 --- a/src/python/netconf_server/netconf_server_factory.py +++ /dev/null @@ -1,40 +0,0 @@ -### -# ============LICENSE_START======================================================= -# Netconf Server -# ================================================================================ -# Copyright (C) 2021 Nokia. All rights reserved. -# ================================================================================ -# 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. -# ============LICENSE_END========================================================= -### -import logging - -from netconf_server.netconf_server import NetconfServer -from netconf_server.sysrepo_interface.config_change_subscriber import ConfigChangeSubscriber - -logger = logging.getLogger("netconf_saver") - - -class NetconfServerFactory(object): - - def __init__(self, modules_to_subscribe_names: list): - self.modules_to_subscribe_names = modules_to_subscribe_names - - def create(self) -> NetconfServer: - subscriptions = list() - for module_name in self.modules_to_subscribe_names: - subscriptions.append( - ConfigChangeSubscriber(module_name) - ) - return NetconfServer(subscriptions) - diff --git a/src/python/netconf_server_application.py b/src/python/netconf_server_application.py index e112490..09dea83 100644 --- a/src/python/netconf_server_application.py +++ b/src/python/netconf_server_application.py @@ -17,38 +17,43 @@ # limitations under the License. # ============LICENSE_END========================================================= ### -import asyncio import sys import logging +from netconf_server.netconf_rest_server import NetconfRestServer -from netconf_server.netconf_server import NetconfServer -from netconf_server.netconf_server_factory import NetconfServerFactory +from netconf_server.netconf_change_listener import NetconfChangeListener +from netconf_server.netconf_change_listener_factory import NetconfChangeListenerFactory from netconf_server.sysrepo_configuration.sysrepo_configuration_loader import SysrepoConfigurationLoader, \ ConfigLoadingException from netconf_server.sysrepo_interface.sysrepo_client import SysrepoClient logging.basicConfig( - handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_saver.log")], + handlers=[logging.StreamHandler(), logging.FileHandler("/logs/netconf_server.log")], level=logging.DEBUG ) -logger = logging.getLogger("netconf_saver") +logger = logging.getLogger("netconf_server") -def run_server_forever(session, server: NetconfServer): - server.run(session) - asyncio.get_event_loop().run_forever() +def run_server_forever(session, change_listener: NetconfChangeListener, server_rest: NetconfRestServer): + change_listener.run(session) + server_rest.start() -def create_configured_server() -> NetconfServer: +def create_change_listener() -> NetconfChangeListener: configuration = SysrepoConfigurationLoader.load_configuration(sys.argv[1]) - return NetconfServerFactory(configuration.models_to_subscribe_to).create() + return NetconfChangeListenerFactory(configuration.models_to_subscribe_to).create() + + +def create_rest_server() -> NetconfRestServer: + return NetconfRestServer() if __name__ == "__main__": if len(sys.argv) >= 2: try: - netconf_server = create_configured_server() - SysrepoClient().run_in_session(run_server_forever, netconf_server) + netconf_change_listener = create_change_listener() + rest_server = create_rest_server() + SysrepoClient().run_in_session(run_server_forever, netconf_change_listener, rest_server) except ConfigLoadingException: logger.error("File to load configuration from file %s" % sys.argv[1]) else: diff --git a/src/python/requirements.txt b/src/python/requirements.txt index ee6c404..0dc606a 100644 --- a/src/python/requirements.txt +++ b/src/python/requirements.txt @@ -19,3 +19,4 @@ ### sysrepo==0.4.2 +Flask==1.1.1 diff --git a/src/python/tests/netconf_server/test_netconf_server.py b/src/python/tests/netconf_server/test_netconf_server.py index 6306dd9..c2889f1 100644 --- a/src/python/tests/netconf_server/test_netconf_server.py +++ b/src/python/tests/netconf_server/test_netconf_server.py @@ -20,7 +20,7 @@ import unittest from unittest.mock import MagicMock -from netconf_server.netconf_server_factory import NetconfServerFactory +from netconf_server.netconf_change_listener_factory import NetconfChangeListenerFactory from tests.mocs.mocked_session import MockedSession @@ -29,7 +29,7 @@ class TestNetconfServer(unittest.TestCase): def test_should_create_and_run_netconf_server_with_one_model(self): # given modules_to_subscribe_names = ["test"] - server = NetconfServerFactory(modules_to_subscribe_names).create() + server = NetconfChangeListenerFactory(modules_to_subscribe_names).create() session = MockedSession() session.subscribe_module_change = MagicMock() @@ -42,7 +42,7 @@ class TestNetconfServer(unittest.TestCase): def test_should_create_and_run_netconf_server_with_multiple_models(self): # given modules_to_subscribe_names = ["test", "test2", "test3"] - server = NetconfServerFactory(modules_to_subscribe_names).create() + server = NetconfChangeListenerFactory(modules_to_subscribe_names).create() session = MockedSession() session.subscribe_module_change = MagicMock() -- cgit 1.2.3-korg