1 # Copyright 2020 Preethika P(Tata Elxsi)
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
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 __author__
= "Preethika P,preethika.p@tataelxsi.co.in"
19 from osm_nbi
.base_topic
import BaseTopic
, EngineException
20 from osm_nbi
.validation
import subscription
21 from http
import HTTPStatus
24 class CommonSubscriptions(BaseTopic
):
25 topic
= "subscriptions"
28 def _subscription_mapper(self
, _id
, data
, table
):
30 Performs data transformation on subscription request
31 :param data: data to be trasformed
32 :param table: table in which transformed data are inserted
36 def format_subscription(self
, subs_data
):
38 Brings lexicographical order for list items at any nested level. For subscriptions max level of nesting is 4.
39 :param subs_data: Subscription data to be ordered.
42 if isinstance(subs_data
, dict):
43 for key
in subs_data
.keys():
45 if isinstance(subs_data
[key
], list):
49 self
.format_subscription(subs_data
[key
])
52 def check_conflict_on_new(self
, session
, content
):
54 Two subscriptions are equal if Auth username, CallbackUri and filter are same.
55 :param session: Session object.
56 :param content: Subscription data.
57 :return: None if no conflict otherwise, raises an exception.
59 # Get all subscriptions from db table subscriptions and compare.
60 self
.format_subscription(content
)
61 filter_dict
= {"CallbackUri": content
["CallbackUri"]}
62 if content
.get("authentication"):
63 if content
["authentication"].get("authType") == "basic":
64 filter_dict
["authentication.authType"] = "basic"
65 # elif add other authTypes here
67 filter_dict
["authentication"] = None # For Items without authentication
68 existing_subscriptions
= self
.db
.get_list("subscriptions", q_filter
=filter_dict
)
71 content
.get("authentication")
72 and content
["authentication"].get("authType") == "basic"
74 new_sub_pwd
= content
["authentication"]["paramsBasic"]["password"]
75 content
["authentication"]["paramsBasic"].pop("password", None)
76 for existing_subscription
in existing_subscriptions
:
77 sub_id
= existing_subscription
.pop("_id", None)
78 existing_subscription
.pop("_admin", None)
79 existing_subscription
.pop("schema_version", None)
81 existing_subscription
.get("authentication")
82 and existing_subscription
["authentication"].get("authType") == "basic"
84 existing_subscription
["authentication"]["paramsBasic"].pop(
87 # self.logger.debug(existing_subscription)
88 if existing_subscription
== content
:
89 raise EngineException(
90 "Subscription already exists with id: {}".format(sub_id
),
94 content
["authentication"]["paramsBasic"]["password"] = new_sub_pwd
97 def format_on_new(self
, content
, project_id
=None, make_public
=False):
98 super().format_on_new(content
, project_id
=project_id
, make_public
=make_public
)
100 # TODO check how to release Engine.write_lock during the check
101 def _check_endpoint(url
, auth
):
103 Checks if the notification endpoint is valid
104 :param url: the notification end
105 :param auth: contains the authentication details with type basic
109 response
= requests
.get(url
, timeout
=5)
110 if response
.status_code
!= HTTPStatus
.NO_CONTENT
:
111 raise EngineException(
112 "Cannot access to the notification URL '{}',received {}: {}".format(
113 url
, response
.status_code
, response
.content
116 elif auth
["authType"] == "basic":
117 username
= auth
["paramsBasic"].get("userName")
118 password
= auth
["paramsBasic"].get("password")
119 response
= requests
.get(url
, auth
=(username
, password
), timeout
=5)
120 if response
.status_code
!= HTTPStatus
.NO_CONTENT
:
121 raise EngineException(
122 "Cannot access to the notification URL '{}',received {}: {}".format(
123 url
, response
.status_code
, response
.content
126 except requests
.exceptions
.RequestException
as e
:
127 error_text
= type(e
).__name
__ + ": " + str(e
)
128 raise EngineException(
129 "Cannot access to the notification URL '{}': {}".format(
134 url
= content
["CallbackUri"]
135 auth
= content
.get("authentication")
136 _check_endpoint(url
, auth
)
137 content
["schema_version"] = schema_version
= "1.1"
138 if auth
is not None and auth
["authType"] == "basic":
139 if content
["authentication"]["paramsBasic"].get("password"):
140 content
["authentication"]["paramsBasic"]["password"] = self
.db
.encrypt(
141 content
["authentication"]["paramsBasic"]["password"],
142 schema_version
=schema_version
,
147 def new(self
, rollback
, session
, indata
=None, kwargs
=None, headers
=None):
149 Uses BaseTopic.new to create entry into db
150 Once entry is made into subscriptions,mapper function is invoked
152 _id
, op_id
= BaseTopic
.new(
153 self
, rollback
, session
, indata
=indata
, kwargs
=kwargs
, headers
=headers
157 "topic": "mapped_subscriptions",
158 "operation": "del_list",
159 "filter": {"reference": _id
},
162 self
._subscription
_mapper
(_id
, indata
, table
="mapped_subscriptions")
165 def delete_extra(self
, session
, _id
, db_content
, not_send_msg
=None):
167 Deletes the mapped_subscription entry for this particular subscriber
168 :param _id: subscription_id deleted
170 super().delete_extra(session
, _id
, db_content
, not_send_msg
)
171 filter_q
= {"reference": _id
}
172 self
.db
.del_list("mapped_subscriptions", filter_q
)
175 class NslcmSubscriptionsTopic(CommonSubscriptions
):
176 schema_new
= subscription
178 def _subscription_mapper(self
, _id
, data
, table
):
180 Performs data transformation on subscription request
181 :param data: data to be trasformed
182 :param table: table in which transformed data are inserted
186 "reference": data
.get("_id"),
187 "CallbackUri": data
.get("CallbackUri"),
189 if data
.get("authentication"):
190 formed_data
.update({"authentication": data
.get("authentication")})
191 if data
.get("filter"):
192 if data
["filter"].get("nsInstanceSubscriptionFilter"):
193 key
= list(data
["filter"]["nsInstanceSubscriptionFilter"].keys())[0]
194 identifier
= data
["filter"]["nsInstanceSubscriptionFilter"][key
]
195 formed_data
.update({"identifier": identifier
})
196 if data
["filter"].get("notificationTypes"):
197 for elem
in data
["filter"].get("notificationTypes"):
198 update_dict
= formed_data
.copy()
199 update_dict
["notificationType"] = elem
200 if elem
== "NsIdentifierCreationNotification":
201 update_dict
["operationTypes"] = "INSTANTIATE"
202 update_dict
["operationStates"] = "ANY"
203 formatted_data
.append(update_dict
)
204 elif elem
== "NsIdentifierDeletionNotification":
205 update_dict
["operationTypes"] = "TERMINATE"
206 update_dict
["operationStates"] = "ANY"
207 formatted_data
.append(update_dict
)
208 elif elem
== "NsLcmOperationOccurrenceNotification":
209 if "operationTypes" in data
["filter"].keys():
210 update_dict
["operationTypes"] = data
["filter"][
214 update_dict
["operationTypes"] = "ANY"
215 if "operationStates" in data
["filter"].keys():
216 update_dict
["operationStates"] = data
["filter"][
220 update_dict
["operationStates"] = "ANY"
221 formatted_data
.append(update_dict
)
222 elif elem
== "NsChangeNotification":
223 if "nsComponentTypes" in data
["filter"].keys():
224 update_dict
["nsComponentTypes"] = data
["filter"][
228 update_dict
["nsComponentTypes"] = "ANY"
229 if "lcmOpNameImpactingNsComponent" in data
["filter"].keys():
230 update_dict
["lcmOpNameImpactingNsComponent"] = data
[
232 ]["lcmOpNameImpactingNsComponent"]
234 update_dict
["lcmOpNameImpactingNsComponent"] = "ANY"
236 "lcmOpOccStatusImpactingNsComponent"
237 in data
["filter"].keys()
239 update_dict
["lcmOpOccStatusImpactingNsComponent"] = data
[
241 ]["lcmOpOccStatusImpactingNsComponent"]
243 update_dict
["lcmOpOccStatusImpactingNsComponent"] = "ANY"
244 formatted_data
.append(update_dict
)
245 self
.db
.create_list(table
, formatted_data
)