1 # Copyright (C) 2019 Verizon. All Rights Reserved
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
21 from collections import Counter
23 from rest_framework import status
25 from genericparser.packages import const
26 from genericparser.pub.database.models import NsdmSubscriptionModel
27 from genericparser.pub.exceptions import GenericparserException, \
28 ResourceNotFoundException, \
29 NsdmBadRequestException, NsdmDuplicateSubscriptionException
30 from genericparser.pub.utils.values import ignore_case_get
32 logger = logging.getLogger(__name__)
34 PARAMSBASICKEYS = ["userName", "password"]
36 PARAMSOAUTH2CLIENTCREDENTIALSKEYS = ["clientId", "clientPassword",
40 def is_filter_type_equal(new_filter, existing_filter):
41 return Counter(list(set(new_filter))) == Counter(existing_filter)
44 class NsdmSubscription:
49 def query_single_subscription(self, subscription_id):
50 logger.debug("Start Query Subscription... ")
52 NsdmSubscriptionModel.objects.filter(
53 subscriptionid=subscription_id)
54 if not subscription.exists():
55 raise ResourceNotFoundException(
56 "Subscription(%s) doesn't exists" % subscription_id)
57 logger.debug("Subscription found... ")
58 return self.fill_resp_data(subscription[0])
60 def delete_single_subscription(self, subscription_id):
61 logger.debug("Start Delete Subscription... ")
63 NsdmSubscriptionModel.objects.filter(
64 subscriptionid=subscription_id)
65 if not subscription.exists():
66 raise ResourceNotFoundException(
67 "Subscription(%s) doesn't exists" % subscription_id)
69 logger.debug("Deleted Subscription... ")
71 def query_multi_subscriptions(self, query_params):
72 self.params = query_params
74 logger.debug("Start QueryMultiSubscriptions get --> "
75 "Check for filters in query params" % self.params)
76 for query, value in self.params.iteritems():
77 if query in const.NSDM_NOTIFICATION_FILTERS and value:
78 query_data[query + '__icontains'] = json.dumps(list(set(value)))
79 # Query the database with filters if the request
80 # has fields in request params, else fetch all records
82 subscriptions = NsdmSubscriptionModel.objects.filter(**query_data)
84 subscriptions = NsdmSubscriptionModel.objects.all()
85 if not subscriptions.exists():
86 raise ResourceNotFoundException("Subscriptions doesn't exist")
87 return [self.fill_resp_data(subscription)
88 for subscription in subscriptions]
90 def check_callbackuri_connection(self):
91 logger.debug("Create Subscription --> Test Callback URI --"
92 "Sending GET request to %s" % self.callback_uri)
94 response = requests.get(self.callback_uri, timeout=2)
95 if response.status_code != status.HTTP_204_NO_CONTENT:
96 raise GenericparserException("callbackUri %s returns %s status "
97 "code." % (self.callback_uri,
98 response.status_code))
100 raise GenericparserException("callbackUri %s didn't return 204 status"
101 "code." % self.callback_uri)
103 def fill_resp_data(self, subscription):
104 subscription_filter = dict()
105 for filter_type in const.NSDM_NOTIFICATION_FILTERS:
106 subscription_filter[filter_type] = \
107 ast.literal_eval(subscription.__dict__[filter_type])
109 'id': subscription.subscriptionid,
110 'callbackUri': subscription.callback_uri,
111 'filter': subscription_filter,
112 '_links': json.loads(subscription.links)
116 def create(self, data):
117 logger.debug("Start Create Subscription... ")
118 self.filter = ignore_case_get(data, "filter", {})
119 self.callback_uri = ignore_case_get(data, "callbackUri")
120 self.authentication = ignore_case_get(data, "authentication", {})
121 self.subscription_id = str(uuid.uuid4())
122 self.check_callbackuri_connection()
123 self.check_valid_auth_info()
124 self.check_filter_types()
128 NsdmSubscriptionModel.objects.get(
129 subscriptionid=self.subscription_id)
130 return self.fill_resp_data(subscription)
132 def check_filter_types(self):
133 # Check if both nsdId and nsdInfoId
134 # or pnfdId and pnfdInfoId are present
135 logger.debug("Create Subscription --> Validating Filters... ")
137 self.filter.get("nsdId", "") and \
138 self.filter.get("nsdInfoId", ""):
139 raise NsdmBadRequestException("Notification Filter should contain"
140 " either nsdId or nsdInfoId")
142 self.filter.get("pnfdId", "") and \
143 self.filter.get("pnfdInfoIds", ""):
144 raise NsdmBadRequestException("Notification Filter should contain"
145 " either pnfdId or pnfdInfoIds")
147 def check_valid_auth_info(self):
148 logger.debug("Create Subscription --> Validating Auth "
149 "details if provided... ")
150 if self.authentication.get("paramsBasic", {}) and \
151 const.BASIC not in self.authentication.get("authType", ''):
152 raise NsdmBadRequestException('Auth type should be ' + const.BASIC)
153 if self.authentication.get("paramsOauth2ClientCredentials", {}) and \
154 const.OAUTH2_CLIENT_CREDENTIALS not in \
155 self.authentication.get("authType", ''):
156 raise NsdmBadRequestException('Auth type should '
157 'be ' + const.OAUTH2_CLIENT_CREDENTIALS)
158 if const.BASIC in self.authentication.get("authType", '') and \
159 "paramsBasic" in self.authentication.keys() and \
160 not is_filter_type_equal(PARAMSBASICKEYS,
161 self.authentication.get("paramsBasic").keys()):
162 raise NsdmBadRequestException('userName and password needed '
163 'for ' + const.BASIC)
164 if const.OAUTH2_CLIENT_CREDENTIALS in \
165 self.authentication.get("authType", '') and \
166 "paramsOauth2ClientCredentials" in \
167 self.authentication.keys() and \
168 not is_filter_type_equal(PARAMSOAUTH2CLIENTCREDENTIALSKEYS,
169 self.authentication.get("paramsOauth2ClientCredentials").keys()):
170 raise NsdmBadRequestException('clientId, clientPassword and '
171 'tokenEndpoint required '
172 'for ' + const.OAUTH2_CLIENT_CREDENTIALS)
174 def check_filter_exists(self, subscription):
175 for filter_type in const.NSDM_NOTIFICATION_FILTERS:
176 if not is_filter_type_equal(self.filter.get(filter_type, []),
178 getattr(subscription,
183 def check_valid(self):
184 logger.debug("Create Subscription --> Checking DB if "
185 "same subscription exists already exists... ")
187 NsdmSubscriptionModel.objects.filter(
188 callback_uri=self.callback_uri)
189 if not subscriptions.exists():
191 for subscription in subscriptions:
192 if self.check_filter_exists(subscription):
193 raise NsdmDuplicateSubscriptionException(
194 "Already Subscription exists with the "
195 "same callbackUri and filter")
198 logger.debug("Create Subscription --> Saving the subscription "
199 "%s to the database" % self.subscription_id)
203 const.NSDM_SUBSCRIPTION_ROOT_URI + self.subscription_id
206 subscription_save_db = {
207 "subscriptionid": self.subscription_id,
208 "callback_uri": self.callback_uri,
209 "auth_info": self.authentication,
210 "links": json.dumps(links)
212 for filter_type in const.NSDM_NOTIFICATION_FILTERS:
213 subscription_save_db[filter_type] = json.dumps(
214 list(set(self.filter.get(filter_type, []))))
215 NsdmSubscriptionModel.objects.create(**subscription_save_db)
216 logger.debug('Create Subscription[%s] success', self.subscription_id)