[PMSH] Adding cbs module support 73/106473/1
authorefiacor <fiachra.corcoran@est.tech>
Tue, 21 Apr 2020 12:39:35 +0000 (13:39 +0100)
committerefiacor <fiachra.corcoran@est.tech>
Wed, 22 Apr 2020 13:41:17 +0000 (14:41 +0100)
Signed-off-by: efiacor <fiachra.corcoran@est.tech>
Change-Id: Ie711995a3c7a2111f6cb872952507f511c0de6dd
Issue-ID: DCAEGEN2-2156

components/pm-subscription-handler/pmsh_service/mod/aai_client.py
components/pm-subscription-handler/pmsh_service/mod/config_handler.py [deleted file]
components/pm-subscription-handler/pmsh_service/mod/pmsh_logging.py
components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
components/pm-subscription-handler/pmsh_service/pmsh_service_main.py
components/pm-subscription-handler/setup.py
components/pm-subscription-handler/tests/test_aai_service.py
components/pm-subscription-handler/tests/test_config_handler.py [deleted file]
components/pm-subscription-handler/tests/test_subscription_handler.py

index 86cecb5..5e71da4 100755 (executable)
@@ -55,7 +55,7 @@ def _get_all_aai_nf_data():
     Return queried nf data from the AAI service.
 
     Returns:
-        json: the json response from AAI query, else None.
+        dict: the json response from AAI query, else None.
     """
     nf_data = None
     try:
@@ -94,7 +94,7 @@ def _get_aai_service_url():
     """
     try:
         aai_service = environ['AAI_SERVICE_HOST']
-        aai_ssl_port = environ['AAI_SERVICE_PORT_AAI_SSL']
+        aai_ssl_port = environ['AAI_SERVICE_PORT']
         return f'https://{aai_service}:{aai_ssl_port}'
     except KeyError as e:
         logger.debug(f'Failed to get AAI env vars: {e}')
diff --git a/components/pm-subscription-handler/pmsh_service/mod/config_handler.py b/components/pm-subscription-handler/pmsh_service/mod/config_handler.py
deleted file mode 100755 (executable)
index 26b0315..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# ============LICENSE_START===================================================
-#  Copyright (C) 2019-2020 Nordix Foundation.
-# ============================================================================
-# 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.
-#
-# SPDX-License-Identifier: Apache-2.0
-# ============LICENSE_END=====================================================
-
-from os import environ
-
-import requests
-from tenacity import retry, wait_fixed, stop_after_attempt, retry_if_exception_type
-
-import mod.pmsh_logging as logger
-
-
-class ConfigHandler:
-    """ Handles retrieval of PMSH's configuration from Configbinding service."""
-
-    def __init__(self):
-        self.cbs_url = f'http://{self.cbs_hostname}:{str(self.cbs_port)}/' \
-            f'service_component_all/{self.hostname}'
-        self._config = None
-
-    @property
-    def cbs_hostname(self):
-        return _get_environment_variable('CONFIG_BINDING_SERVICE_SERVICE_HOST')
-
-    @property
-    def cbs_port(self):
-        return _get_environment_variable('CONFIG_BINDING_SERVICE_SERVICE_PORT')
-
-    @property
-    def hostname(self):
-        return _get_environment_variable('HOSTNAME')
-
-    @retry(wait=wait_fixed(2), stop=stop_after_attempt(5), retry=retry_if_exception_type(Exception))
-    def get_config(self):
-        """ Retrieves PMSH's configuration from Configbinding service. If a non-2xx response
-        is received, it retries after 2 seconds for 5 times before raising an exception.
-
-        Returns:
-            dict: Dictionary representation of the the service configuration
-
-        Raises:
-            Exception: If any error occurred pulling configuration from Configbinding service.
-        """
-
-        try:
-            response = requests.get(self.cbs_url)
-            response.raise_for_status()
-            self._config = response.json()
-            logger.debug(f'PMSH Configuration from Configbinding Service: {self._config}')
-            return self._config
-        except Exception as err:
-            raise Exception(f'Error retrieving configuration from CBS: {err}')
-
-
-def _get_environment_variable(env_var_key):
-    try:
-        env_var = environ[env_var_key]
-    except KeyError as error:
-        raise KeyError(f'Environment variable {env_var_key} must be set. {error}')
-    return env_var
index 885644b..e0a7e1b 100644 (file)
@@ -17,6 +17,7 @@
 # ============LICENSE_END=====================================================
 import datetime
 import logging as log
