def add_new_filtered_nfs(filtered_nfs, unlocked_mgs, sub_model): """ Inserts the filtered nfs in measurement groups of subscription Args: filtered_nfs (List[NetworkFunction]): nfs to be inserted unlocked_mgs (List[MeasurementGroupModel]): mgs to be updated with new nfs sub_model (SubscriptionModel): subscription model to update """ if filtered_nfs: logger.info(f'Applying the filtered nfs for subscription: ' f'{sub_model.subscription_name}') save_filtered_nfs(filtered_nfs) apply_subscription_to_nfs(filtered_nfs, sub_model.subscription_name) db.session.commit() if unlocked_mgs: apply_measurement_grp_to_nfs(filtered_nfs, unlocked_mgs) db.session.commit() publish_measurement_grp_to_nfs(sub_model, filtered_nfs, unlocked_mgs) else: logger.error(f'All measurement groups are locked for subscription: ' f'{sub_model.subscription_name}, ' f'please verify/check measurement groups.') else: logger.error(f'No network functions found for subscription: ' f'{sub_model.subscription_name}, ' f'please verify/check NetworkFunctionFilter.')
def main(): try: try: app = create_app() app.app_context().push() db.create_all(app=app) pmsh_app_conf = AppConfig() except Exception as e: logger.error(f'Failed to get config and create application: {e}', exc_info=True) sys.exit(e) policy_response_handler = PolicyResponseHandler(app) policy_response_handler_thread = PeriodicTask( 25, policy_response_handler.poll_policy_topic) policy_response_handler_thread.name = 'policy_event_thread' logger.info('Start polling PMSH_CL_INPUT topic on DMaaP MR.') policy_response_handler_thread.start() aai_event_handler = AAIEventHandler(app) aai_event_handler_thread = PeriodicTask(20, aai_event_handler.execute) aai_event_handler_thread.name = 'aai_event_thread' aai_event_handler_thread.start() periodic_tasks = [ policy_response_handler_thread, aai_event_handler_thread ] signal(SIGTERM, ExitHandler(periodic_tasks=periodic_tasks)) launch_api_server(pmsh_app_conf) except Exception as e: logger.error(f'Failed to initialise PMSH: {e}', exc_info=True) sys.exit(e)
def create_subscription(subscription): """ Creates a subscription Args: subscription (dict): subscription to save. Raises: DuplicateDataException: contains details on duplicate fields Exception: contains runtime error details """ logger.info(f'Initiating create subscription for: {subscription["subscriptionName"]}') perform_validation(subscription) try: sub_model = save_subscription_request(subscription) db.session.commit() logger.info(f'Successfully saved subscription request for: ' f'{subscription["subscriptionName"]}') filtered_nfs = nf_service.capture_filtered_nfs(sub_model.subscription_name) unlocked_mgs = get_unlocked_measurement_grps(sub_model) add_new_filtered_nfs(filtered_nfs, unlocked_mgs, sub_model) except IntegrityError as e: db.session.rollback() raise DuplicateDataException(f'DB Integrity issue encountered: {e.orig.args[0]}') from e except Exception as e: db.session.rollback() raise e finally: db.session.remove()
def get_from_topic(self, mr_topic, consumer_id, consumer_group='dcae_pmsh_cg', timeout=5000, **kwargs): """ Returns the json data from the MrTopic. Args: mr_topic (enum) : Message Router topic to subscribe. consumer_id (str): Within your subscribers group, a name that uniquely identifies your subscribers process. consumer_group (str): A name that uniquely identifies your subscribers. timeout (int): The request timeout value in mSec. Returns: list[str]: the json response from DMaaP Message Router topic. """ try: session = requests.Session() topic_url = self.streams_subscribes[mr_topic].get('dmaap_info').get('topic_url') headers = {'accept': 'application/json', 'content-type': 'application/json', 'InvocationID': kwargs['invocation_id'], 'RequestID': kwargs['request_id']} logger.info(f'Fetching messages from MR topic: {topic_url}') response = session.get(f'{topic_url}/{consumer_group}/{consumer_id}' f'?timeout={timeout}', auth=HTTPBasicAuth(self.aaf_id, self.aaf_pass), headers=headers, verify=(self.ca_cert_path if self.enable_tls else False)) if response.status_code == 503: logger.error(f'MR Service is unavailable at present: {response.content}') response.raise_for_status() if response.ok: return response.json() except Exception as e: logger.error(f'Failed to fetch message from MR: {e}', exc_info=True) raise
def create(self): """ Creates a NetworkFunction database entry """ existing_nf = NetworkFunctionModel.query.filter( NetworkFunctionModel.nf_name == self.nf_name).one_or_none() if existing_nf is None: new_nf = NetworkFunctionModel( nf_name=self.nf_name, ipv4_address=self.ipv4_address, ipv6_address=self.ipv6_address, model_invariant_id=self.model_invariant_id, model_version_id=self.model_version_id, model_name=self.model_name, 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.') return new_nf else: logger.debug( f'Network function {existing_nf.nf_name} already exists,' f' returning this network function..') return existing_nf
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. """ 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_id, app_conf.aaf_pass), verify=(app_conf.ca_cert_path if app_conf.enable_tls else False), cert=((app_conf.cert_path, app_conf.key_path) 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
def delete_filtered_nfs(del_nfs, sub_model, unlocked_mgs): """ Removes unfiltered nfs Args: del_nfs (List[String]): Names of nfs to be deleted sub_model (SubscriptionModel): Subscription model to perform nfs delete unlocked_mgs (List[MeasurementGroupModel]): unlocked msgs to perform nfs delete """ if del_nfs: logger.info(f'Removing nfs from subscription: ' f'{sub_model.subscription_name}') for mg in unlocked_mgs: MeasurementGroupModel.query.filter( MeasurementGroupModel.measurement_group_name == mg.measurement_group_name) \ .update({MeasurementGroupModel.administrative_state: measurement_group_service.AdministrativeState. FILTERING.value}, synchronize_session='evaluate') db.session.commit() nf_meas_relations = NfMeasureGroupRelationalModel.query.filter( NfMeasureGroupRelationalModel.measurement_grp_name == mg. measurement_group_name, NfMeasureGroupRelationalModel. nf_name.in_(del_nfs)).all() measurement_group_service.deactivate_nfs(sub_model, mg, nf_meas_relations)
def poll_policy_topic(self): """ This method polls MR for response from policy. It checks whether the message is for the relevant subscription and then handles the response """ self.app.app_context().push() logger.info( 'Polling MR for XNF activation/deactivation policy response events.' ) try: response_data = AppConfig.get_instance(). \ get_from_topic(MRTopic.POLICY_PM_SUBSCRIBER.value, 'dcae_pmsh_policy_cl_input') for data in response_data: data = json.loads(data) measurement_group_name = data['status']['measurementGroupName'] subscription_name = data['status']['subscriptionName'] measurement_group = (MeasurementGroupModel.query.filter( MeasurementGroupModel.measurement_group_name == measurement_group_name, subscription_name == MeasurementGroupModel.subscription_name).one_or_none()) nf_name = data['status']['nfName'] response_message = data['status']['message'] if measurement_group: self._handle_response( measurement_group_name, measurement_group.administrative_state, nf_name, response_message) else: logger.info( f'Polled MR response provides missing measurement ' f'group name : {measurement_group_name}') except Exception as err: logger.error( f'Error trying to poll policy response topic on MR: {err}', exc_info=True)
def create_measurement_group(subscription, measurement_group_name, body): """ Creates a measurement group for a subscription Args: subscription (SubscriptionModel): Subscription. measurement_group_name (String): Name of MeasGroup body (dict): measurement group request body to save. """ logger.info( f'Initiating create measurement group for: {measurement_group_name}') check_duplication(subscription.subscription_name, measurement_group_name) check_measurement_group_names_comply(measurement_group_name, body) new_mg = [ save_measurement_group(body["measurementGroup"], subscription.subscription_name) ] if body["measurementGroup"][ "administrativeState"] == AdministrativeState.UNLOCKED.value: filtered_nfs = nf_service.capture_filtered_nfs( subscription.subscription_name) subscription_service.add_new_filtered_nfs(filtered_nfs, new_mg, subscription) else: logger.info( f'Measurement Group {measurement_group_name} is not in an unlocked state' ) db.session.commit()
def put_nf_filter(subscription_name, body): """ Performs network function filter update for the respective subscription Args: subscription_name (String): Name of the subscription. body (dict): Request body with nf filter data to update. Returns: string, HTTPStatus: Successfully updated network function Filter, 200 string, HTTPStatus: Invalid request details, 400 string, HTTPStatus: Cannot update as Locked/Filtering request is in progress, 409 string, HTTPStatus: Exception details of server failure, 500 """ logger.info('Performing network function filter update for subscription ' f'with sub name: {subscription_name} ') response = 'Successfully updated network function Filter', HTTPStatus.OK.value try: subscription_service.update_filter(subscription_name, body) except InvalidDataException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.BAD_REQUEST.value except DataConflictException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.CONFLICT.value except Exception as exception: logger.error( 'Update nf filter request was not processed for sub name: ' f'{subscription_name} due to Exception : {exception}') response = 'Update nf filter request was not processed for sub name: ' \ f'{subscription_name} due to Exception : {exception}', \ HTTPStatus.INTERNAL_SERVER_ERROR return response
def deactivate_nfs(sub_model, measurement_group, nf_meas_relations): """ Deactivates network functions associated with measurement group Args: sub_model (SubscriptionModel): Subscription model measurement_group (MeasurementGroupModel): Measurement group to update nf_meas_relations (list[NfMeasureGroupRelationalModel]): nf to measurement grp relations """ for nf in nf_meas_relations: logger.info( f'Saving measurement group to nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name} with DELETE request') update_measurement_group_nf_status( measurement_group.measurement_group_name, MgNfState.PENDING_DELETE.value, nf.nf_name) try: network_function = NetworkFunction(**nf.serialize_meas_group_nfs()) logger.info( f'Publishing event for nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name} with DELETE request' ) publish_measurement_group(sub_model, measurement_group, network_function, 'DELETE') except Exception as ex: logger.error( f'Publish event failed for nf name, measure_grp_name, sub_name: ' f'{nf.nf_name},{measurement_group.measurement_group_name}, ' f'{sub_model.subscription_name} with error: {ex}')
def apply_subscription_to_nfs(filtered_nfs, subscription_name): """ Associate and saves the subscription with Network functions Args: filtered_nfs (list[NetworkFunction]): list of filtered network functions to save. subscription_name (string): subscription name to save against nfs """ logger.info(f'Saving filtered nfs for subscription: {subscription_name}') for nf in filtered_nfs: new_nf_sub_rel = NfSubRelationalModel(subscription_name=subscription_name, nf_name=nf.nf_name) db.session.add(new_nf_sub_rel)
def capture_filtered_nfs(sub_name): """ Retrieves network functions from AAI client and returns a list of filtered NetworkFunctions using the Filter Args: sub_name (string): The name of subscription inorder to perform filtering Returns: list[NetworkFunction]: a list of filtered NetworkFunction Objects or an empty list if no network function is filtered. """ logger.info(f'Getting filtered nfs for subscription: {sub_name}') nf_filter = NetworkFunctionFilter.get_network_function_filter(sub_name) return aai_client.get_pmsh_nfs_from_aai(AppConfig.get_instance(), nf_filter)
def delete_meas_group_by_name(subscription_name, measurement_group_name): """Deletes the measurement group by name Args: subscription_name (String): Name of the subscription measurement_group_name (String): Name of measurement group Returns: NoneType, HTTPStatus: None, 204 dict, HTTPStatus: measurement group not defined, 404 dict, HTTPStatus: Reason for not deleting measurement group, 409 dict, HTTPStatus: Exception details of failure, 500 """ logger.info( f'API call received to delete measurement group: {measurement_group_name}' ) try: measurement_group_administrative_status = \ measurement_group_service.query_get_meas_group_admin_status(subscription_name, measurement_group_name) if measurement_group_administrative_status == \ measurement_group_service.AdministrativeState.LOCKED.value: if measurement_group_service.query_to_delete_meas_group( subscription_name, measurement_group_name) == 1: return None, HTTPStatus.NO_CONTENT else: logger.error( f'Measurement Group not found with name {measurement_group_name}' ) return { 'error': f'Measurement Group not found with name ' f'{measurement_group_name}' }, HTTPStatus.NOT_FOUND.value else: logger.error( 'Measurement Group was not deleted because the Administrative State ' f'was {measurement_group_administrative_status}') return {'error': 'Measurement Group was not deleted because the Administrative State ' 'was {measurement_group_administrative_status}'}, \ HTTPStatus.CONFLICT.value except Exception as e: logger.error( f'Try again, measurement group {measurement_group_name} was not' f'deleted due to exception: {e}') return { 'error': f'Try again, measurement group {measurement_group_name} was not ' f'deleted due to exception: {e}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value
def query_all_subscriptions(): """ Queries the db for all existing subscriptions defined in PMSH Returns list (SubscriptionModel): of all subscriptions else None """ logger.info('Attempting to fetch all the subscriptions') subscriptions = db.session.query(SubscriptionModel) \ .options(joinedload(SubscriptionModel.network_filter), joinedload(SubscriptionModel.measurement_groups), joinedload(SubscriptionModel.nfs)) \ .all() db.session.remove() return subscriptions
def save_nf_filter(nf_filter, subscription_name): """ Saves the nf_filter data request Args: nf_filter (dict) : network function filter to save subscription_name (string) : subscription name to associate with nf filter. """ logger.info(f'Saving nf filter for subscription request: {subscription_name}') new_filter = NetworkFunctionFilterModel(subscription_name=subscription_name, nf_names=nf_filter['nfNames'], model_invariant_ids=nf_filter['modelInvariantIDs'], model_version_ids=nf_filter['modelVersionIDs'], model_names=nf_filter['modelNames']) db.session.add(new_filter)
def get_subscriptions_list(): """ Converts all subscriptions to JSON and appends to list Returns list: dict of all subscriptions else empty """ subscriptions = query_all_subscriptions() subscriptions_list = [] if subscriptions is not None: logger.info('Queried all the subscriptions was successful') for subscription in subscriptions: if (subscription.network_filter is not None) and \ (len(subscription.measurement_groups) != 0): subscriptions_list.append(subscription.serialize()) return subscriptions_list
def apply_measurement_grp_to_nfs(filtered_nfs, unlocked_mgs): """ Saves measurement groups against nfs with status as PENDING_CREATE Args: filtered_nfs (list[NetworkFunction]): list of filtered network functions unlocked_mgs (list[MeasurementGroupModel]): list of measurement group """ for measurement_group in unlocked_mgs: for nf in filtered_nfs: logger.info(f'Saving measurement group to nf name, measure_grp_name: {nf.nf_name},' f'{measurement_group.measurement_group_name}') measurement_group_service.apply_nf_status_to_measurement_group( nf.nf_name, measurement_group.measurement_group_name, measurement_group_service.MgNfState.PENDING_CREATE.value)
def publish_to_topic(self, mr_topic, event_json, **kwargs): """ Publish the event to the DMaaP Message Router topic. Args: mr_topic (enum) : Message Router topic to publish. event_json (dict): the json data to be published. """ session = requests.Session() topic_url = self.streams_publishes[mr_topic].get('dmaap_info').get('topic_url') headers = {'content-type': 'application/json', 'x-transactionid': kwargs['request_id'], 'InvocationID': kwargs['invocation_id'], 'RequestID': kwargs['request_id']} logger.info(f'Publishing event to MR topic: {topic_url}') response = session.post(topic_url, headers=headers, auth=HTTPBasicAuth(self.aaf_id, self.aaf_pass), json=event_json, verify=(self.ca_cert_path if self.enable_tls else False)) response.raise_for_status()
def query_unlocked_mg_by_sub_name(subscription_name): """ Queries the db for unlocked/locking measurement groups by subscription name Args: subscription_name (String): Name of the Subscription Returns: list (MeasurementGroupModel): If measurement groups with admin state UNLOCKED exists else empty list """ logger.info(f'Attempting to fetch measurement groups by subscription name: {subscription_name}') mg_model = db.session.query(MeasurementGroupModel) \ .filter_by(subscription_name=subscription_name) \ .filter(MeasurementGroupModel.administrative_state.in_(('UNLOCKED', 'LOCKING'))).all() db.session.remove() return mg_model
def save_nf_filter_update(sub_name, nf_filter): """ Updates the network function filter for the subscription in the db Args: sub_name (String): Name of the Subscription nf_filter (dict): filter object to update in the subscription """ NetworkFunctionFilterModel.query.filter( NetworkFunctionFilterModel.subscription_name == sub_name). \ update({NetworkFunctionFilterModel.nf_names: nf_filter['nfNames'], NetworkFunctionFilterModel.model_invariant_ids: nf_filter['modelInvariantIDs'], NetworkFunctionFilterModel.model_version_ids: nf_filter['modelVersionIDs'], NetworkFunctionFilterModel.model_names: nf_filter['modelNames']}, synchronize_session='evaluate') db.session.commit() logger.info(f'Successfully saved filter for subscription: {sub_name}')
def query_subscription_by_name(subscription_name): """ Queries the db for existing subscription by name Args: subscription_name (String): Name of the Subscription Returns: SubscriptionModel: If subscription was defined else None """ logger.info(f'Attempting to fetch subscription by name: {subscription_name}') subscription_model = db.session.query(SubscriptionModel) \ .options(joinedload(SubscriptionModel.network_filter), joinedload(SubscriptionModel.measurement_groups), joinedload(SubscriptionModel.nfs)) \ .filter_by(subscription_name=subscription_name).first() db.session.remove() return subscription_model
def check_measurement_group_names_comply(measurement_group_name, measurement_group): """ Check if measurement_group_name matches the name in the URI Args: measurement_group_name (String): Name of the measurement group measurement_group (dict): Measurement Group """ logger.info("Checking names match") if measurement_group_name != measurement_group["measurementGroup"][ "measurementGroupName"]: logger.info( f'Changing measurement_group_name in body to {measurement_group_name}' ) measurement_group["measurementGroup"][ "measurementGroupName"] = measurement_group_name
def check_duplication(subscription_name, measurement_group_name): """ Check if measurement group exists already Args: measurement_group_name (String): Name of the measurement group subscription_name (string) : subscription name to associate with measurement group. Raises: DuplicateDataException: exception containing the detail on duplicate data field. """ logger.info( f"Checking that measurement group {measurement_group_name} does not exist" ) if query_meas_group_by_name(subscription_name, measurement_group_name): raise DuplicateDataException( f'Measurement Group Name: ' f'{measurement_group_name} already exists.')
def get_subscriptions(): """ Retrieves all the subscriptions that are defined in PMSH. Returns: list (dict), HTTPStatus: All subs in PMSH, 200 dict, HTTPStatus: Exception details of failure, 500 """ logger.info('API call received to fetch all subscriptions') try: subscriptions = subscription_service.get_subscriptions_list() return subscriptions, HTTPStatus.OK.value except Exception as exception: logger.error( f'The following exception occurred while fetching subscriptions: {exception}' ) return { 'error': 'Request was not processed due to Exception : ' f'{exception}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value
def _get_config(self): """ 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: logger.info('Attempting to fetch PMSH Configuration from CBS.') config = get_all() logger.info(f'Successfully fetched PMSH config from CBS: {config}') return config except Exception as e: logger.error(f'Failed to get config from CBS: {e}', exc_info=True) raise ValueError(e) from e
def delete_subscription_by_name(subscription_name): """ Deletes the subscription by name Args: subscription_name (String): Name of the subscription Returns: NoneType, HTTPStatus: None, 204 dict, HTTPStatus: subscription not defined, 404 dict, HTTPStatus: Reason for not deleting subscription, 409 dict, HTTPStatus: Exception details of failure, 500 """ logger.info( f'API call received to delete subscription by name: {subscription_name}' ) try: unlocked_locking_mgs = \ subscription_service.query_unlocked_mg_by_sub_name(subscription_name) if not unlocked_locking_mgs: if subscription_service.query_to_delete_subscription_by_name( subscription_name) == 1: return None, HTTPStatus.NO_CONTENT else: logger.error( f'Subscription is not defined with name {subscription_name}' ) return {'error': f'Subscription is not defined with name {subscription_name}'}, \ HTTPStatus.NOT_FOUND.value else: logger.error( 'Subscription is not deleted due to associated MGs were UNLOCKED ' '(or) under update process to LOCKED') return {'error': 'Subscription is not deleted due to the following MGs were UNLOCKED ' '(or) under update process to LOCKED', 'measurementGroupNames': [{'measurementGroupName': mg.measurement_group_name}for mg in unlocked_locking_mgs]}, \ HTTPStatus.CONFLICT.value except Exception as exception: logger.error(f'Try again, subscription with name {subscription_name}' f'is not deleted due to following exception: {exception}') return {'error': f'Try again, subscription with name {subscription_name}' f'is not deleted due to following exception: {exception}'}, \ HTTPStatus.INTERNAL_SERVER_ERROR.value
def update_admin_state(subscription_name, measurement_group_name, body): """ Performs administrative state update for the respective subscription and measurement group name Args: subscription_name (String): Name of the subscription. measurement_group_name (String): Name of the measurement group body (dict): Request body with admin state to update. Returns: string, HTTPStatus: Successfully updated admin state, 200 string, HTTPStatus: Invalid request details, 400 string, HTTPStatus: Cannot update as Locked request is in progress, 409 string, HTTPStatus: Exception details of server failure, 500 """ logger.info( 'Performing administration status update for measurement group ' f'with sub name: {subscription_name} and measurement ' f'group name: {measurement_group_name} to {body["administrativeState"]} status' ) response = 'Successfully updated admin state', HTTPStatus.OK.value try: meas_group = measurement_group_service.query_meas_group_by_name( subscription_name, measurement_group_name) measurement_group_service.update_admin_status( meas_group, body["administrativeState"]) except InvalidDataException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.BAD_REQUEST.value except DataConflictException as exception: logger.error(exception.args[0]) response = exception.args[0], HTTPStatus.CONFLICT.value except Exception as exception: logger.error( 'Update admin status request was not processed for sub name: ' f'{subscription_name} and meas group name: ' f'{measurement_group_name} due to Exception : {exception}') response = 'Update admin status request was not processed for sub name: '\ f'{subscription_name} and meas group name: {measurement_group_name}'\ f' due to Exception : {exception}', HTTPStatus.INTERNAL_SERVER_ERROR return response
def get_unlocked_measurement_grps(sub_model): """ Gets unlocked measurement groups and logs locked measurement groups Args: sub_model (SubscriptionModel): Subscription model to perform nfs delete Returns: unlocked_mgs (List[MeasurementGroupModel]): unlocked msgs in a subscription """ unlocked_mgs = [] for measurement_group in sub_model.measurement_groups: if measurement_group.administrative_state \ == measurement_group_service.AdministrativeState.UNLOCKED.value: unlocked_mgs.append(measurement_group) else: logger.info(f'No nfs added as measure_grp_name: ' f'{measurement_group.measurement_group_name} is LOCKED') return unlocked_mgs
def get_meas_group_with_nfs(subscription_name, measurement_group_name): """ Retrieves the measurement group and it's associated network functions Args: subscription_name (String): Name of the subscription. measurement_group_name (String): Name of the measurement group Returns: dict, HTTPStatus: measurement group info with associated nfs, 200 dict, HTTPStatus: measurement group was not defined, 404 dict, HTTPStatus: Exception details of failure, 500 """ logger.info( 'API call received to query measurement group and associated network' f' functions by using sub name: {subscription_name} and measurement ' f'group name: {measurement_group_name}') try: meas_group = measurement_group_service.query_meas_group_by_name( subscription_name, measurement_group_name) if meas_group is not None: return meas_group.meas_group_with_nfs(), HTTPStatus.OK.value else: logger.error( 'measurement group was not defined with the sub name: ' f'{subscription_name} and meas group name: ' f'{measurement_group_name}') return { 'error': 'measurement group was not defined with the sub name: ' f'{subscription_name} and meas group name: ' f'{measurement_group_name}' }, HTTPStatus.NOT_FOUND.value except Exception as exception: logger.error( 'The following exception occurred while fetching measurement group: ' f'{exception}') return { 'error': 'Request was not processed due to Exception : ' f'{exception}' }, HTTPStatus.INTERNAL_SERVER_ERROR.value