diff options
Diffstat (limited to 'genericparser/packages/biz/nsdm_subscription.py')
-rw-r--r-- | genericparser/packages/biz/nsdm_subscription.py | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/genericparser/packages/biz/nsdm_subscription.py b/genericparser/packages/biz/nsdm_subscription.py new file mode 100644 index 0000000..ba74c70 --- /dev/null +++ b/genericparser/packages/biz/nsdm_subscription.py @@ -0,0 +1,219 @@ +# Copyright (C) 2019 Verizon. All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import ast +import json +import logging +import requests +import uuid + +from collections import Counter + +from rest_framework import status + +from genericparser.packages import const +from genericparser.pub.database.models import NsdmSubscriptionModel +from genericparser.pub.exceptions import GenericparserException, \ + ResourceNotFoundException, \ + NsdmBadRequestException, NsdmDuplicateSubscriptionException +from genericparser.pub.utils.values import ignore_case_get + +logger = logging.getLogger(__name__) + +PARAMSBASICKEYS = ["userName", "password"] + +PARAMSOAUTH2CLIENTCREDENTIALSKEYS = ["clientId", "clientPassword", + "tokenEndpoint"] + + +def is_filter_type_equal(new_filter, existing_filter): + return Counter(list(set(new_filter))) == Counter(existing_filter) + + +class NsdmSubscription: + + def __init__(self): + pass + + def query_single_subscription(self, subscription_id): + logger.debug("Start Query Subscription... ") + subscription = \ + NsdmSubscriptionModel.objects.filter( + subscriptionid=subscription_id) + if not subscription.exists(): + raise ResourceNotFoundException( + "Subscription(%s) doesn't exists" % subscription_id) + logger.debug("Subscription found... ") + return self.fill_resp_data(subscription[0]) + + def delete_single_subscription(self, subscription_id): + logger.debug("Start Delete Subscription... ") + subscription = \ + NsdmSubscriptionModel.objects.filter( + subscriptionid=subscription_id) + if not subscription.exists(): + raise ResourceNotFoundException( + "Subscription(%s) doesn't exists" % subscription_id) + subscription.delete() + logger.debug("Deleted Subscription... ") + + def query_multi_subscriptions(self, query_params): + self.params = query_params + query_data = {} + logger.debug("Start QueryMultiSubscriptions get --> " + "Check for filters in query params" % self.params) + for query, value in self.params.iteritems(): + if query in const.NSDM_NOTIFICATION_FILTERS and value: + query_data[query + '__icontains'] = json.dumps(list(set(value))) + # Query the database with filters if the request + # has fields in request params, else fetch all records + if query_data: + subscriptions = NsdmSubscriptionModel.objects.filter(**query_data) + else: + subscriptions = NsdmSubscriptionModel.objects.all() + if not subscriptions.exists(): + raise ResourceNotFoundException("Subscriptions doesn't exist") + return [self.fill_resp_data(subscription) + for subscription in subscriptions] + + def check_callbackuri_connection(self): + logger.debug("Create Subscription --> Test Callback URI --" + "Sending GET request to %s" % self.callback_uri) + try: + response = requests.get(self.callback_uri, timeout=2) + if response.status_code != status.HTTP_204_NO_CONTENT: + raise GenericparserException("callbackUri %s returns %s status " + "code." % (self.callback_uri, + response.status_code)) + except Exception: + raise GenericparserException("callbackUri %s didn't return 204 status" + "code." % self.callback_uri) + + def fill_resp_data(self, subscription): + subscription_filter = dict() + for filter_type in const.NSDM_NOTIFICATION_FILTERS: + subscription_filter[filter_type] = \ + ast.literal_eval(subscription.__dict__[filter_type]) + resp_data = { + 'id': subscription.subscriptionid, + 'callbackUri': subscription.callback_uri, + 'filter': subscription_filter, + '_links': json.loads(subscription.links) + } + return resp_data + + def create(self, data): + logger.debug("Start Create Subscription... ") + self.filter = ignore_case_get(data, "filter", {}) + self.callback_uri = ignore_case_get(data, "callbackUri") + self.authentication = ignore_case_get(data, "authentication", {}) + self.subscription_id = str(uuid.uuid4()) + self.check_callbackuri_connection() + self.check_valid_auth_info() + self.check_filter_types() + self.check_valid() + self.save_db() + subscription = \ + NsdmSubscriptionModel.objects.get( + subscriptionid=self.subscription_id) + return self.fill_resp_data(subscription) + + def check_filter_types(self): + # Check if both nsdId and nsdInfoId + # or pnfdId and pnfdInfoId are present + logger.debug("Create Subscription --> Validating Filters... ") + if self.filter and \ + self.filter.get("nsdId", "") and \ + self.filter.get("nsdInfoId", ""): + raise NsdmBadRequestException("Notification Filter should contain" + " either nsdId or nsdInfoId") + if self.filter and \ + self.filter.get("pnfdId", "") and \ + self.filter.get("pnfdInfoIds", ""): + raise NsdmBadRequestException("Notification Filter should contain" + " either pnfdId or pnfdInfoIds") + + def check_valid_auth_info(self): + logger.debug("Create Subscription --> Validating Auth " + "details if provided... ") + if self.authentication.get("paramsBasic", {}) and \ + const.BASIC not in self.authentication.get("authType", ''): + raise NsdmBadRequestException('Auth type should be ' + const.BASIC) + if self.authentication.get("paramsOauth2ClientCredentials", {}) and \ + const.OAUTH2_CLIENT_CREDENTIALS not in \ + self.authentication.get("authType", ''): + raise NsdmBadRequestException('Auth type should ' + 'be ' + const.OAUTH2_CLIENT_CREDENTIALS) + if const.BASIC in self.authentication.get("authType", '') and \ + "paramsBasic" in self.authentication.keys() and \ + not is_filter_type_equal(PARAMSBASICKEYS, + self.authentication. + get("paramsBasic").keys()): + raise NsdmBadRequestException('userName and password needed ' + 'for ' + const.BASIC) + if const.OAUTH2_CLIENT_CREDENTIALS in \ + self.authentication.get("authType", '') and \ + "paramsOauth2ClientCredentials" in \ + self.authentication.keys() and \ + not is_filter_type_equal(PARAMSOAUTH2CLIENTCREDENTIALSKEYS, + self.authentication. + get("paramsOauth2ClientCredentials") + .keys()): + raise NsdmBadRequestException('clientId, clientPassword and ' + 'tokenEndpoint required ' + 'for ' + const.OAUTH2_CLIENT_CREDENTIALS) + + def check_filter_exists(self, subscription): + for filter_type in const.NSDM_NOTIFICATION_FILTERS: + if not is_filter_type_equal(self.filter.get(filter_type, []), + ast.literal_eval( + getattr(subscription, + filter_type))): + return False + return True + + def check_valid(self): + logger.debug("Create Subscription --> Checking DB if " + "same subscription exists already exists... ") + subscriptions = \ + NsdmSubscriptionModel.objects.filter( + callback_uri=self.callback_uri) + if not subscriptions.exists(): + return + for subscription in subscriptions: + if self.check_filter_exists(subscription): + raise NsdmDuplicateSubscriptionException( + "Already Subscription exists with the " + "same callbackUri and filter") + + def save_db(self): + logger.debug("Create Subscription --> Saving the subscription " + "%s to the database" % self.subscription_id) + links = { + "self": { + "href": + const.NSDM_SUBSCRIPTION_ROOT_URI + self.subscription_id + } + } + subscription_save_db = { + "subscriptionid": self.subscription_id, + "callback_uri": self.callback_uri, + "auth_info": self.authentication, + "links": json.dumps(links) + } + for filter_type in const.NSDM_NOTIFICATION_FILTERS: + subscription_save_db[filter_type] = json.dumps( + list(set(self.filter.get(filter_type, [])))) + NsdmSubscriptionModel.objects.create(**subscription_save_db) + logger.debug('Create Subscription[%s] success', self.subscription_id) |