1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
# 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 os
import requests
import uuid
from collections import Counter
from rest_framework import status
from catalog.packages import const
from catalog.pub.database.models import VnfPkgSubscriptionModel
from catalog.pub.exceptions import VnfPkgSubscriptionException, VnfPkgDuplicateSubscriptionException
from catalog.pub.utils.values import ignore_case_get
logger = logging.getLogger(__name__)
ROOT_FILTERS = {
"notificationTypes": "notification_types",
"vnfdId": "vnfd_id",
"vnfPkgId": "vnf_pkg_id",
"operationalState": "operation_states",
"usageState": "usage_states"
}
def is_filter_type_equal(new_filter, existing_filter):
return Counter(new_filter) == Counter(existing_filter)
class CreateSubscription(object):
def __init__(self, data):
self.data = data
self.filter = ignore_case_get(self.data, "filters", {})
self.callback_uri = ignore_case_get(self.data, "callbackUri")
self.authentication = ignore_case_get(self.data, "authentication", {})
self.notification_types = ignore_case_get(self.filter, "notificationTypes", [])
self.operation_states = ignore_case_get(self.filter, "operationalState", [])
self.usage_states = ignore_case_get(self.filter, "usageState", [])
self.vnfd_id = ignore_case_get(self.filter, "vnfdId", [])
self.vnf_pkg_id = ignore_case_get(self.filter, "vnfPkgId", [])
self.vnf_products_from_provider = \
ignore_case_get(self.filter, "vnfProductsFromProviders", {})
def check_callbackuri_connection(self):
logger.debug("SubscribeNotification-post::> 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 VnfPkgSubscriptionException("callbackUri %s returns %s status "
"code." % (self.callback_uri, response.status_code))
except Exception:
raise VnfPkgSubscriptionException("callbackUri %s didn't return 204 status"
"code." % self.callback_uri)
def do_biz(self):
self.subscription_id = str(uuid.uuid4())
self.check_callbackuri_connection()
self.check_valid_auth_info()
self.check_valid()
self.save_db()
subscription = VnfPkgSubscriptionModel.objects.get(subscription_id=self.subscription_id)
if subscription:
return subscription.toDict()
def check_valid_auth_info(self):
logger.debug("SubscribeNotification--post::> Validating Auth "
"details if provided")
if self.authentication.get("paramsBasic", {}) and \
const.BASIC not in self.authentication.get("authType"):
raise VnfPkgSubscriptionException('Auth type should be ' + const.BASIC)
if self.authentication.get("paramsOauth2ClientCredentials", {}) and \
const.OAUTH2_CLIENT_CREDENTIALS not in self.authentication.get("authType"):
raise VnfPkgSubscriptionException('Auth type should be ' + const.OAUTH2_CLIENT_CREDENTIALS)
def check_filter_exists(self, sub):
# Check the usage states, operationStates
for filter_type in ["operation_states", "usage_states"]:
if not is_filter_type_equal(getattr(self, filter_type),
ast.literal_eval(getattr(sub, filter_type))):
return False
# If all the above types are same then check id filters
for id_filter in ["vnfd_id", "vnf_pkg_id"]:
if not is_filter_type_equal(getattr(self, id_filter),
ast.literal_eval(getattr(sub, id_filter))):
return False
return True
def check_valid(self):
logger.debug("SubscribeNotification--post::> Checking DB if "
"callbackUri already exists")
subscriptions = VnfPkgSubscriptionModel.objects.filter(callback_uri=self.callback_uri)
if not subscriptions.exists():
return True
for subscription in subscriptions:
if self.check_filter_exists(subscription):
raise VnfPkgDuplicateSubscriptionException(
"Already Subscription (%s) exists with the "
"same callbackUri and filter" % subscription.subscription_id)
return True
def save_db(self):
logger.debug("SubscribeNotification--post::> Saving the subscription "
"%s to the database" % self.subscription_id)
links = {
"self": {
"href": os.path.join(const.VNFPKG_SUBSCRIPTION_ROOT_URI, self.subscription_id)
}
}
VnfPkgSubscriptionModel.objects.create(
subscription_id=self.subscription_id,
callback_uri=self.callback_uri,
notification_types=json.dumps(self.notification_types),
auth_info=json.dumps(self.authentication),
usage_states=json.dumps(self.usage_states),
operation_states=json.dumps(self.operation_states),
vnf_products_from_provider=json.dumps(self.vnf_products_from_provider),
vnfd_id=json.dumps(self.vnfd_id),
vnf_pkg_id=json.dumps(self.vnf_pkg_id),
links=json.dumps(links))
logger.debug('Create Subscription[%s] success', self.subscription_id)
|