summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcomponents/pm-subscription-handler/Changelog.md1
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/aai_client.py3
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/aai_event_handler.py1
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/api/db_models.py8
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/exit_handler.py17
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/network_function.py21
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/subscription.py22
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/pmsh_service_main.py4
-rwxr-xr-xcomponents/pm-subscription-handler/tests/data/pm_subscription_event.json1
-rw-r--r--components/pm-subscription-handler/tests/test_aai_service.py10
-rwxr-xr-xcomponents/pm-subscription-handler/tests/test_network_function.py2
-rwxr-xr-xcomponents/pm-subscription-handler/tests/test_subscription.py15
12 files changed, 70 insertions, 35 deletions
diff --git a/components/pm-subscription-handler/Changelog.md b/components/pm-subscription-handler/Changelog.md
index ca988296..6e7e0428 100755
--- a/components/pm-subscription-handler/Changelog.md
+++ b/components/pm-subscription-handler/Changelog.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [1.1.2]
### Changed
* Bug fix for missing sdnc params in DELETE event (DCAEGEN2-2483)
+* Fix to add IP to event sent to Policy framework (DCAEGEN2-2486)
## [1.1.1]
### Changed
diff --git a/components/pm-subscription-handler/pmsh_service/mod/aai_client.py b/components/pm-subscription-handler/pmsh_service/mod/aai_client.py
index 73bf8d4c..48f757da 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/aai_client.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/aai_client.py
@@ -97,7 +97,7 @@ def _get_aai_service_url():
"""
try:
aai_ssl_port = environ['AAI_SERVICE_PORT']
- return f'https://aai:{aai_ssl_port}/aai/v20'
+ return f'https://aai:{aai_ssl_port}/aai/v21'
except KeyError as e:
logger.error(f'Failed to get AAI env var: {e}', exc_info=True)
raise
@@ -135,6 +135,7 @@ def _filter_nf_data(nf_data, app_conf):
name_identifier = 'pnf-name' if nf['node-type'] == 'pnf' else 'vnf-name'
new_nf = mod.network_function.NetworkFunction(
nf_name=nf['properties'].get(name_identifier),
+ ip_address=nf['properties'].get('ipaddress-v4-oam'),
model_invariant_id=nf['properties'].get('model-invariant-id'),
model_version_id=nf['properties'].get('model-version-id'))
if not new_nf.set_sdnc_params(app_conf):
diff --git a/components/pm-subscription-handler/pmsh_service/mod/aai_event_handler.py b/components/pm-subscription-handler/pmsh_service/mod/aai_event_handler.py
index 61b42b52..f39f1f46 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/aai_event_handler.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/aai_event_handler.py
@@ -63,6 +63,7 @@ def process_aai_events(mr_sub, mr_pub, app, app_conf):
f'is not "Active"')
continue
nf = NetworkFunction(nf_name=xnf_name,
+ ip_address=aai_entity['ipaddress-v4-oam'],
model_invariant_id=aai_entity['model-invariant-id'],
model_version_id=aai_entity['model-version-id'])
if not nf.set_sdnc_params(app_conf):
diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/db_models.py b/components/pm-subscription-handler/pmsh_service/mod/api/db_models.py
index a8b13e89..b6735cc9 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/api/db_models.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/api/db_models.py
@@ -48,6 +48,7 @@ class SubscriptionModel(db.Model):
def serialize(self):
sub_nfs = NfSubRelationalModel.query.filter(
NfSubRelationalModel.subscription_name == self.subscription_name).all()
+ db.session.remove()
return {'subscription_name': self.subscription_name, 'subscription_status': self.status,
'network_functions': [sub_nf.serialize_nf() for sub_nf in sub_nfs]}
@@ -56,6 +57,7 @@ class NetworkFunctionModel(db.Model):
__tablename__ = 'network_functions'
id = Column(Integer, primary_key=True, autoincrement=True)
nf_name = Column(String(100), unique=True)
+ ip_address = Column(String(50))
model_invariant_id = Column(String(100))
model_version_id = Column(String(100))
sdnc_model_name = Column(String(100))
@@ -66,9 +68,10 @@ class NetworkFunctionModel(db.Model):
cascade='all, delete-orphan',
backref='nf')
- def __init__(self, nf_name, model_invariant_id, model_version_id, sdnc_model_name,
+ def __init__(self, nf_name, ip_address, model_invariant_id, model_version_id, sdnc_model_name,
sdnc_model_version):
self.nf_name = nf_name
+ self.ip_address = ip_address
self.model_invariant_id = model_invariant_id
self.model_version_id = model_version_id
self.sdnc_model_name = sdnc_model_name
@@ -82,6 +85,7 @@ class NetworkFunctionModel(db.Model):
return NetworkFunction(sdnc_model_name=self.sdnc_model_name,
sdnc_model_version=self.sdnc_model_version,
**{'nf_name': self.nf_name,
+ 'ip_address': self.ip_address,
'model_invariant_id': self.model_invariant_id,
'model_version_id': self.model_version_id})
@@ -118,7 +122,9 @@ class NfSubRelationalModel(db.Model):
def serialize_nf(self):
nf = NetworkFunctionModel.query.filter(
NetworkFunctionModel.nf_name == self.nf_name).one_or_none()
+ db.session.remove()
return {'nf_name': self.nf_name,
+ 'ip_address': nf.ip_address,
'nf_sub_status': self.nf_sub_status,
'model_invariant_id': nf.model_invariant_id,
'model_version_id': nf.model_version_id,
diff --git a/components/pm-subscription-handler/pmsh_service/mod/exit_handler.py b/components/pm-subscription-handler/pmsh_service/mod/exit_handler.py
index 12932966..fbb8b241 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/exit_handler.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/exit_handler.py
@@ -16,7 +16,7 @@
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=====================================================
-from mod import logger
+from mod import logger, db
from mod.subscription import AdministrativeState
@@ -39,14 +39,21 @@ class ExitHandler:
def __call__(self, sig_num, frame):
logger.info('Graceful shutdown of PMSH initiated.')
logger.debug(f'ExitHandler was called with signal number: {sig_num}.')
+ for thread in self.periodic_tasks:
+ if thread.name == 'app_conf_thread':
+ logger.info(f'Cancelling thread {thread.name}')
+ thread.cancel()
current_sub = self.app_conf.subscription
if current_sub.administrativeState == AdministrativeState.UNLOCKED.value:
try:
current_sub.deactivate_subscription(self.subscription_handler.mr_pub, self.app_conf)
- current_sub.update_subscription_status()
- for thread in self.periodic_tasks:
- logger.debug(f'Cancelling periodic task with thread name: {thread.name}.')
- thread.cancel()
except Exception as e:
logger.error(f'Failed to shut down PMSH application: {e}', exc_info=True)
+ for thread in self.periodic_tasks:
+ logger.info(f'Cancelling thread {thread.name}')
+ thread.cancel()
+ logger.info('Closing all DB connections')
+ db.session.bind.dispose()
+ db.session.close()
+ db.engine.dispose()
ExitHandler.shutdown_signal_received = True
diff --git a/components/pm-subscription-handler/pmsh_service/mod/network_function.py b/components/pm-subscription-handler/pmsh_service/mod/network_function.py
index 798da00b..3f383885 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/network_function.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/network_function.py
@@ -27,6 +27,7 @@ class NetworkFunction:
def __init__(self, sdnc_model_name=None, sdnc_model_version=None, **kwargs):
""" Object representation of the NetworkFunction. """
self.nf_name = kwargs.get('nf_name')
+ self.ip_address = kwargs.get('ip_address')
self.model_invariant_id = kwargs.get('model_invariant_id')
self.model_version_id = kwargs.get('model_version_id')
self.sdnc_model_name = sdnc_model_name
@@ -34,11 +35,12 @@ class NetworkFunction:
@classmethod
def nf_def(cls):
- return cls(nf_name=None, model_invariant_id=None, model_version_id=None,
+ return cls(nf_name=None, ip_address=None, model_invariant_id=None, model_version_id=None,
sdnc_model_name=None, sdnc_model_version=None)
def __str__(self):
return f'nf-name: {self.nf_name}, ' \
+ f'ipaddress-v4-oam: {self.ip_address}, ' \
f'model-invariant-id: {self.model_invariant_id}, ' \
f'model-version-id: {self.model_version_id}, ' \
f'sdnc-model-name: {self.sdnc_model_name}, ' \
@@ -47,13 +49,14 @@ class NetworkFunction:
def __eq__(self, other):
return \
self.nf_name == other.nf_name and \
+ self.ip_address == other.ip_address and \
self.model_invariant_id == other.model_invariant_id and \
self.model_version_id == other.model_version_id and \
self.sdnc_model_name == other.sdnc_model_name and \
self.sdnc_model_version == other.sdnc_model_version
def __hash__(self):
- return hash((self.nf_name, self.model_invariant_id,
+ return hash((self.nf_name, self.ip_address, self.model_invariant_id,
self.model_version_id, self.sdnc_model_name, self.sdnc_model_version))
def create(self):
@@ -63,6 +66,7 @@ class NetworkFunction:
if existing_nf is None:
new_nf = NetworkFunctionModel(nf_name=self.nf_name,
+ ip_address=self.ip_address,
model_invariant_id=self.model_invariant_id,
model_version_id=self.model_version_id,
sdnc_model_name=self.sdnc_model_name,
@@ -90,7 +94,8 @@ class NetworkFunction:
f'sdnc-model data associated in AAI: {e}', exc_info=True)
return not params_set
except Exception as e:
- logger.error(f'Failed to get sdnc-model info for XNFs from AAI: {e}', exc_info=True)
+ logger.error(f'Failed to get sdnc-model info for XNF {self.nf_name} from AAI: {e}',
+ exc_info=True)
return not params_set
@staticmethod
@@ -101,8 +106,10 @@ class NetworkFunction:
Returns:
NetworkFunctionModel object else None
"""
- return NetworkFunctionModel.query.filter(
+ nf_model = NetworkFunctionModel.query.filter(
NetworkFunctionModel.nf_name == nf_name).one_or_none()
+ db.session.remove()
+ return nf_model
@staticmethod
def get_all():
@@ -110,7 +117,10 @@ class NetworkFunction:
Returns:
list: NetworkFunctionModel objects else empty
"""
- return NetworkFunctionModel.query.all()
+
+ nf_models = NetworkFunctionModel.query.all()
+ db.session.remove()
+ return nf_models
@staticmethod
def delete(**kwargs):
@@ -122,6 +132,7 @@ class NetworkFunction:
if nf:
db.session.delete(nf)
db.session.commit()
+ db.session.remove()
class NetworkFunctionFilter:
diff --git a/components/pm-subscription-handler/pmsh_service/mod/subscription.py b/components/pm-subscription-handler/pmsh_service/mod/subscription.py
index 21e2399d..34753e84 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/subscription.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/subscription.py
@@ -79,6 +79,8 @@ class Subscription:
except Exception as e:
logger.error(f'Failed to create subscription {self.subscriptionName} in the DB: {e}',
exc_info=True)
+ finally:
+ db.session.remove()
def update_subscription_status(self):
""" Updates the status of subscription in subscription table """
@@ -92,6 +94,8 @@ class Subscription:
except Exception as e:
logger.error(f'Failed to update status of subscription: {self.subscriptionName}: {e}',
exc_info=True)
+ finally:
+ db.session.remove()
def prepare_subscription_event(self, nf, app_conf):
"""Prepare the sub event for publishing
@@ -105,7 +109,9 @@ class Subscription:
"""
try:
clean_sub = {k: v for k, v in self.__dict__.items() if k != 'nfFilter'}
- sub_event = {'nfName': nf.nf_name, 'blueprintName': nf.sdnc_model_name,
+ sub_event = {'nfName': nf.nf_name,
+ 'ipv4Address': nf.ip_address,
+ 'blueprintName': nf.sdnc_model_name,
'blueprintVersion': nf.sdnc_model_version,
'policyName': app_conf.operational_policy_name,
'changeType': 'DELETE'
@@ -149,8 +155,9 @@ class Subscription:
Returns:
SubscriptionModel object else None
"""
- return SubscriptionModel.query.filter(
+ sub_model = SubscriptionModel.query.filter(
SubscriptionModel.subscription_name == self.subscriptionName).one_or_none()
+ return sub_model
def get_local_sub_admin_state(self):
""" Retrieves the subscription admin state
@@ -160,6 +167,7 @@ class Subscription:
"""
sub_model = SubscriptionModel.query.filter(
SubscriptionModel.subscription_name == self.subscriptionName).one_or_none()
+ db.session.remove()
return sub_model.status
@staticmethod
@@ -169,14 +177,17 @@ class Subscription:
Returns:
list(SubscriptionModel): Subscriptions list else empty
"""
- return SubscriptionModel.query.all()
+
+ sub_models = SubscriptionModel.query.all()
+ db.session.remove()
+ return sub_models
def activate_subscription(self, nfs, mr_pub, app_conf):
logger.info(f'Activate subscription initiated for {self.subscriptionName}.')
try:
existing_nfs = self.get_network_functions()
sub_model = self.get()
- for nf in set(nfs + existing_nfs):
+ for nf in [new_nf for new_nf in nfs if new_nf not in existing_nfs]:
logger.info(f'Publishing event to activate '
f'Sub: {self.subscriptionName} for the nf: {nf.nf_name}')
mr_pub.publish_subscription_event_data(self, nf, app_conf)
@@ -209,6 +220,7 @@ class Subscription:
list(NfSubRelationalModel): NetworkFunctions per Subscription list else empty
"""
nf_per_subscriptions = NfSubRelationalModel.query.all()
+ db.session.remove()
return nf_per_subscriptions
@staticmethod
@@ -238,5 +250,5 @@ class Subscription:
nf_model_object = NetworkFunctionModel.query.filter(
NetworkFunctionModel.nf_name == nf_sub_entry.nf_name).one_or_none()
nfs.append(nf_model_object.to_nf())
-
+ db.session.remove()
return nfs
diff --git a/components/pm-subscription-handler/pmsh_service/pmsh_service_main.py b/components/pm-subscription-handler/pmsh_service/pmsh_service_main.py
index 6b6b9baa..f92fdc91 100755
--- a/components/pm-subscription-handler/pmsh_service/pmsh_service_main.py
+++ b/components/pm-subscription-handler/pmsh_service/pmsh_service_main.py
@@ -41,18 +41,22 @@ def main():
sys.exit(e)
app_conf_thread = PeriodicTask(10, app_conf.refresh_config)
+ app_conf_thread.name = 'app_conf_thread'
app_conf_thread.start()
policy_response_handler = PolicyResponseHandler(policy_mr_sub, app_conf, app)
policy_response_handler_thread = PeriodicTask(25, policy_response_handler.poll_policy_topic)
+ policy_response_handler_thread.name = 'policy_event_thread'
aai_event_thread = PeriodicTask(20, process_aai_events,
args=(aai_event_mr_sub, policy_mr_pub, app, app_conf))
+ aai_event_thread.name = 'aai_event_thread'
subscription_handler = SubscriptionHandler(policy_mr_pub, app, app_conf, aai_event_thread,
policy_response_handler_thread)
subscription_handler_thread = PeriodicTask(30, subscription_handler.execute)
+ subscription_handler_thread.name = 'sub_handler_thread'
subscription_handler_thread.start()
periodic_tasks = [app_conf_thread, aai_event_thread, subscription_handler_thread,
diff --git a/components/pm-subscription-handler/tests/data/pm_subscription_event.json b/components/pm-subscription-handler/tests/data/pm_subscription_event.json
index 9416ec28..cd547d9d 100755
--- a/components/pm-subscription-handler/tests/data/pm_subscription_event.json
+++ b/components/pm-subscription-handler/tests/data/pm_subscription_event.json
@@ -5,6 +5,7 @@
"policyName":"pmsh-operational-policy",
"changeType":"CREATE",
"closedLoopControlName":"pmsh-control-loop",
+ "ipv4Address": "1.2.3.4",
"subscription":{
"subscriptionName":"ExtraPM-All-gNB-R2B",
"administrativeState":"UNLOCKED",
diff --git a/components/pm-subscription-handler/tests/test_aai_service.py b/components/pm-subscription-handler/tests/test_aai_service.py
index 7a3b846d..27694851 100644
--- a/components/pm-subscription-handler/tests/test_aai_service.py
+++ b/components/pm-subscription-handler/tests/test_aai_service.py
@@ -72,21 +72,21 @@ class AaiClientTestCase(BaseClassSetup):
@responses.activate
def test_aai_client_get_all_aai_xnf_data_not_found(self):
responses.add(responses.PUT,
- 'https://1.2.3.4:8443/aai/v20/query?format=simple&nodesOnly=true',
+ 'https://1.2.3.4:8443/aai/v21/query?format=simple&nodesOnly=true',
json={'error': 'not found'}, status=404)
self.assertIsNone(aai_client._get_all_aai_nf_data(self.app_conf))
@responses.activate
def test_aai_client_get_all_aai_xnf_data_success(self):
responses.add(responses.PUT,
- 'https://aai:8443/aai/v20/query?format=simple&nodesOnly=true',
+ 'https://aai:8443/aai/v21/query?format=simple&nodesOnly=true',
json={'dummy_data': 'blah_blah'}, status=200)
self.assertIsNotNone(aai_client._get_all_aai_nf_data(self.app_conf))
@responses.activate
def test_aai_client_get_sdnc_params_success(self):
responses.add(responses.GET,
- 'https://aai:8443/aai/v20/service-design-and-creation/models/model/'
+ 'https://aai:8443/aai/v21/service-design-and-creation/models/model/'
'6fb9f466-7a79-4109-a2a3-72b340aca53d/model-vers/model-ver/'
'6d25b637-8bca-47e2-af1a-61258424183d',
json=json.loads(self.good_model_info), status=200)
@@ -98,7 +98,7 @@ class AaiClientTestCase(BaseClassSetup):
@responses.activate
def test_aai_client_get_sdnc_params_fail(self):
responses.add(responses.GET,
- 'https://aai:8443/aai/v20/service-design-and-creation/models/model/'
+ 'https://aai:8443/aai/v21/service-design-and-creation/models/model/'
'9fb9f466-7a79-4109-a2a3-72b340aca53d/model-vers/model-ver/'
'b7469cc5-be51-41cc-b37f-361537656771', status=404)
with self.assertRaises(HTTPError):
@@ -111,4 +111,4 @@ class AaiClientTestCase(BaseClassSetup):
aai_client._get_aai_service_url()
def test_aai_client_get_aai_service_url_success(self):
- self.assertEqual('https://aai:8443/aai/v20', aai_client._get_aai_service_url())
+ self.assertEqual('https://aai:8443/aai/v21', aai_client._get_aai_service_url())
diff --git a/components/pm-subscription-handler/tests/test_network_function.py b/components/pm-subscription-handler/tests/test_network_function.py
index ea5d2c7e..c930c41d 100755
--- a/components/pm-subscription-handler/tests/test_network_function.py
+++ b/components/pm-subscription-handler/tests/test_network_function.py
@@ -33,10 +33,12 @@ class NetworkFunctionTests(BaseClassSetup):
super().setUp()
self.nf_1 = NetworkFunction(sdnc_model_name='blah', sdnc_model_version=1.0,
**{'nf_name': 'pnf_1',
+ 'ip_address': '1.2.3.4',
'model_invariant_id': 'some_id',
'model_version_id': 'some_other_id'})
self.nf_2 = NetworkFunction(sdnc_model_name='blah', sdnc_model_version=2.0,
**{'nf_name': 'pnf_2',
+ 'ip_address': '1.2.3.4',
'model_invariant_id': 'some_id',
'model_version_id': 'some_other_id'})
with open(os.path.join(os.path.dirname(__file__), 'data/aai_model_info.json'), 'r') as data:
diff --git a/components/pm-subscription-handler/tests/test_subscription.py b/components/pm-subscription-handler/tests/test_subscription.py
index 9bfe825f..62a9e16e 100755
--- a/components/pm-subscription-handler/tests/test_subscription.py
+++ b/components/pm-subscription-handler/tests/test_subscription.py
@@ -47,6 +47,7 @@ class SubscriptionTest(BaseClassSetup):
mock_session_get.return_value.text = self.aai_model_data
self.mock_mr_sub = Mock()
self.mock_mr_pub = Mock()
+ self.app_conf.subscription.create()
self.xnfs = aai_client.get_pmsh_nfs_from_aai(self.app_conf)
self.sub_model = self.app_conf.subscription.get()
@@ -65,12 +66,10 @@ class SubscriptionTest(BaseClassSetup):
def test_get_subscription(self):
sub_name = 'ExtraPM-All-gNB-R2B'
- self.app_conf.subscription.create()
new_sub = self.app_conf.subscription.get()
self.assertEqual(sub_name, new_sub.subscription_name)
def test_get_nf_names_per_sub(self):
- self.app_conf.subscription.create()
self.app_conf.subscription.add_network_function_to_subscription(list(self.xnfs)[0],
self.sub_model)
self.app_conf.subscription.add_network_function_to_subscription(list(self.xnfs)[1],
@@ -82,16 +81,6 @@ class SubscriptionTest(BaseClassSetup):
self.assertEqual(sub1, same_sub1)
self.assertEqual(1, len(self.app_conf.subscription.get_all()))
- def test_add_network_functions_per_subscription(self):
- for nf in self.xnfs:
- self.app_conf.subscription.add_network_function_to_subscription(nf, self.sub_model)
- nfs_for_sub_1 = Subscription.get_all_nfs_subscription_relations()
- self.assertEqual(3, len(nfs_for_sub_1))
- new_nf = NetworkFunction(nf_name='vnf_3', orchestration_status='Active')
- self.app_conf.subscription.add_network_function_to_subscription(new_nf, self.sub_model)
- nf_subs = Subscription.get_all_nfs_subscription_relations()
- self.assertEqual(4, len(nf_subs))
-
def test_add_duplicate_network_functions_per_subscription(self):
self.app_conf.subscription.add_network_function_to_subscription(list(self.xnfs)[0],
self.sub_model)
@@ -103,7 +92,6 @@ class SubscriptionTest(BaseClassSetup):
self.assertEqual(1, len(nf_subs))
def test_update_subscription_status(self):
- self.app_conf.subscription.create()
self.app_conf.subscription.administrativeState = 'new_status'
self.app_conf.subscription.update_subscription_status()
sub = self.app_conf.subscription.get()
@@ -152,6 +140,7 @@ class SubscriptionTest(BaseClassSetup):
'data/pm_subscription_event.json'), 'r') as data:
expected_sub_event = json.load(data)
nf = NetworkFunction(nf_name='pnf_1',
+ ip_address='1.2.3.4',
model_invariant_id='some-id',
model_version_id='some-id')
nf.sdnc_model_name = 'some-name'