diff options
Diffstat (limited to 'components/pm-subscription-handler/pmsh_service/mod/subscription.py')
-rwxr-xr-x | components/pm-subscription-handler/pmsh_service/mod/subscription.py | 205 |
1 files changed, 109 insertions, 96 deletions
diff --git a/components/pm-subscription-handler/pmsh_service/mod/subscription.py b/components/pm-subscription-handler/pmsh_service/mod/subscription.py index dbcd7a5e..97bfc401 100755 --- a/components/pm-subscription-handler/pmsh_service/mod/subscription.py +++ b/components/pm-subscription-handler/pmsh_service/mod/subscription.py @@ -33,6 +33,7 @@ class SubNfState(Enum): class AdministrativeState(Enum): UNLOCKED = 'UNLOCKED' LOCKED = 'LOCKED' + PENDING = 'PENDING' subscription_nf_states = { @@ -55,28 +56,7 @@ class Subscription: self.fileLocation = kwargs.get('fileLocation') self.nfFilter = kwargs.get('nfFilter') self.measurementGroups = kwargs.get('measurementGroups') - - def prepare_subscription_event(self, xnf_name, app_conf): - """Prepare the sub event for publishing - - Args: - xnf_name: the AAI xnf name. - app_conf (AppConfig): the application configuration. - - Returns: - dict: the Subscription event to be published. - """ - 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, - '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) - raise + self.create() def create(self): """ Creates a subscription database entry @@ -89,7 +69,7 @@ class Subscription: SubscriptionModel.subscription_name == self.subscriptionName).one_or_none()) if existing_subscription is None: new_subscription = SubscriptionModel(subscription_name=self.subscriptionName, - status=self.administrativeState) + status=AdministrativeState.PENDING.value) db.session.add(new_subscription) db.session.commit() return new_subscription @@ -101,54 +81,111 @@ class Subscription: logger.error(f'Failed to create subscription {self.subscriptionName} in the DB: {e}', exc_info=True) - def add_network_function_to_subscription(self, nf): + def update_subscription_status(self): + """ Updates the status of subscription in subscription table """ + try: + SubscriptionModel.query.filter( + SubscriptionModel.subscription_name == self.subscriptionName)\ + .update({SubscriptionModel.status: self.administrativeState}, + synchronize_session='evaluate') + + db.session.commit() + except Exception as e: + 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): + """Prepare the sub event for publishing + + Args: + xnf_name: the AAI xnf name. + app_conf (AppConfig): the application configuration. + + Returns: + dict: the Subscription event to be published. + """ + 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, + '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) + raise + + def add_network_function_to_subscription(self, nf, sub_model): """ Associates a network function to a Subscription Args: - nf : A NetworkFunction object. + sub_model(SubscriptionModel): The SubscriptionModel from the DB. + nf(NetworkFunction): A NetworkFunction object. """ - current_sub = self.create() try: current_nf = nf.create() - logger.debug(f'Adding network function {nf.nf_name} to Subscription ' - f'{current_sub.subscription_name}') existing_entry = NfSubRelationalModel.query.filter( - NfSubRelationalModel.subscription_name == current_sub.subscription_name, + NfSubRelationalModel.subscription_name == self.subscriptionName, NfSubRelationalModel.nf_name == current_nf.nf_name).one_or_none() if existing_entry is None: - new_nf_sub = NfSubRelationalModel(current_sub.subscription_name, + new_nf_sub = NfSubRelationalModel(self.subscriptionName, nf.nf_name, SubNfState.PENDING_CREATE.value) - new_nf_sub.nf = current_nf - current_sub.nfs.append(new_nf_sub) - logger.debug(f'Network function {current_nf.nf_name} added to Subscription ' - f'{current_sub.subscription_name}') - db.session.add(current_sub) + sub_model.nfs.append(new_nf_sub) + db.session.add(sub_model) db.session.commit() + logger.info(f'Network function {current_nf.nf_name} added to Subscription ' + f'{self.subscriptionName}') except Exception as e: logger.error(f'Failed to add nf {nf.nf_name} to subscription ' - f'{current_sub.subscription_name}: {e}', exc_info=True) - logger.debug(f'Subscription {current_sub.subscription_name} now contains these XNFs:' - f'{Subscription.get_nf_names_per_sub(current_sub.subscription_name)}') + 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)}') - @staticmethod - def get(subscription_name): - """ Retrieves a subscription - - Args: - subscription_name (str): The subscription name + def get(self): + """ Retrieves a SubscriptionModel object Returns: - Subscription object else None + SubscriptionModel object else None """ return SubscriptionModel.query.filter( - SubscriptionModel.subscription_name == subscription_name).one_or_none() + SubscriptionModel.subscription_name == self.subscriptionName).one_or_none() + + def get_local_sub_admin_state(self): + """ Retrieves the subscription admin state + + Returns: + str: The admin state of the SubscriptionModel + """ + sub_model = SubscriptionModel.query.filter( + SubscriptionModel.subscription_name == self.subscriptionName).one_or_none() + return sub_model.status @staticmethod def get_all(): """ Retrieves a list of subscriptions Returns: - list: Subscription list else empty + list(SubscriptionModel): Subscriptions list else empty """ return SubscriptionModel.query.all() @@ -160,7 +197,7 @@ class Subscription: subscription_name (str): The subscription name Returns: - list: List of network function names + list(str): List of network function names """ nf_sub_rel = NfSubRelationalModel.query.filter( NfSubRelationalModel.subscription_name == subscription_name).all() @@ -170,65 +207,41 @@ class Subscription: return list_of_nfs - def update_subscription_status(self): - """ Updates the status of subscription in subscription table """ - try: - SubscriptionModel.query.filter( - SubscriptionModel.subscription_name == self.subscriptionName)\ - .update({SubscriptionModel.status: self.administrativeState}, - synchronize_session='evaluate') - - db.session.commit() - except Exception as e: - 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 process_subscription(self, nfs, mr_pub, app_conf): - action = 'Deactivate' - sub_nf_state = SubNfState.PENDING_DELETE.value - self.update_subscription_status() - - if self.administrativeState == AdministrativeState.UNLOCKED.value: - action = 'Activate' - sub_nf_state = SubNfState.PENDING_CREATE.value - logger.info(f'{action} subscription initiated for {self.subscriptionName}.') - + def activate_subscription(self, nfs, mr_pub, app_conf): + logger.info(f'Activate subscription initiated for {self.subscriptionName}.') try: + sub_model = self.get() for nf in nfs: mr_pub.publish_subscription_event_data(self, nf.nf_name, app_conf) - logger.debug(f'Publishing Event to {action} ' - f'Sub: {self.subscriptionName} for the nf: {nf.nf_name}') - if action == 'Activate': - self.add_network_function_to_subscription(nf) - self.update_sub_nf_status(self.subscriptionName, sub_nf_state, nf.nf_name) + logger.info(f'Publishing event to activate ' + f'Sub: {self.subscriptionName} for the nf: {nf.nf_name}') + self.add_network_function_to_subscription(nf, sub_model) + self.update_sub_nf_status(self.subscriptionName, SubNfState.PENDING_CREATE.value, + nf.nf_name) except Exception as err: raise Exception(f'Error publishing activation event to MR: {err}') + def deactivate_subscription(self, mr_pub, app_conf): + nfs = self.get_network_functions() + try: + 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) + logger.debug(f'Publishing Event to deactivate ' + f'Sub: {self.subscriptionName} for the nf: {nf.nf_name}') + self.update_sub_nf_status(self.subscriptionName, + SubNfState.PENDING_DELETE.value, + nf.nf_name) + except Exception as err: + raise Exception(f'Error publishing deactivation event to MR: {err}') + @staticmethod def get_all_nfs_subscription_relations(): """ Retrieves all network function to subscription relations Returns: - list: NetworkFunctions per Subscription list else empty + list(NfSubRelationalModel): NetworkFunctions per Subscription list else empty """ nf_per_subscriptions = NfSubRelationalModel.query.all() return nf_per_subscriptions |