1 # -------------------------------------------------------------------------
2 # Copyright (c) 2020 Huawei Intellectual Property
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # -------------------------------------------------------------------------
20 from requests.auth import HTTPBasicAuth
22 from osdf.utils.mdc_utils import mdc_from_json
23 from osdf.logging.osdf_logging import MH, audit_log, error_log, debug_log
25 from sklearn import preprocessing
28 BASE_DIR = os.path.dirname(__file__)
33 This values will need to deleted..
34 only added for the debug purpose
36 # DNS server and standard port of AAI..
37 # TODO: read the port from the configuration and add to DNS
38 aai_host = "https://aai.api.simpledemo.onap.org:8443"
39 audit_log.info("base directory")
40 audit_log.info(BASE_DIR)
42 "X-TransactionId": "9999",
44 "Accept": "application/json",
45 "Content-Type": "application/json",
49 def isCrossONAPLink(self, logical_link):
51 This method checks if cross link is cross onap
55 for relationship in logical_link["relationship-list"]["relationship"]:
56 if relationship["related-to"] == "ext-aai-network":
60 def getLinksName(self, routes,initial_start_edge,initial_end_edge, mappingTable):
64 for i in range(0, len(routes[0]['x'])):
66 # listOfLinks.append(self.fetchLogicalLinks(initial_start_edge[i], initial_end_edge[i], mappingTable))
67 listOfLinks.append(mappingTable[initial_start_edge[i] + ":" + initial_end_edge[i]])
71 # def search(self, ip1, ip2, dic):
72 # if ip1 == "" or ip2 == "":
75 # string = ip1 + ":" + ip2
78 # def fetchLogicalLinks(self, initial_start_edge, initial_end_edge, mappingTable):
79 # link_name=self.search(initial_start_edge, initial_end_edge, mappingTable)
83 # def fetchLogicalLinks(self, initial_start_edge, initial_end_edge, mappingTable):
84 # return mappingTable[initial_start_edge + ":" + initial_end_edge]
86 def solve(self, mzn_model, dzn_data):
87 return pymzn.minizinc(mzn=mzn_model, data=dzn_data)
89 def getLinks(self, mzn_model, dzn_data, initial_start_edge,initial_end_edge, mappingTable):
90 routes = self.solve(mzn_model, dzn_data)
91 audit_log.info("mocked minizinc solution====>")
92 audit_log.info(routes)
94 converted_links=self.getLinksName(routes, initial_start_edge,initial_end_edge, mappingTable)
95 audit_log.info("converted links===>")
96 audit_log.info(converted_links)
97 return converted_links
99 def addition(self, data):
100 relationship = data["relationship-list"]["relationship"]
102 for index, eachItem in enumerate(relationship):
103 if index == len(relationship) - 1:
104 res += eachItem["accessNodeId"]
106 res += eachItem["accessNodeId"] + ":"
108 return data["link-name"], res
110 def createMapTable(self, logical_links):
111 result = map(self.addition, logical_links)
115 for eachItem in result:
116 parseTemplate[eachItem[1]] = eachItem[0]
117 audit_log.info("mapping table")
118 audit_log.info(parseTemplate)
121 def build_dzn_data(self, src_access_node_id, dst_access_node_id):
124 logical_links = self.get_logical_links()
125 audit_log.info("mocked response of AAI received (logical links) successful===>")
126 audit_log.info(logical_links)
128 mappingTable = self.createMapTable(logical_links)
129 # take the logical link where both the p-interface in same onap
130 if logical_links is not None:
131 for logical_link in logical_links:
132 if not self.isCrossONAPLink(logical_link):
133 # link is in local ONAP
134 relationship = logical_link["relationship-list"]["relationship"]
136 relationshipStartNode = relationship[0]
137 relationshipStartNodeID = relationshipStartNode["related-link"].split("/")[-1]
138 start_accessNodeId = relationshipStartNodeID.split("-")[-3]
139 Edge_Start.append(start_accessNodeId)
141 relationshipEndtNode = relationship[1]
142 relationshipEndNodeID = relationshipEndtNode["related-link"].split("/")[-1]
143 end_accessNodeId = relationshipEndNodeID.split("-")[-3]
144 Edge_End.append(end_accessNodeId)
146 audit_log.info("edge start and end array of i/p address are===>")
147 audit_log.info(Edge_Start)
148 audit_log.info(Edge_End)
149 # labeling ip to number for mapping
150 le = preprocessing.LabelEncoder()
151 le.fit(Edge_Start + Edge_End)
153 dzn_start_edge = le.transform(Edge_Start)
155 final_dzn_start_arr = []
156 for i in range(0, len(dzn_start_edge)):
157 final_dzn_start_arr.append(dzn_start_edge[i])
159 final_dzn_end_arr = []
160 dzn_end_edge = le.transform(Edge_End)
161 for j in range(0, len(dzn_end_edge)):
162 final_dzn_end_arr.append(dzn_end_edge[j])
164 audit_log.info("start and end array that passed in dzn_data===>")
165 audit_log.info(final_dzn_start_arr)
166 audit_log.info(final_dzn_end_arr)
169 for k in range(0, len(final_dzn_start_arr)):
172 audit_log.info("src_access_node_id")
173 audit_log.info(src_access_node_id)
174 source= le.transform([src_access_node_id])
175 audit_log.info("vallue of source===>")
176 audit_log.info(source)
177 if source in final_dzn_start_arr :
179 audit_log.info("source node")
180 audit_log.info(start)
182 audit_log.info("dst_access_node_id")
183 audit_log.info(dst_access_node_id)
184 destination= le.transform([dst_access_node_id])
185 if destination in final_dzn_end_arr :
187 audit_log.info("destination node")
189 # data to be prepared in the below format:
191 'N': self.total_node(final_dzn_start_arr + final_dzn_end_arr),
192 'M': len(final_dzn_start_arr),
193 'Edge_Start': final_dzn_start_arr,
194 'Edge_End': final_dzn_end_arr,
199 # can not do reverse mapping outside of this scope, so doing here
200 audit_log.info("reverse mapping after prepared dzn_data")
201 initial_start_edge=le.inverse_transform(final_dzn_start_arr)
202 initial_end_edge=le.inverse_transform(final_dzn_end_arr)
203 audit_log.info(initial_start_edge)
204 audit_log.info(initial_end_edge)
205 return dzn_data, initial_start_edge,initial_end_edge, mappingTable
207 def total_node(self, node):
209 for i in range(0, len(node)):
211 total_node = len(nodeSet)
214 def getRoute(self, request):
220 routeInfo = request["routeInfo"]["routeRequests"]
221 routeRequest = routeInfo[0]
222 src_access_node_id = routeRequest["srcPort"]["accessNodeId"]
223 dst_access_node_id = routeRequest["dstPort"]["accessNodeId"]
225 dzn_data, initial_start_edge, initial_end_edge, mappingTable = self.build_dzn_data(src_access_node_id, dst_access_node_id )
226 #mzn_model = "/home/root1/Videos/projects/osdf/test/functest/simulators/osdf/optimizers/routeopt/route_opt.mzn"
227 mzn_model = os.path.join(BASE_DIR, 'route_opt.mzn')
229 routeSolutions = self.getLinks(mzn_model, dzn_data, initial_start_edge,initial_end_edge, mappingTable)
232 "requestId": request["requestInfo"]["requestId"],
233 "transactionId": request["requestInfo"]["transactionId"],
234 "statusMessage": " ",
235 "requestStatus": "accepted",
236 "solutions": routeSolutions
239 def get_logical_links(self):
241 This method returns list of all cross ONAP links
242 from /aai/v14/network/logical-links?operation-status="Up"
243 :return: logical-links[]
245 logical_link_url = "/aai/v13/network/logical-links?operational-status=up"
246 aai_req_url = self.aai_host + logical_link_url
247 response = requests.get(aai_req_url,headers=self.aai_headers,auth=HTTPBasicAuth("AAI", "AAI"),verify=False)
248 if response.status_code == 200:
249 return response.json()