summaryrefslogtreecommitdiffstats
path: root/components/pm-subscription-handler/pmsh_service
diff options
context:
space:
mode:
authorefiacor <fiachra.corcoran@est.tech>2020-09-08 16:26:50 +0100
committerefiacor <fiachra.corcoran@est.tech>2020-09-10 13:00:50 +0100
commit0080fa4309a40599b7d239b53bab9a74182ae500 (patch)
tree17af572ecb3e03a3be7115d41e3097985773ed5a /components/pm-subscription-handler/pmsh_service
parent2e3c407d0fcf8c73c5fd6714d6013e37930c92cb (diff)
[PMSSH] Add sdnc model info to event publish1.1.1-pmsh
Signed-off-by: efiacor <fiachra.corcoran@est.tech> Change-Id: I89e25e99a2d541a29cf4a8dde986fab5b1812c9e Issue-ID: DCAEGEN2-2405
Diffstat (limited to 'components/pm-subscription-handler/pmsh_service')
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/aai_client.py114
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/aai_event_handler.py36
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/api/db_models.py35
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/network_function.py68
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py10
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/subscription.py77
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py4
7 files changed, 193 insertions, 151 deletions
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 c8dea9f7..73bf8d4c 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/aai_client.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/aai_client.py
@@ -21,9 +21,9 @@ from os import environ
import requests
from requests.auth import HTTPBasicAuth
+import mod.network_function
+import mod.pmsh_utils
from mod import logger
-from mod.network_function import NetworkFunction
-from mod.pmsh_utils import mdc_handler
def get_pmsh_nfs_from_aai(app_conf):
@@ -34,21 +34,20 @@ def get_pmsh_nfs_from_aai(app_conf):
app_conf (AppConfig): the AppConfig object.
Returns:
- set(NetworkFunctions): set of NetworkFunctions.
+ NetworkFunctions (list): list of NetworkFunctions.
Raises:
RuntimeError: if AAI Network Function data cannot be retrieved.
"""
aai_nf_data = _get_all_aai_nf_data(app_conf)
if aai_nf_data:
- nfs = _filter_nf_data(aai_nf_data, app_conf.nf_filter)
+ nfs = _filter_nf_data(aai_nf_data, app_conf)
else:
raise RuntimeError('Failed to get data from AAI')
return nfs
-@mdc_handler
-def _get_all_aai_nf_data(app_conf, **kwargs):
+def _get_all_aai_nf_data(app_conf):
"""
Return queried nf data from the AAI service.
@@ -61,24 +60,19 @@ def _get_all_aai_nf_data(app_conf, **kwargs):
nf_data = None
try:
session = requests.Session()
- aai_endpoint = f'{_get_aai_service_url()}{"/aai/v19/query"}'
+ aai_named_query_endpoint = f'{_get_aai_service_url()}{"/query"}'
logger.info('Fetching XNFs from AAI.')
- headers = {'accept': 'application/json',
- 'content-type': 'application/json',
- 'x-fromappid': 'dcae-pmsh',
- 'x-transactionid': kwargs['request_id'],
- 'InvocationID': kwargs['invocation_id'],
- 'RequestID': kwargs['request_id']}
- json_data = """
- {'start':
- ['network/pnfs',
- 'network/generic-vnfs']
- }"""
+ headers = _get_aai_request_headers()
+ data = """
+ {'start':
+ ['network/pnfs',
+ 'network/generic-vnfs']
+ }"""
params = {'format': 'simple', 'nodesOnly': 'true'}
- response = session.put(aai_endpoint, headers=headers,
+ response = session.put(aai_named_query_endpoint, headers=headers,
auth=HTTPBasicAuth(app_conf.aaf_creds.get('aaf_id'),
app_conf.aaf_creds.get('aaf_pass')),
- data=json_data, params=params,
+ data=data, params=params,
verify=(app_conf.ca_cert_path if app_conf.enable_tls else False),
cert=(app_conf.cert_params if app_conf.enable_tls else None))
response.raise_for_status()
@@ -103,39 +97,89 @@ def _get_aai_service_url():
"""
try:
aai_ssl_port = environ['AAI_SERVICE_PORT']
- return f'https://aai:{aai_ssl_port}'
+ return f'https://aai:{aai_ssl_port}/aai/v20'
except KeyError as e:
logger.error(f'Failed to get AAI env var: {e}', exc_info=True)
raise
-def _filter_nf_data(nf_data, nf_filter):
+@mod.pmsh_utils.mdc_handler
+def _get_aai_request_headers(**kwargs):
+ return {'accept': 'application/json',
+ 'content-type': 'application/json',
+ 'x-fromappid': 'dcae-pmsh',
+ 'x-transactionid': kwargs['request_id'],
+ 'InvocationID': kwargs['invocation_id'],
+ 'RequestID': kwargs['request_id']}
+
+
+def _filter_nf_data(nf_data, app_conf):
"""
Returns a list of filtered NetworkFunctions using the nf_filter.
Args:
- nf_data(dict): the nf json data from AAI.
- nf_filter(NetworkFunctionFilter): the NetworkFunctionFilter to be applied.
+ nf_data (dict): the nf json data from AAI.
+ app_conf (AppConfig): the AppConfig object.
Returns:
- set(NetworkFunctions): a set of filtered NetworkFunctions.
+ NetworkFunction (list): a list of filtered NetworkFunction Objects.
Raises:
KeyError: if AAI data cannot be parsed.
"""
- nf_set = set()
+ nf_list = []
try:
for nf in nf_data['results']:
+ if nf['properties'].get('orchestration-status') != 'Active':
+ continue
name_identifier = 'pnf-name' if nf['node-type'] == 'pnf' else 'vnf-name'
- orchestration_status = nf['properties'].get('orchestration-status')
- model_invariant_id = nf['properties'].get('model-invariant-id')
- model_version_id = nf['properties'].get('model-version-id')
- if nf_filter.is_nf_in_filter(nf['properties'].get(name_identifier),
- model_invariant_id, model_version_id, orchestration_status):
- nf_set.add(NetworkFunction(
- nf_name=nf['properties'].get(name_identifier),
- orchestration_status=orchestration_status))
+ new_nf = mod.network_function.NetworkFunction(
+ nf_name=nf['properties'].get(name_identifier),
+ 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):
+ continue
+ if app_conf.nf_filter.is_nf_in_filter(new_nf):
+ nf_list.append(new_nf)
except KeyError as e:
logger.error(f'Failed to parse AAI data: {e}', exc_info=True)
raise
- return nf_set
+ return nf_list
+
+
+def get_aai_model_data(app_conf, model_invariant_id, model_version_id, nf_name):
+ """
+ Get the sdnc_model info for the xNF from AAI.
+
+ Args:
+ model_invariant_id (str): the AAI model-invariant-id
+ model_version_id (str): the AAI model-version-id
+ app_conf (AppConfig): the AppConfig object.
+ nf_name (str): The xNF name.
+
+ Returns:
+ json (dict): the sdnc_model json object.
+
+ Raises:
+ Exception: if AAI model data cannot be retrieved.
+ """
+ try:
+ session = requests.Session()
+ aai_model_ver_endpoint = \
+ f'{_get_aai_service_url()}/service-design-and-creation/models/model/' \
+ f'{model_invariant_id}/model-vers/model-ver/{model_version_id}'
+
+ logger.info(f'Fetching sdnc-model info for xNF: {nf_name} from AAI.')
+ headers = _get_aai_request_headers()
+ response = session.get(aai_model_ver_endpoint, headers=headers,
+ auth=HTTPBasicAuth(app_conf.aaf_creds.get('aaf_id'),
+ app_conf.aaf_creds.get('aaf_pass')),
+ verify=(app_conf.ca_cert_path if app_conf.enable_tls else False),
+ cert=(app_conf.cert_params if app_conf.enable_tls else None))
+ response.raise_for_status()
+ if response.ok:
+ data = json.loads(response.text)
+ logger.debug(f'Successfully fetched sdnc-model info from AAI: {data}')
+ return data
+ except Exception:
+ raise
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 92369322..61b42b52 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
@@ -58,28 +58,26 @@ def process_aai_events(mr_sub, mr_pub, app, app_conf):
entity_type = entry['event-header']['entity-type']
xnf_name = aai_entity['pnf-name'] if entity_type == XNFType.PNF.value \
else aai_entity['vnf-name']
- new_status = aai_entity['orchestration-status']
- model_invariant_id = aai_entity['model-invariant-id']
- model_version_id = aai_entity['model-version-id']
-
- if app_conf.nf_filter.is_nf_in_filter(xnf_name, model_invariant_id, model_version_id, new_status):
- _process_event(action, new_status, xnf_name, mr_pub, app_conf)
+ if aai_entity['orchestration-status'] != 'Active':
+ logger.info(f'Skipping XNF {xnf_name} as its orchestration-status '
+ f'is not "Active"')
+ continue
+ nf = NetworkFunction(nf_name=xnf_name,
+ model_invariant_id=aai_entity['model-invariant-id'],
+ model_version_id=aai_entity['model-version-id'])
+ if not nf.set_sdnc_params(app_conf):
+ continue
+ if app_conf.nf_filter.is_nf_in_filter(nf):
+ _process_event(action, nf, mr_pub, app_conf)
except Exception as e:
logger.error(f'Failed to process AAI event: {e}', exc_info=True)
-def _process_event(action, new_status, xnf_name, mr_pub, app_conf):
+def _process_event(action, nf, mr_pub, app_conf):
if action == AAIEvent.UPDATE.value:
- logger.info(f'Update event found for network function {xnf_name}')
- local_xnf = NetworkFunction.get(xnf_name)
-
- if local_xnf is None:
- app_conf.subscription.activate_subscription([NetworkFunction(
- nf_name=xnf_name, orchestration_status=new_status)], mr_pub, app_conf)
- else:
- logger.debug(f"Update Event for network function {xnf_name} will not be processed "
- f" as it's state is set to {local_xnf.orchestration_status}.")
+ logger.info(f'Update event found for network function {nf.nf_name}')
+ app_conf.subscription.activate_subscription([nf], mr_pub, app_conf)
elif action == AAIEvent.DELETE.value:
- logger.info(f'Delete event found for network function {xnf_name}')
- NetworkFunction.delete(nf_name=xnf_name)
- logger.info(f'{xnf_name} successfully deleted.')
+ logger.info(f'Delete event found for network function {nf.nf_name}')
+ NetworkFunction.delete(nf_name=nf.nf_name)
+ logger.info(f'{nf.nf_name} successfully deleted.')
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 1d6f72b3..ff172d1c 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
@@ -56,19 +56,34 @@ class NetworkFunctionModel(db.Model):
__tablename__ = 'network_functions'
id = Column(Integer, primary_key=True, autoincrement=True)
nf_name = Column(String(100), unique=True)
- orchestration_status = Column(String(100))
+ model_invariant_id = Column(String(100))
+ model_version_id = Column(String(100))
+ sdnc_model_name = Column(String(100))
+ sdnc_model_version = Column(String(100))
subscriptions = relationship(
'NfSubRelationalModel',
cascade='all, delete-orphan',
backref='nf')
- def __init__(self, nf_name, orchestration_status):
+ def __init__(self, nf_name, model_invariant_id, model_version_id, sdnc_model_name=None,
+ sdnc_model_version=None):
self.nf_name = nf_name
- self.orchestration_status = orchestration_status
+ self.model_invariant_id = model_invariant_id
+ self.model_version_id = model_version_id
+ self.sdnc_model_name = sdnc_model_name
+ self.sdnc_model_version = sdnc_model_version
def __repr__(self):
- return f'nf_name: {self.nf_name}, orchestration_status: {self.orchestration_status}'
+ return str(self.to_nf())
+
+ def to_nf(self):
+ from mod.network_function import NetworkFunction
+ return NetworkFunction(**{'nf_name': self.nf_name,
+ 'model_invariant_id': self.model_invariant_id,
+ 'model_version_id': self.model_version_id,
+ 'sdnc_model_name': self.sdnc_model_name,
+ 'sdnc_model_version': self.sdnc_model_version})
class NfSubRelationalModel(db.Model):
@@ -101,7 +116,11 @@ class NfSubRelationalModel(db.Model):
'nf_sub_status': self.nf_sub_status}
def serialize_nf(self):
- nf_orch_status = NetworkFunctionModel.query.filter(
- NetworkFunctionModel.nf_name == self.nf_name).one_or_none().orchestration_status
- return {'nf_name': self.nf_name, 'orchestration_status': nf_orch_status,
- 'nf_sub_status': self.nf_sub_status}
+ nf = NetworkFunctionModel.query.filter(
+ NetworkFunctionModel.nf_name == self.nf_name).one_or_none()
+ return {'nf_name': self.nf_name,
+ 'nf_sub_status': self.nf_sub_status,
+ 'model_invariant_id': nf.model_invariant_id,
+ 'model_version_id': nf.model_version_id,
+ 'sdnc_model_name': nf.sdnc_model_name,
+ 'sdnc_model_version': nf.sdnc_model_version}
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 62cd546f..fd940385 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/network_function.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/network_function.py
@@ -18,6 +18,7 @@
import re
+import mod.aai_client
from mod import logger, db
from mod.api.db_models import NetworkFunctionModel
@@ -26,21 +27,34 @@ class NetworkFunction:
def __init__(self, **kwargs):
""" Object representation of the NetworkFunction. """
self.nf_name = kwargs.get('nf_name')
- self.orchestration_status = kwargs.get('orchestration_status')
+ self.model_invariant_id = kwargs.get('model_invariant_id')
+ self.model_version_id = kwargs.get('model_version_id')
+ self.sdnc_model_name = None
+ self.sdnc_model_version = None
@classmethod
def nf_def(cls):
- return cls(nf_name=None, orchestration_status=None)
+ return cls(nf_name=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}, orchestration-status: {self.orchestration_status}'
+ return f'nf-name: {self.nf_name}, ' \
+ f'model-invariant-id: {self.model_invariant_id}, ' \
+ f'model-version-id: {self.model_version_id}, ' \
+ f'sdnc-model-name: {self.sdnc_model_name}, ' \
+ f'sdnc-model-version: {self.sdnc_model_version}'
def __eq__(self, other):
- return self.nf_name == other.nf_name and \
- self.orchestration_status == other.orchestration_status
+ return \
+ self.nf_name == other.nf_name 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.orchestration_status))
+ return hash((self.nf_name, self.model_invariant_id,
+ self.model_version_id, self.sdnc_model_name, self.sdnc_model_version))
def create(self):
""" Creates a NetworkFunction database entry """
@@ -49,7 +63,10 @@ class NetworkFunction:
if existing_nf is None:
new_nf = NetworkFunctionModel(nf_name=self.nf_name,
- orchestration_status=self.orchestration_status)
+ model_invariant_id=self.model_invariant_id,
+ model_version_id=self.model_version_id,
+ sdnc_model_name=self.sdnc_model_name,
+ sdnc_model_version=self.sdnc_model_version)
db.session.add(new_nf)
db.session.commit()
logger.info(f'Network Function {new_nf.nf_name} successfully created.')
@@ -59,6 +76,23 @@ class NetworkFunction:
f' returning this network function..')
return existing_nf
+ def set_sdnc_params(self, app_conf):
+ params_set = True
+ try:
+ sdnc_model_data = mod.aai_client.get_aai_model_data(app_conf, self.model_invariant_id,
+ self.model_version_id, self.nf_name)
+ try:
+ self.sdnc_model_name = sdnc_model_data['sdnc-model-name']
+ self.sdnc_model_version = sdnc_model_data['sdnc-model-version']
+ return params_set
+ except KeyError as e:
+ logger.info(f'Skipping NF {self.nf_name} as there is no '
+ 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)
+ return not params_set
+
@staticmethod
def get(nf_name):
""" Retrieves a network function
@@ -90,33 +124,27 @@ class NetworkFunction:
db.session.commit()
-
class NetworkFunctionFilter:
def __init__(self, **kwargs):
self.nf_names = kwargs.get('nfNames')
- self.model_invariant_ids = kwargs.get('modelInvariantUUIDs')
+ self.model_invariant_ids = kwargs.get('modelInvariantIDs')
self.model_version_ids = kwargs.get('modelVersionIDs')
self.regex_matcher = re.compile('|'.join(raw_regex for raw_regex in self.nf_names))
- def is_nf_in_filter(self, nf_name, model_invariant_id, model_version_id, orchestration_status):
- """Match the nf name against regex values in Subscription.nfFilter.nfNames
+ def is_nf_in_filter(self, nf):
+ """Match the nf fields against values in Subscription.nfFilter
Args:
- nf_name (str): the AAI nf name.
- invariant_uuid (str): the AAI model-invariant-id
- uuid (str): the AAI model-version-id
- orchestration_status (str): orchestration status of the nf
+ nf (NetworkFunction): The NF to be filtered.
Returns:
bool: True if matched, else False.
"""
match = True
- if orchestration_status != 'Active':
- match = False
- if self.nf_names and self.regex_matcher.search(nf_name) is None:
+ if self.nf_names and self.regex_matcher.search(nf.nf_name) is None:
match = False
- if self.model_invariant_ids and not model_invariant_id in self.model_invariant_ids:
+ if self.model_invariant_ids and nf.model_invariant_id not in self.model_invariant_ids:
match = False
- if self.model_version_ids and not model_version_id in self.model_version_ids:
+ if self.model_version_ids and nf.model_version_id not in self.model_version_ids:
match = False
return match
diff --git a/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py b/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
index fd24fca9..24eade98 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
@@ -25,8 +25,8 @@ from onaplogging.mdcContext import MDC
from requests.auth import HTTPBasicAuth
from tenacity import wait_fixed, stop_after_attempt, retry, retry_if_exception_type
+import mod.network_function
from mod import logger
-from mod.network_function import NetworkFunctionFilter
from mod.subscription import Subscription
@@ -77,7 +77,7 @@ class AppConfig:
self.operational_policy_name = conf['config'].get('operational_policy_name')
self.control_loop_name = conf['config'].get('control_loop_name')
self.subscription = Subscription(**conf['policy']['subscription'])
- self.nf_filter = NetworkFunctionFilter(**self.subscription.nfFilter)
+ self.nf_filter = mod.network_function.NetworkFunctionFilter(**self.subscription.nfFilter)
def __new__(cls, *args, **kwargs):
if AppConfig.INSTANCE is None:
@@ -223,17 +223,17 @@ class _MrPub(_DmaapMrClient):
except Exception as e:
raise e
- def publish_subscription_event_data(self, subscription, xnf_name, app_conf):
+ def publish_subscription_event_data(self, subscription, nf, app_conf):
"""
Update the Subscription dict with xnf and policy name then publish to DMaaP MR topic.
Args:
subscription (Subscription): the `Subscription` <Subscription> object.
- xnf_name (str): the xnf to include in the event.
+ nf (NetworkFunction): the NetworkFunction to include in the event.
app_conf (AppConfig): the application configuration.
"""
try:
- subscription_event = subscription.prepare_subscription_event(xnf_name, app_conf)
+ subscription_event = subscription.prepare_subscription_event(nf, app_conf)
self.publish_to_topic(subscription_event)
except Exception as e:
logger.error(f'Failed to publish to topic {self.topic_url}: {e}', exc_info=True)
diff --git a/components/pm-subscription-handler/pmsh_service/mod/subscription.py b/components/pm-subscription-handler/pmsh_service/mod/subscription.py
index 97bfc401..21e2399d 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/subscription.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/subscription.py
@@ -19,7 +19,6 @@ from enum import Enum
from mod import db, logger
from mod.api.db_models import SubscriptionModel, NfSubRelationalModel, NetworkFunctionModel
-from mod.network_function import NetworkFunction
class SubNfState(Enum):
@@ -94,30 +93,11 @@ class Subscription:
logger.error(f'Failed to update status of subscription: {self.subscriptionName}: {e}',
exc_info=True)
- def delete_subscription(self):
- """ Deletes a subscription and all its association from the database. A network function
- that is only associated with the subscription being removed will also be deleted."""
- try:
- subscription = SubscriptionModel.query.filter(
- SubscriptionModel.subscription_name == self.subscriptionName).one_or_none()
- if subscription:
- for nf_relationship in subscription.nfs:
- other_nf_relationship = NfSubRelationalModel.query.filter(
- NfSubRelationalModel.subscription_name != self.subscriptionName,
- NfSubRelationalModel.nf_name == nf_relationship.nf_name).one_or_none()
- if not other_nf_relationship:
- db.session.delete(nf_relationship.nf)
- db.session.delete(subscription)
- db.session.commit()
- except Exception as e:
- logger.error(f'Failed to delete subscription: {self.subscriptionName} '
- f'and it\'s relations from the DB: {e}', exc_info=True)
-
- def prepare_subscription_event(self, xnf_name, app_conf):
+ def prepare_subscription_event(self, nf, app_conf):
"""Prepare the sub event for publishing
Args:
- xnf_name: the AAI xnf name.
+ nf (NetworkFunction): the AAI nf.
app_conf (AppConfig): the application configuration.
Returns:
@@ -125,14 +105,16 @@ class Subscription:
"""
try:
clean_sub = {k: v for k, v in self.__dict__.items() if k != 'nfFilter'}
- sub_event = {'nfName': xnf_name, 'policyName': app_conf.operational_policy_name,
+ sub_event = {'nfName': nf.nf_name, 'blueprintName': nf.sdnc_model_name,
+ 'blueprintVersion': nf.sdnc_model_version,
+ 'policyName': app_conf.operational_policy_name,
'changeType': 'DELETE'
if self.administrativeState == AdministrativeState.LOCKED.value
else 'CREATE', 'closedLoopControlName': app_conf.control_loop_name,
'subscription': clean_sub}
return sub_event
except Exception as e:
- logger.error(f'Failed to prep Sub event for xNF {xnf_name}: {e}', exc_info=True)
+ logger.error(f'Failed to prep Sub event for xNF {nf.nf_name}: {e}', exc_info=True)
raise
def add_network_function_to_subscription(self, nf, sub_model):
@@ -159,7 +141,7 @@ class Subscription:
logger.error(f'Failed to add nf {nf.nf_name} to subscription '
f'{self.subscriptionName}: {e}', exc_info=True)
logger.debug(f'Subscription {self.subscriptionName} now contains these XNFs:'
- f'{Subscription.get_nf_names_per_sub(self.subscriptionName)}')
+ f'{[nf.nf_name for nf.nf_name in self.get_network_functions()]}')
def get(self):
""" Retrieves a SubscriptionModel object
@@ -189,32 +171,15 @@ class Subscription:
"""
return SubscriptionModel.query.all()
- @staticmethod
- def get_nf_names_per_sub(subscription_name):
- """ Retrieves a list of network function names related to the subscription
-
- Args:
- subscription_name (str): The subscription name
-
- Returns:
- list(str): List of network function names
- """
- nf_sub_rel = NfSubRelationalModel.query.filter(
- NfSubRelationalModel.subscription_name == subscription_name).all()
- list_of_nfs = []
- for nf in nf_sub_rel:
- list_of_nfs.append(nf.nf_name)
-
- return list_of_nfs
-
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 nfs:
- mr_pub.publish_subscription_event_data(self, nf.nf_name, app_conf)
+ for nf in set(nfs + 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)
self.add_network_function_to_subscription(nf, sub_model)
self.update_sub_nf_status(self.subscriptionName, SubNfState.PENDING_CREATE.value,
nf.nf_name)
@@ -222,12 +187,12 @@ class Subscription:
raise Exception(f'Error publishing activation event to MR: {err}')
def deactivate_subscription(self, mr_pub, app_conf):
- nfs = self.get_network_functions()
try:
+ nfs = self.get_network_functions()
if nfs:
logger.info(f'Deactivate subscription initiated for {self.subscriptionName}.')
for nf in nfs:
- mr_pub.publish_subscription_event_data(self, nf.nf_name, app_conf)
+ mr_pub.publish_subscription_event_data(self, nf, app_conf)
logger.debug(f'Publishing Event to deactivate '
f'Sub: {self.subscriptionName} for the nf: {nf.nf_name}')
self.update_sub_nf_status(self.subscriptionName,
@@ -265,25 +230,13 @@ class Subscription:
logger.error(f'Failed to update status of nf: {nf_name} for subscription: '
f'{subscription_name}: {e}', exc_info=True)
- def _get_nf_models(self):
+ def get_network_functions(self):
nf_sub_relationships = NfSubRelationalModel.query.filter(
NfSubRelationalModel.subscription_name == self.subscriptionName)
- nf_models = []
+ nfs = []
for nf_sub_entry in nf_sub_relationships:
nf_model_object = NetworkFunctionModel.query.filter(
NetworkFunctionModel.nf_name == nf_sub_entry.nf_name).one_or_none()
- nf_models.append(nf_model_object)
-
- return nf_models
-
- def get_network_functions(self):
- nfs = []
- nf_models = self._get_nf_models()
- for nf_model in nf_models:
- nf = NetworkFunction(
- nf_name=nf_model.nf_name,
- orchestration_status=nf_model.orchestration_status
- )
- nfs.append(nf)
+ nfs.append(nf_model_object.to_nf())
return nfs
diff --git a/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py b/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
index e74a1732..6de702f2 100644
--- a/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
@@ -54,8 +54,8 @@ class SubscriptionHandler:
def _activate(self, local_admin_state, new_administrative_state):
logger.info(f'Administrative State has changed from {local_admin_state} '
f'to {new_administrative_state}.')
- existing_nfs_in_aai = aai.get_pmsh_nfs_from_aai(self.app_conf)
- self.app_conf.subscription.activate_subscription(existing_nfs_in_aai, self.mr_pub,
+ nfs_in_aai = aai.get_pmsh_nfs_from_aai(self.app_conf)
+ self.app_conf.subscription.activate_subscription(nfs_in_aai, self.mr_pub,
self.app_conf)
self.app_conf.subscription.update_subscription_status()
logger.info('Start listening for new NFs on AAI-EVENT topic in MR.')