+import sys
 from logging.handlers import RotatingFileHandler
 from os import makedirs
 
@@ -41,7 +42,9 @@ def _create_logger(name, logfile):
     formatter = log.Formatter("%(message)s")
     file_handler.setFormatter(formatter)
     logger.setLevel(log.DEBUG)
+    stdout_handler = log.StreamHandler(sys.stdout)
     logger.addHandler(file_handler)
+    logger.addHandler(stdout_handler)
     return logger
 
 
@@ -107,7 +110,7 @@ def debug(msg="n/a"):
     """
     ets = utc()
 
-    _DEBUG_LOGGER.info(
+    _DEBUG_LOGGER.debug(
         "{ets}|{msg}".format(
             ets=ets.isoformat(),
             msg=msg,
index 750b721..8db3c1f 100755 (executable)
@@ -20,11 +20,36 @@ import uuid
 from threading import Timer
 
 import requests
+from onap_dcae_cbs_docker_client.client import get_all
 from requests.auth import HTTPBasicAuth
+from tenacity import wait_fixed, stop_after_attempt, retry, retry_if_exception_type
 
 import mod.pmsh_logging as logger
 
 
+class ConfigHandler:
+    """ Handles retrieval of PMSH's configuration from Configbinding service."""
+    @staticmethod
+    @retry(wait=wait_fixed(2), stop=stop_after_attempt(5), retry=retry_if_exception_type(Exception))
+    def get_pmsh_config():
+        """ Retrieves PMSH's configuration from Config binding service. If a non-2xx response
+        is received, it retries after 2 seconds for 5 times before raising an exception.
+
+        Returns:
+            dict: Dictionary representation of the the service configuration
+
+        Raises:
+            Exception: If any error occurred pulling configuration from Config binding service.
+        """
+        try:
+            config = get_all()
+            logger.debug(f'PMSH config from CBS: {config}')
+            return config
+        except Exception as err:
+            logger.debug(f'Failed to get config from CBS: {err}')
+            raise Exception
+
+
 class AppConfig:
     def __init__(self, **kwargs):
         self.aaf_creds = {'aaf_id': kwargs.get('aaf_identity'),
index 40b8c96..4d4c531 100644 (file)
 
 import mod.aai_client as aai
 import mod.pmsh_logging as logger
+from mod.pmsh_utils import ConfigHandler
 from mod.subscription import AdministrativeState
 
 
 class SubscriptionHandler:
-    def __init__(self, config_handler, administrative_state, mr_pub, app, app_conf,
-                 aai_event_thread):
+    def __init__(self, administrative_state, mr_pub, app, app_conf, aai_event_thread):
         self.current_nfs = None
         self.current_sub = None
-        self.config_handler = config_handler
         self.administrative_state = administrative_state
         self.mr_pub = mr_pub
         self.app = app
@@ -39,7 +38,7 @@ class SubscriptionHandler:
         the Subscription if a change has occurred
         """
         self.app.app_context().push()
-        config = self.config_handler.get_config()
+        config = ConfigHandler.get_pmsh_config()
         new_administrative_state = config['policy']['subscription']['administrativeState']
 
         try:
index 60cf89c..a2ba1fd 100755 (executable)
@@ -23,9 +23,8 @@ import mod.aai_client as aai
 import mod.pmsh_logging as logger
 from mod import db, create_app, launch_api_server
 from mod.aai_event_handler import process_aai_events
-from mod.config_handler import ConfigHandler
 from mod.exit_handler import ExitHandler
-from mod.pmsh_utils import AppConfig, PeriodicTask
+from mod.pmsh_utils import AppConfig, PeriodicTask, ConfigHandler
 from mod.policy_response_handler import PolicyResponseHandler
 from mod.subscription import Subscription, AdministrativeState
 from mod.subscription_handler import SubscriptionHandler
@@ -33,12 +32,13 @@ from mod.subscription_handler import SubscriptionHandler
 
 def main():
     try:
-        config_handler = ConfigHandler()
-        config = config_handler.get_config()
-        app_conf = AppConfig(**config['config'])
         app = create_app()
         app.app_context().push()
         db.create_all(app=app)
+
+        config = ConfigHandler.get_pmsh_config()
+        app_conf = AppConfig(**config['config'])
+
         sub, nfs = aai.get_pmsh_subscription_data(config)
         policy_mr_pub = app_conf.get_mr_pub('policy_pm_publisher')
         policy_mr_sub = app_conf.get_mr_sub('policy_pm_subscriber')
@@ -50,7 +50,7 @@ def main():
         aai_event_thread = PeriodicTask(10, process_aai_events,
                                         args=(mr_aai_event_sub,
                                               sub, policy_mr_pub, app, app_conf))
-        subscription_handler = SubscriptionHandler(config_handler, administrative_state,
+        subscription_handler = SubscriptionHandler(administrative_state,
                                                    policy_mr_pub, app, app_conf, aai_event_thread)
         policy_response_handler = PolicyResponseHandler(policy_mr_sub, sub.subscriptionName, app)
 
index 056a5d8..0437f5d 100644 (file)
@@ -34,5 +34,6 @@ setup(
         "connexion==2.5.0",
         "flask_sqlalchemy==2.4.1",
         "Flask==1.1.1",
-        "psycopg2-binary==2.8.4"]
+        "psycopg2-binary==2.8.4",
+        "onap_dcae_cbs_docker_client==2.1.0"]
 )
index aaf2bb1..1ee7155 100644 (file)
@@ -32,7 +32,7 @@ class AaiClientTestCase(TestCase):
     def setUp(self):
         self.env = EnvironmentVarGuard()
         self.env.set('AAI_SERVICE_HOST', '1.2.3.4')
-        self.env.set('AAI_SERVICE_PORT_AAI_SSL', '8443')
+        self.env.set('AAI_SERVICE_PORT', '8443')
         with open(os.path.join(os.path.dirname(__file__), 'data/cbs_data_1.json'), 'r') as data:
             self.cbs_data = json.load(data)
         with open(os.path.join(os.path.dirname(__file__), 'data/aai_xnfs.json'), 'r') as data:
diff --git a/components/pm-subscription-handler/tests/test_config_handler.py b/components/pm-subscription-handler/tests/test_config_handler.py
deleted file mode 100755 (executable)
index dce48fc..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# ============LICENSE_START===================================================
-#  Copyright (C) 2019-2020 Nordix Foundation.
-# ============================================================================
-# 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.
-#
-# SPDX-License-Identifier: Apache-2.0
-# ============LICENSE_END=====================================================
-
-import json
-import unittest
-from os import environ
-from os import path
-
-import responses
-from tenacity import wait_none
-
-from mod.config_handler import ConfigHandler
-
-
-class ConfigHandlerTestCase(unittest.TestCase):
-
-    def setUp(self):
-        self.env_vars = {'CONFIG_BINDING_SERVICE_SERVICE_HOST': 'cbs_hostname',
-                         'CONFIG_BINDING_SERVICE_SERVICE_PORT': '10000',
-                         'HOSTNAME': 'hostname'}
-        for key, value in self.env_vars.items():
-            environ[key] = value
-        self.cbs_url = 'http://cbs_hostname:10000/service_component_all/hostname'
-        with open(path.join(path.dirname(__file__), 'data/cbs_data_2.json'))as json_file:
-            self.expected_config = json.load(json_file)
-
-    def test_missing_environment_variable(self):
-        for key, value in self.env_vars.items():
-            with self.assertRaises(KeyError):
-                environ.pop(key)
-                test_value = globals()[value]
-                test_value()
-            environ[key] = value
-
-    @responses.activate
-    def test_get_config_success(self):
-        responses.add(responses.GET, self.cbs_url, json=self.expected_config,
-                      status=200)
-
-        config_handler = ConfigHandler()
-        config_handler.get_config.retry.wait = wait_none()
-
-        self.assertEqual(self.expected_config, config_handler.get_config())
-
-    @responses.activate
-    def test_get_config_error(self):
-        responses.add(responses.GET, self.cbs_url, status=404)
-        config_handler = ConfigHandler()
-        config_handler.get_config.retry.wait = wait_none()
-
-        with self.assertRaises(Exception):
-            config_handler.get_config()
-
-    @responses.activate
-    def test_get_config_max_retries_error(self):
-        retry_limit = 5
-        config_handler = ConfigHandler()
-        config_handler.get_config.retry.wait = wait_none()
-
-        for __ in range(retry_limit):
-            responses.add(responses.GET, self.cbs_url, status=500)
-
-        with self.assertRaises(Exception):
-            config_handler.get_config()
-        self.assertEqual(retry_limit, len(responses.calls))
-
-    @responses.activate
-    def test_get_config_less_than_5_retries_success(self):
-        retry_attempts = 4
-        responses.add(responses.GET, self.cbs_url, status=500)
-        responses.add(responses.GET, self.cbs_url, status=400)
-        responses.add(responses.GET, self.cbs_url, status=300)
-        responses.add(responses.GET, self.cbs_url, json=json.dumps(self.expected_config),
-                      status=200)
-
-        config_handler = ConfigHandler()
-        config_handler.get_config.retry.wait = wait_none()
-        config_handler.get_config()
-
-        self.assertEqual(retry_attempts, len(responses.calls))
index 168d036..d922b96 100644 (file)
@@ -30,17 +30,15 @@ class SubscriptionHandlerTest(TestCase):
     @patch('mod.create_app')
     @patch('mod.subscription.Subscription')
     @patch('mod.pmsh_utils._MrPub')
-    @patch('mod.config_handler.ConfigHandler')
     @patch('mod.pmsh_utils.AppConfig')
     @patch('mod.pmsh_utils.PeriodicTask')
-    def setUp(self, mock_aai_event_thread, mock_app_conf, mock_config_handler, mock_mr_pub,
+    def setUp(self, mock_aai_event_thread, mock_app_conf, mock_mr_pub,
               mock_sub, mock_app):
         with open(os.path.join(os.path.dirname(__file__), 'data/cbs_data_1.json'), 'r') as data:
             self.cbs_data_1 = json.load(data)
         self.mock_app = mock_app
         self.mock_sub = mock_sub
         self.mock_mr_pub = mock_mr_pub
-        self.mock_config_handler = mock_config_handler
         self.mock_app_conf = mock_app_conf
         self.mock_aai_event_thread = mock_aai_event_thread
         self.nf_1 = NetworkFunction(nf_name='pnf_1')
@@ -51,25 +49,22 @@ class SubscriptionHandlerTest(TestCase):
     @patch('mod.aai_client.get_pmsh_subscription_data')
     def test_execute_no_change_of_state(self, mock_get_aai, mock_logger):
         mock_get_aai.return_value = self.mock_sub, self.nfs
-        self.mock_config_handler.get_config.return_value = self.cbs_data_1
-        sub_handler = SubscriptionHandler(self.mock_config_handler,
-                                          AdministrativeState.UNLOCKED.value, self.mock_mr_pub,
+        sub_handler = SubscriptionHandler(AdministrativeState.UNLOCKED.value, self.mock_mr_pub,
                                           self.mock_app, self.mock_app_conf,
                                           self.mock_aai_event_thread)
-        sub_handler.execute()
-
+        with patch('mod.pmsh_utils.ConfigHandler.get_pmsh_config', return_value=self.cbs_data_1):
+            sub_handler.execute()
         mock_logger.assert_called_with('Administrative State did not change in the Config')
 
     @patch('mod.aai_client.get_pmsh_subscription_data')
     def test_execute_change_of_state_unlocked(self, mock_get_aai):
         mock_get_aai.return_value = self.mock_sub, self.nfs
         self.mock_aai_event_thread.return_value.start.return_value = 'start_method'
-        self.mock_config_handler.get_config.return_value = self.cbs_data_1
-        sub_handler = SubscriptionHandler(self.mock_config_handler,
-                                          AdministrativeState.LOCKED.value, self.mock_mr_pub,
+        sub_handler = SubscriptionHandler(AdministrativeState.LOCKED.value, self.mock_mr_pub,
                                           self.mock_app, self.mock_app_conf,
                                           self.mock_aai_event_thread.return_value)
-        sub_handler.execute()
+        with patch('mod.pmsh_utils.ConfigHandler.get_pmsh_config', return_value=self.cbs_data_1):
+            sub_handler.execute()
 
         self.assertEqual(AdministrativeState.UNLOCKED.value, sub_handler.administrative_state)
         self.mock_sub.process_subscription.assert_called_with(self.nfs, self.mock_mr_pub,
@@ -82,12 +77,11 @@ class SubscriptionHandlerTest(TestCase):
         self.mock_aai_event_thread.return_value.cancel.return_value = 'cancel_method'
         self.cbs_data_1['policy']['subscription']['administrativeState'] = \
             AdministrativeState.LOCKED.value
-        self.mock_config_handler.get_config.return_value = self.cbs_data_1
-        sub_handler = SubscriptionHandler(self.mock_config_handler,
-                                          AdministrativeState.UNLOCKED.value, self.mock_mr_pub,
+        sub_handler = SubscriptionHandler(AdministrativeState.UNLOCKED.value, self.mock_mr_pub,
                                           self.mock_app, self.mock_app_conf,
                                           self.mock_aai_event_thread.return_value)
-        sub_handler.execute()
+        with patch('mod.pmsh_utils.ConfigHandler.get_pmsh_config', return_value=self.cbs_data_1):
+            sub_handler.execute()
 
         self.assertEqual(AdministrativeState.LOCKED.value, sub_handler.administrative_state)
         self.mock_sub.process_subscription.assert_called_with(self.nfs, self.mock_mr_pub,
@@ -98,12 +92,11 @@ class SubscriptionHandlerTest(TestCase):
     @patch('mod.aai_client.get_pmsh_subscription_data')
     def test_execute_exception(self, mock_get_aai, mock_logger):
         mock_get_aai.return_value = self.mock_sub, self.nfs
-        self.mock_config_handler.get_config.return_value = self.cbs_data_1
         self.mock_sub.process_subscription.side_effect = Exception
-        sub_handler = SubscriptionHandler(self.mock_config_handler,
-                                          AdministrativeState.LOCKED.value, self.mock_mr_pub,
+        sub_handler = SubscriptionHandler(AdministrativeState.LOCKED.value, self.mock_mr_pub,
                                           self.mock_app, self.mock_app_conf,
                                           self.mock_aai_event_thread)
-        sub_handler.execute()
+        with patch('mod.pmsh_utils.ConfigHandler.get_pmsh_config', return_value=self.cbs_data_1):
+            sub_handler.execute()
 
         mock_logger.assert_called_with('Error occurred during the activation/deactivation process ')