diff options
author | 2022-02-23 13:38:34 +0000 | |
---|---|---|
committer | 2022-03-09 12:25:35 +0000 | |
commit | 36987b3ac6eccb475e9976b95a08683a86682cdc (patch) | |
tree | ff0b5a0296ef94450a04ae1b5b1701e052e27777 /components/pm-subscription-handler/pmsh_service/mod/api | |
parent | 6c9c8cc2a1a289ef0b4172d387376d0367549fe3 (diff) |
[PMSH] Create Measurement Group API
Creates Measurement Group for an associated Subscription
POST: /subscription/{subscription_name}/measurementGroups/{measurement_group_name}
Measurement Group structure:
{
"measurementGroup": {
"measurementGroupName": "string",
"fileBasedGP": 0,
"fileLocation": "string",
"administrativeState": "LOCKED",
"measurementTypes": [
{ "measurementType": "string" }
],
"managedObjectDNsBasic": [
{ "DN": "string" }
]
}
}
Returns:
Success: 201
Invalid Data: 400 when measurement_group_name in URI and body do not match
Not Found: 404 when subscription does not exist to associate measurement group to
Duplicate Data: Measurement group with that name already exists
Error raised for any server failure
Issue-ID: DCAEGEN2-2920
Signed-off-by: egernug <gerard.nugent@est.tech>
Change-Id: I812c5a891e9bed5433000f5da24e2667bf9a5d65
Diffstat (limited to 'components/pm-subscription-handler/pmsh_service/mod/api')
4 files changed, 149 insertions, 15 deletions
diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/controller.py b/components/pm-subscription-handler/pmsh_service/mod/api/controller.py index 2e811c28..1aad0519 100755 --- a/components/pm-subscription-handler/pmsh_service/mod/api/controller.py +++ b/components/pm-subscription-handler/pmsh_service/mod/api/controller.py @@ -22,7 +22,6 @@ from mod.api.services import subscription_service, measurement_group_service from connexion import NoContent from mod.api.custom_exception import InvalidDataException, DuplicateDataException, \ DataConflictException -from mod.api.services.measurement_group_service import AdministrativeState def status(): @@ -69,6 +68,58 @@ def post_subscription(body): return response +def post_meas_group(subscription_name, measurement_group_name, body): + """ + Creates a measurement group for a subscription + + Args: + subscription_name (String): Name of the subscription. + measurement_group_name (String): Name of the measurement group + body (dict): measurement group request body to save. + + Returns: + Success : NoContent, 201 + Invalid Data: Invalid message, 400 + Not Found: Subscription no found, 404 + Duplicate Data : Duplicate field detail, 409 + + Raises: + Error: If anything fails in the server. + """ + response = NoContent, HTTPStatus.CREATED.value + try: + subscription = subscription_service.query_subscription_by_name(subscription_name) + if subscription is not None: + try: + measurement_group_service.create_measurement_group(subscription, + measurement_group_name, body) + except DuplicateDataException as e: + logger.error(f'Failed to create measurement group for ' + f'{subscription_name} due to duplicate data: {e}', + exc_info=True) + response = e.args[0], HTTPStatus.CONFLICT.value + except InvalidDataException as e: + logger.error(f'Failed to create measurement group for ' + f'{subscription_name} due to invalid data: {e}', + exc_info=True) + response = e.args[0], HTTPStatus.BAD_REQUEST.value + except Exception as e: + logger.error(f'Failed to create measurement group due to exception {e}') + response = e.args[0], HTTPStatus.INTERNAL_SERVER_ERROR.value + else: + logger.error('queried subscription was un successful with the name: ' + f'{subscription_name}') + return {'error': 'Subscription was not defined with the name : ' + f'{subscription_name}'}, HTTPStatus.NOT_FOUND.value + + except Exception as exception: + logger.error(f'While querying the subscription with name: {subscription_name}, ' + f'it occurred the following exception "{exception}"') + return {'error': 'Request was not processed due to Exception : ' + f'{exception}'}, HTTPStatus.INTERNAL_SERVER_ERROR.value + return response + + def get_subscription_by_name(subscription_name): """ Retrieves subscription based on the name @@ -169,7 +220,8 @@ def delete_meas_group_by_name(subscription_name, measurement_group_name): measurement_group_administrative_status = \ measurement_group_service.query_get_meas_group_admin_status(subscription_name, measurement_group_name) - if measurement_group_administrative_status == AdministrativeState.LOCKED.value: + 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 diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml b/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml index 1f24f171..258ca51e 100644 --- a/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml +++ b/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml @@ -160,6 +160,37 @@ paths: description: Exception occurred while querying database /subscription/{subscription_name}/measurementGroups/{measurement_group_name}: + post: + description: Create a measurement group for a given subscription + operationId: mod.api.controller.post_meas_group + tags: + - "Measurement Group" + parameters: + - name : subscription_name + in: path + required: true + description: Name of the subscription + type: string + - name: measurement_group_name + in: path + required: true + description: Name of the measurement group + type: string + - in: "body" + name: "body" + required: true + schema: + $ref: "#/definitions/measurementGroup" + responses: + 201: + description: Successfully created measurement group + 404: + description: Subscription with the specified name not found + 409: + description: Duplicate data + 500: + description: Internal server error + get: description: Get the measurement group and associated network functions from PMSH by using sub name and meas group name diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/services/measurement_group_service.py b/components/pm-subscription-handler/pmsh_service/mod/api/services/measurement_group_service.py index 145a492c..29c4a27a 100644 --- a/components/pm-subscription-handler/pmsh_service/mod/api/services/measurement_group_service.py +++ b/components/pm-subscription-handler/pmsh_service/mod/api/services/measurement_group_service.py @@ -16,9 +16,10 @@ # SPDX-License-Identifier: Apache-2.0 # ============LICENSE_END===================================================== -from mod.api.custom_exception import InvalidDataException, DataConflictException -from mod.api.db_models import MeasurementGroupModel, NfMeasureGroupRelationalModel, \ - SubscriptionModel +from mod.api.custom_exception import InvalidDataException, \ + DataConflictException, DuplicateDataException +from mod.api.db_models import MeasurementGroupModel, \ + NfMeasureGroupRelationalModel, SubscriptionModel from mod import db, logger from mod.api.services import nf_service, subscription_service from mod.network_function import NetworkFunction @@ -59,6 +60,58 @@ mg_nf_states = { } +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, subscription.subscription_name)] + if body["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') + + +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 + + """ + if measurement_group_name != measurement_group["measurementGroupName"]: + logger.info(f'Changing measurement_group_name in body to {measurement_group_name}') + measurement_group["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 save_measurement_group(measurement_group, subscription_name): """ Saves the measurement_group data request @@ -165,10 +218,6 @@ def delete_nf_to_measurement_group(nf_name, measurement_group_name, status): NfMeasureGroupRelationalModel.nf_name == nf_name).one_or_none() db.session.delete(nf_measurement_group_rel) db.session.commit() - nf_relations = NfMeasureGroupRelationalModel.query.filter( - NfMeasureGroupRelationalModel.nf_name == nf_name).all() - if not nf_relations: - NetworkFunction.delete(nf_name=nf_name) except Exception as e: logger.error(f'Failed to delete nf: {nf_name} for measurement group: ' f'{measurement_group_name} due to: {e}') diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/services/subscription_service.py b/components/pm-subscription-handler/pmsh_service/mod/api/services/subscription_service.py index 99b72dfb..6216a803 100644 --- a/components/pm-subscription-handler/pmsh_service/mod/api/services/subscription_service.py +++ b/components/pm-subscription-handler/pmsh_service/mod/api/services/subscription_service.py @@ -23,7 +23,6 @@ from mod.api.db_models import SubscriptionModel, NfSubRelationalModel, \ from mod.api.services import measurement_group_service, nf_service from mod.api.custom_exception import InvalidDataException, DuplicateDataException, \ DataConflictException -from mod.api.services.measurement_group_service import MgNfState, AdministrativeState from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import joinedload @@ -155,7 +154,7 @@ def apply_measurement_grp_to_nfs(filtered_nfs, unlocked_mgs): f'{measurement_group.measurement_group_name}') measurement_group_service.apply_nf_status_to_measurement_group( nf.nf_name, measurement_group.measurement_group_name, - MgNfState.PENDING_CREATE.value) + measurement_group_service.MgNfState.PENDING_CREATE.value) def check_missing_data(subscription): @@ -261,7 +260,7 @@ def save_subscription(subscription): SubscriptionModel(subscription_name=subscription["subscriptionName"], operational_policy_name=subscription["operationalPolicyName"], control_loop_name=control_loop_name, - status=AdministrativeState.LOCKED.value) + status=measurement_group_service.AdministrativeState.LOCKED.value) db.session.add(subscription_model) return subscription_model @@ -450,7 +449,7 @@ def get_unlocked_measurement_grps(sub_model): unlocked_mgs = [] for measurement_group in sub_model.measurement_groups: if measurement_group.administrative_state \ - == AdministrativeState.UNLOCKED.value: + == measurement_group_service.AdministrativeState.UNLOCKED.value: unlocked_mgs.append(measurement_group) else: logger.info(f'No nfs added as measure_grp_name: ' @@ -474,7 +473,8 @@ def delete_filtered_nfs(del_nfs, sub_model, unlocked_mgs): for mg in unlocked_mgs: MeasurementGroupModel.query.filter( MeasurementGroupModel.measurement_group_name == mg.measurement_group_name) \ - .update({MeasurementGroupModel.administrative_state: AdministrativeState. + .update({MeasurementGroupModel.administrative_state: + measurement_group_service.AdministrativeState. FILTERING.value}, synchronize_session='evaluate') db.session.commit() nf_meas_relations = NfMeasureGroupRelationalModel.query.filter( @@ -515,7 +515,9 @@ def validate_sub_mgs_state(sub_model): DataConflictException: contains details on conflicting status in measurement group """ mg_names_processing = [mg for mg in sub_model.measurement_groups - if mg.administrative_state in [AdministrativeState.FILTERING.value, + if mg.administrative_state in [measurement_group_service. + AdministrativeState.FILTERING.value, + measurement_group_service. AdministrativeState.LOCKING.value]] if mg_names_processing: raise DataConflictException('Cannot update filter as subscription: ' |