[SLICEANALYSIS] Filter data from AAI to avoid possible exceptions, remove null parame...
[dcaegen2/services.git] / components / slice-analysis-ms / src / main / java / org / onap / slice / analysis / ms / aai / AaiService.java
1 /*******************************************************************************
2  *  ============LICENSE_START=======================================================
3  *  slice-analysis-ms
4  *  ================================================================================
5  *   Copyright (C) 2021-2022 Wipro Limited.
6  *   Copyright (C) 2022 Huawei Canada Limited.
7  *   ==============================================================================
8  *     Licensed under the Apache License, Version 2.0 (the "License");
9  *     you may not use this file except in compliance with the License.
10  *     You may obtain a copy of the License at
11  *
12  *          http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *     Unless required by applicable law or agreed to in writing, software
15  *     distributed under the License is distributed on an "AS IS" BASIS,
16  *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *     See the License for the specific language governing permissions and
18  *     limitations under the License.
19  *     ============LICENSE_END=========================================================
20  *
21  *******************************************************************************/
22
23 package org.onap.slice.analysis.ms.aai;
24
25 import com.fasterxml.jackson.databind.ObjectMapper;
26
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Objects;
32
33 import org.json.JSONArray;
34 import org.json.JSONObject;
35 import org.onap.slice.analysis.ms.models.Configuration;
36 import org.onap.slice.analysis.ms.models.aai.ServiceInstance;
37 import org.onap.slice.analysis.ms.restclients.AaiRestClient;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.core.ParameterizedTypeReference;
42 import org.springframework.http.ResponseEntity;
43 import org.springframework.stereotype.Service;
44
45 /**
46  *
47  * Service for AAI interfaces
48  *
49  */
50 @Service
51 public class AaiService implements AaiInterface {
52
53     private static Logger log = LoggerFactory.getLogger(Configuration.class);
54
55     @Autowired
56     AaiRestClient restclient;
57
58     private static ObjectMapper objectMapper = new ObjectMapper();
59     private static String globalSubscriberId;
60     private static String subscriptionServiceType;
61     private static String aaiBaseUrl = Configuration.getInstance().getAaiUrl();
62
63     /**
64      * Fetches the details of a service
65      *
66      * @param snssai SNSSAI ID
67      * @return responseMap contains service details
68      */
69     public Map<String, String> fetchServiceDetails(String snssai) {
70         Map<String, String> responseMap = fetchSubscriberAndSubscriptionServiceType();
71         String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
72                 + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances";
73         log.info("serviceReqUrl {}", serviceReqUrl);
74         String serviceRole = "AN-NF";
75         try {
76             String serviceInstance =
77                     restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
78             JSONObject serviceInstanceJson = new JSONObject(serviceInstance);
79             JSONArray serviceInstanceList = serviceInstanceJson.getJSONArray("service-instance");
80             for (int i = 0; i < serviceInstanceList.length(); i++) {
81                 JSONObject serviceObj = serviceInstanceList.getJSONObject(i);
82                 if (serviceObj.has("environment-context") && serviceObj.getString("environment-context").equalsIgnoreCase(snssai)) {
83                     responseMap.put("sliceProfileId", serviceObj.getString("service-instance-id"));
84                 }
85             }
86
87             String serviceRoleReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
88                     + "/service-subscriptions/service-subscription/" + subscriptionServiceType
89                     + "/service-instances/?service-role=nssi&depth=2";
90             log.info("serviceRoleReqUrl {}", serviceRoleReqUrl);
91             String serviceInstanceForServiceRole =
92                     restclient.sendGetRequest(serviceRoleReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
93             JSONObject serviceInstanceForServiceRoleJson = new JSONObject(serviceInstanceForServiceRole);
94             JSONArray serviceInstanceListForServiceRole =
95                     serviceInstanceForServiceRoleJson.getJSONArray("service-instance");
96             for (int i = 0; i < serviceInstanceListForServiceRole.length(); i++) {
97                 JSONObject serviceObj = serviceInstanceListForServiceRole.getJSONObject(i);
98                 if (serviceObj.has("workload-context") && serviceObj.getString("workload-context").trim().equalsIgnoreCase(serviceRole)) {
99                     responseMap.put("ranNFNSSIId", serviceObj.getString("service-instance-id"));
100                 }
101             }
102         } catch (Exception e) {
103             log.info("Exception while fetching serviceDetails: " + e);
104         }
105         responseMap.put("sNSSAI", snssai);
106         log.info("subscriber details: " + responseMap);
107         return responseMap;
108     }
109
110     /**
111      * Fetches the current configuration of a Slice from AAI
112      *
113      * @param snssai SNSSAI ID
114      * @return responseMap contains slice configuration
115      */
116     public Map<String, Integer> fetchCurrentConfigurationOfSlice(String snssai) {
117         log.info("AAI fetch config Slice: " + aaiBaseUrl);
118         String serviceInstaneId = null;
119         String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
120                 + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances";
121         log.info("serviceReqUrl {}", serviceReqUrl);
122         Map<String, Integer> responseMap = new HashMap<String, Integer>();
123         try {
124             String serviceInstance =
125                     restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
126             JSONObject serviceInstanceJson = new JSONObject(serviceInstance);
127
128             JSONArray serviceInstanceList = serviceInstanceJson.getJSONArray("service-instance");
129             for (int i = 0; i < serviceInstanceList.length(); i++) {
130                 JSONObject serviceObj = serviceInstanceList.getJSONObject(i);
131                 if (serviceObj.has("environment-context") && serviceObj.getString("environment-context").equalsIgnoreCase(snssai)) {
132                     serviceInstaneId = serviceObj.getString("service-instance-id");
133                 }
134             }
135
136             String sliceProfileReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
137                     + "/service-subscriptions/service-subscription/" + subscriptionServiceType
138                     + "/service-instances/service-instance/" + serviceInstaneId + "/slice-profiles";
139             log.info("sliceProfileReqUrl {}", sliceProfileReqUrl);
140             String sliceProfile = restclient
141                     .sendGetRequest(sliceProfileReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
142             JSONObject sliceProfileJson = new JSONObject(sliceProfile);
143             JSONArray sliceProfileList = sliceProfileJson.getJSONArray("slice-profile");
144             for (int i = 0; i < sliceProfileList.length(); i++) {
145                 JSONObject sliceProfileObj = sliceProfileList.getJSONObject(i);
146                 responseMap.put("dLThptPerSlice", sliceProfileObj.getInt("exp-data-rate-UL"));
147                 responseMap.put("uLThptPerSlice", sliceProfileObj.getInt("exp-data-rate-DL"));
148                 break;
149             }
150             log.info("Slice configuration: " + responseMap);
151         } catch (Exception e) {
152             log.info("AAI Slice: " + e);
153         }
154         return responseMap;
155     }
156
157     /**
158      * Fetches the details of a subscriber and subscription Service
159      *
160      * @return responseMap contains details of subscriber and subscription service
161      */
162     public Map<String, String> fetchSubscriberAndSubscriptionServiceType() {
163
164         Map<String, String> responseMap = new HashMap<String, String>();
165
166         log.info("Get GlobalSubscriberId");
167         String subscriberReqUrl = aaiBaseUrl + "/business/customers";
168         log.info("subscriberReqUrl {}", subscriberReqUrl);
169         try {
170             String subscriberReq =
171                     restclient.sendGetRequest(subscriberReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
172             JSONObject subscriberReqJson = new JSONObject(subscriberReq);
173             JSONArray subscriberReqJsonList = subscriberReqJson.getJSONArray("customer");
174             for (int i = 0; i < subscriberReqJsonList.length(); i++) {
175                 JSONObject subscriberReqObj = subscriberReqJsonList.getJSONObject(i);
176                 globalSubscriberId = subscriberReqObj.getString("global-customer-id");
177                 responseMap.put("globalSubscriberId", globalSubscriberId);
178                 break;
179             }
180
181             log.info("Get subscriptionServiceType");
182             String subscriptionServiceReqUrl =
183                     aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId + "/service-subscriptions";
184             log.info("subscriptionServiceReqUrl: {}", subscriptionServiceReqUrl);
185             String subscriptionService = restclient
186                     .sendGetRequest(subscriptionServiceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
187             JSONObject subscriptionServiceJson = new JSONObject(subscriptionService);
188             JSONArray subscriptionServiceListJson = subscriptionServiceJson.getJSONArray("service-subscription");
189             for (int i = 0; i < subscriptionServiceListJson.length(); i++) {
190                 JSONObject subscriptionServiceObj = subscriptionServiceListJson.getJSONObject(i);
191                 subscriptionServiceType = subscriptionServiceObj.getString("service-type");
192                 responseMap.put("subscriptionServiceType", subscriptionServiceType);
193                 break;
194             }
195         } catch (Exception e) {
196             log.info("Exception while fetching subscriber and subscription: " + e);
197         }
198
199         log.info("responseMap: " + responseMap);
200         return responseMap;
201
202     }
203
204     /**
205      * Fetches the SNSSIs of a serviceInstanceId
206      *
207      * @param serviceInstanceId service instance ID
208      * @return snssaiList contains list of SNSSAIs
209      */
210     public List<String> getSnssaiList(String sliceInstanceId) {
211         fetchSubscriberAndSubscriptionServiceType();
212         List<String> allotedResource = new ArrayList<>();
213         List<String> sliceProfileList = new ArrayList<>();
214         List<String> snssaiList = new ArrayList<>();
215
216         log.info("fetch slice instance details");
217         String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
218                 + "/service-subscriptions/service-subscription/" + subscriptionServiceType
219                 + "/service-instances/service-instance/" + sliceInstanceId;
220         log.info("serviceReqUrl {}", serviceReqUrl);
221         try {
222             String serviceInstanceString =
223                     restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
224             ServiceInstance serviceInstance = objectMapper.readValue(serviceInstanceString, ServiceInstance.class);
225             if (serviceInstance.getServiceRole().equalsIgnoreCase("nsi")) {
226                 serviceInstance.getRelationshipList().getRelationship().forEach(relationship -> {
227                     if (Objects.nonNull(relationship.getRelatedTo()) && relationship.getRelatedTo().equalsIgnoreCase("allotted-resource")) {
228                         relationship.getRelationshipData().forEach(data -> {
229                             if (data.get("relationship-key").equalsIgnoreCase("service-instance.service-instance-id")) {
230                                 allotedResource.add(data.get("relationship-value"));
231                             }
232
233                         });
234                     }
235                 });
236
237                 return fetchSnssaiOfSliceProfile(fetchSliceProfilesOfAllotedResourceData(allotedResource));
238
239             }
240             if (serviceInstance.getServiceRole().equalsIgnoreCase("nssi")) {
241                 serviceInstance.getRelationshipList().getRelationship().forEach(relationship -> {
242                     if (Objects.nonNull(relationship.getRelatedToProperty())) {
243                         relationship.getRelatedToProperty().forEach(property -> {
244                             if (property.get("property-value").contains("sliceprofile")) {
245                                 relationship.getRelationshipData().forEach(data -> {
246                                     if (data.get("relationship-key")
247                                             .equalsIgnoreCase("service-instance.service-instance-id")) {
248                                         sliceProfileList.add(data.get("relationship-value"));
249                                     }
250
251                                 });
252
253                             }
254
255                         });
256                     }
257                 });
258                 return fetchSnssaiOfSliceProfile(sliceProfileList);
259             }
260
261         } catch (Exception e) {
262             log.info("Exception while fetching snssaiList: " + e);
263         }
264
265         return snssaiList;
266
267     }
268
269     /**
270      * Fetches the sliceProfileList of a AllotedResource
271      *
272      * @param allotedResourceList contains list of allotedResource IDs
273      * @return sliceProfilesList contains list of SliceProfiles
274      */
275     public List<String> fetchSliceProfilesOfAllotedResourceData(List<String> allotedResourceList) {
276
277         List<String> sliceProfileList = new ArrayList<>();
278
279         log.info("fetch Alloted Resource Data");
280
281         allotedResourceList.forEach(serviceInstanceId -> {
282             try {
283                 String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
284                         + "/service-subscriptions/service-subscription/" + subscriptionServiceType
285                         + "/service-instances/service-instance/" + serviceInstanceId;
286                 log.info("serviceReqUrl {}", serviceReqUrl);
287                 String serviceInstanceString =
288                         restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
289                 ServiceInstance serviceInstance = objectMapper.readValue(serviceInstanceString, ServiceInstance.class);
290
291                 serviceInstance.getRelationshipList().getRelationship().forEach(relationship -> {
292                     relationship.getRelatedToProperty().forEach(property -> {
293                         if (property.get("property-value").contains("sliceprofile")) {
294                             relationship.getRelationshipData().forEach(data -> {
295                                 if (data.get("relationship-key")
296                                         .equalsIgnoreCase("service-instance.service-instance-id")) {
297                                     sliceProfileList.add(data.get("relationship-value"));
298                                 }
299
300                             });
301
302                         }
303
304                     });
305
306                 });
307             } catch (Exception e) {
308                 log.info("Exception while fetching AllotedResourceData: " + e);
309             }
310
311         });
312
313         log.info("sliceProfileList: " + sliceProfileList);
314
315         return sliceProfileList;
316
317     }
318
319     /**
320      * Fetches the snssaiList of a SliceProfile
321      *
322      * @param sliceProfileList contains list of sliceProfile IDs
323      * @return snssaiList contains list of SNSSAIs
324      */
325     public List<String> fetchSnssaiOfSliceProfile(List<String> sliceProfileList) {
326         List<String> snssaiList = new ArrayList<>();
327
328         log.info("fetch SliceProfile");
329         sliceProfileList.forEach(serviceInstanceId -> {
330             String serviceReqUrl = aaiBaseUrl + "/business/customers/customer/" + globalSubscriberId
331                     + "/service-subscriptions/service-subscription/" + subscriptionServiceType + "/service-instances/"
332                     + "service-instance/" + serviceInstanceId;
333             log.info("serviceReqUrl {}", serviceReqUrl);
334             try {
335                 String serviceInstanceString =
336                         restclient.sendGetRequest(serviceReqUrl, new ParameterizedTypeReference<String>() {}).getBody();
337                 ServiceInstance serviceInstance = objectMapper.readValue(serviceInstanceString, ServiceInstance.class);
338
339                 if (serviceInstance.getServiceRole().equalsIgnoreCase("slice-profile")) {
340                     if (!snssaiList.contains(serviceInstance.getEnvironmentContext())) {
341                         snssaiList.add(serviceInstance.getEnvironmentContext());
342                     }
343                 }
344
345             } catch (Exception e) {
346                 log.info("Exception while fetching sliceProfile data: " + e);
347             }
348
349         });
350         log.info("snssaiList: " + snssaiList);
351
352         return snssaiList;
353
354     }
355
356     /**
357      * Get network bandwidth attribute of an ethernet service. These data is inside a network policy whose
358      * etwork-policy-fqdn equals to provided service-instance-id
359      * @param serviceId target service instance id
360      * @return Map contains maxBandwidth value of given service-instance
361      */
362     public Map<String, Integer> fetchMaxBandwidthOfService(String serviceId){
363         log.info("Fetching max-bandwidth from AAI network-policy");
364         String networkPolicyUrl = aaiBaseUrl + "/network/network-policies" + "?network-policy-fqdn="
365                 + serviceId;
366         Map<String, Integer> result = new HashMap<>();
367         try {
368             ResponseEntity<String> resp = restclient.sendGetRequest(networkPolicyUrl, new ParameterizedTypeReference<String>() {
369             });
370             if (resp.getStatusCodeValue() == 200){
371                 String networkPolicy = resp.getBody();
372                 JSONObject networkPolicyJson = new JSONObject(networkPolicy);
373                 JSONArray networkPolicyList     = networkPolicyJson.optJSONArray("network-policy");
374                 if (networkPolicyList != null){
375                     JSONObject networkPolicyOjb = networkPolicyList.getJSONObject(0);
376                     result.put("maxBandwidth", networkPolicyOjb.getInt("max-bandwidth"));
377                     return result;
378                 }
379                 log.info("Successfully fetched max bandwidth {}: {}", serviceId, result);
380             }
381         } catch (Exception e){
382             log.warn("Error encountered when fetching maxbandwidth: " + e);
383
384         }
385         return null;
386     }
387 }