feature 7919 - Subscription API for OSS/BSS management systems
[osm/NBI.git] / osm_nbi / subscription_topics.py
1 # Copyright 2020 Preethika P(Tata Elxsi)
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 __author__ = "Preethika P,preethika.p@tataelxsi.co.in"
17
18
19 import requests
20 from osm_nbi.base_topic import BaseTopic, EngineException
21 from osm_nbi.validation import subscription
22
23
24 class CommonSubscriptions(BaseTopic):
25 topic = "subscriptions"
26 topic_msg = None
27
28 def format_on_new(self, content, project_id=None, make_public=False):
29 super().format_on_new(content, project_id=project_id, make_public=make_public)
30
31 # TODO check how to release Engine.write_lock during the check
32 def _check_endpoint(url, auth):
33 """
34 Checks if the notification endpoint is valid
35 :param url: the notification end
36 :param auth: contains the aunthentication details with type basic
37 """
38 try:
39 if auth is None:
40 response = requests.get(url, timeout=5)
41 if response.status_code != 204:
42 raise EngineException("Cannot access to the notification URL '{}',received {}: {}"
43 .format(url, response.status_code, response.content))
44 elif auth["authType"] == "basic":
45 username = auth["paramsBasic"].get("userName")
46 password = auth["paramsBasic"].get("password")
47 response = requests.get(url, auth=(username, password), timeout=5)
48 if response.status_code != 204:
49 raise EngineException("Cannot access to the notification URL '{}',received {}: {}"
50 .format(url, response.status_code, response.content))
51 except requests.exceptions.RequestException as e:
52 error_text = type(e).__name__ + ": " + str(e)
53 raise EngineException("Cannot access to the notification URL '{}': {}".format(url, error_text))
54 url = content["CallbackUri"]
55 auth = content.get("authentication")
56 _check_endpoint(url, auth)
57 content["schema_version"] = schema_version = "1.1"
58 if auth is not None and auth["authType"] == "basic":
59 if content["authentication"]["paramsBasic"].get("password"):
60 content["authentication"]["paramsBasic"]["password"] = \
61 self.db.encrypt(content["authentication"]["paramsBasic"]["password"],
62 schema_version=schema_version, salt=content["_id"])
63 return None
64
65 def new(self, rollback, session, indata=None, kwargs=None, headers=None):
66 """
67 Uses BaseTopic.new to create entry into db
68 Once entry is made into subscriptions,mapper function is invoked
69 """
70 _id, op_id = BaseTopic.new(self, rollback, session, indata=indata, kwargs=kwargs, headers=headers)
71 rollback.append({"topic": "mapped_subscriptions", "operation": "del_list", "filter": {"reference": _id}})
72 self._subscription_mapper(_id, indata, table="mapped_subscriptions")
73 return _id, op_id
74
75 def delete_extra(self, session, _id, db_content, not_send_msg=None):
76 """
77 Deletes the mapped_subscription entry for this particular subscriber
78 :param _id: subscription_id deleted
79 """
80 super().delete_extra(session, _id, db_content, not_send_msg)
81 filter_q = {}
82 filter_q["reference"] = _id
83 self.db.del_list("mapped_subscriptions", filter_q)
84
85
86 class NslcmSubscriptionsTopic(CommonSubscriptions):
87 schema_new = subscription
88
89 def _subscription_mapper(self, _id, data, table):
90 """
91 Performs data transformation on subscription request
92 :param data: data to be trasformed
93 :param table: table in which transformed data are inserted
94 """
95 formatted_data = []
96 formed_data = {"reference": data.get("_id"),
97 "CallbackUri": data.get("CallbackUri")}
98 if data.get("authentication"):
99 formed_data.update({"authentication": data.get("authentication")})
100 if data.get("filter"):
101 if data["filter"].get("nsInstanceSubscriptionFilter"):
102 key = list(data["filter"]["nsInstanceSubscriptionFilter"].keys())[0]
103 identifier = data["filter"]["nsInstanceSubscriptionFilter"][key]
104 formed_data.update({"identifier": identifier})
105 if data["filter"].get("notificationTypes"):
106 for elem in data["filter"].get("notificationTypes"):
107 update_dict = formed_data.copy()
108 update_dict["notificationType"] = elem
109 if elem == "NsIdentifierCreationNotification":
110 update_dict["operationTypes"] = "INSTANTIATE"
111 update_dict["operationStates"] = "ANY"
112 formatted_data.append(update_dict)
113 elif elem == "NsIdentifierDeletionNotification":
114 update_dict["operationTypes"] = "TERMINATE"
115 update_dict["operationStates"] = "ANY"
116 formatted_data.append(update_dict)
117 elif elem == "NsLcmOperationOccurrenceNotification":
118 if "operationTypes" in data["filter"].keys():
119 update_dict["operationTypes"] = data["filter"]["operationTypes"]
120 else:
121 update_dict["operationTypes"] = "ANY"
122 if "operationStates" in data["filter"].keys():
123 update_dict["operationStates"] = data["filter"]["operationStates"]
124 else:
125 update_dict["operationStates"] = "ANY"
126 formatted_data.append(update_dict)
127 elif elem == "NsChangeNotification":
128 if "nsComponentTypes" in data["filter"].keys():
129 update_dict["nsComponentTypes"] = data["filter"]["nsComponentTypes"]
130 else:
131 update_dict["nsComponentTypes"] = "ANY"
132 if "lcmOpNameImpactingNsComponent" in data["filter"].keys():
133 update_dict["lcmOpNameImpactingNsComponent"] = \
134 data["filter"]["lcmOpNameImpactingNsComponent"]
135 else:
136 update_dict["lcmOpNameImpactingNsComponent"] = "ANY"
137 if "lcmOpOccStatusImpactingNsComponent" in data["filter"].keys():
138 update_dict["lcmOpOccStatusImpactingNsComponent"] = \
139 data["filter"]["lcmOpOccStatusImpactingNsComponent"]
140 else:
141 update_dict["lcmOpOccStatusImpactingNsComponent"] = "ANY"
142 formatted_data.append(update_dict)
143 self.db.create_list(table, formatted_data)
144 return None