Merge 1806 code of vid-common
[vid.git] / vid-app-common / src / main / java / org / onap / vid / aai / AaiClient.java
1 package org.onap.vid.aai;
2
3 import org.apache.commons.lang3.StringUtils;
4 import org.apache.http.HttpStatus;
5 import org.apache.http.client.utils.URIBuilder;
6 import org.codehaus.jackson.JsonNode;
7 import org.codehaus.jackson.map.ObjectMapper;
8 import org.json.simple.JSONArray;
9 import org.json.simple.JSONObject;
10 import org.json.simple.parser.JSONParser;
11 import org.onap.vid.aai.model.AaiGetAicZone.AicZones;
12 import org.onap.vid.aai.model.*;
13 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.*;
14 import org.onap.vid.aai.model.AaiGetOperationalEnvironments.OperationalEnvironmentList;
15 import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
16 import org.onap.vid.aai.model.AaiGetServicesRequestModel.GetServicesAAIRespone;
17 import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
18 import org.onap.vid.aai.model.Relationship;
19 import org.onap.vid.aai.model.RelationshipData;
20 import org.onap.vid.aai.model.RelationshipList;
21 import org.onap.vid.aai.util.AAIRestInterface;
22 import org.onap.vid.aai.util.VidObjectMapperType;
23 import org.onap.vid.exceptions.GenericUncheckedException;
24 import org.onap.vid.model.SubscriberList;
25 import org.onap.vid.model.probes.ErrorMetadata;
26 import org.onap.vid.model.probes.ExternalComponentStatus;
27 import org.onap.vid.model.probes.HttpRequestMetadata;
28 import org.onap.vid.utils.Logging;
29 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
30 import org.springframework.web.util.UriUtils;
31
32 import javax.inject.Inject;
33 import javax.ws.rs.WebApplicationException;
34 import javax.ws.rs.core.Response;
35 import java.io.IOException;
36 import java.io.UnsupportedEncodingException;
37 import java.net.URLEncoder;
38 import java.text.DateFormat;
39 import java.text.SimpleDateFormat;
40 import java.util.*;
41
42 import static java.util.Collections.emptyList;
43 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
44
45 /**
46
47  * Created by Oren on 7/4/17.
48  */
49 public class AaiClient implements AaiClientInterface {
50
51
52     public static final String QUERY_FORMAT_RESOURCE = "query?format=resource";
53     public static final String SERVICE_SUBSCRIPTIONS_PATH = "/service-subscriptions/service-subscription/";
54     public static final String MODEL_INVARIANT_ID = "&model-invariant-id=";
55     public static final String QUERY_FORMAT_SIMPLE = "query?format=simple";
56     public static final String BUSINESS_CUSTOMER = "/business/customers/customer/";
57     public static final String SERVICE_INSTANCE = "/service-instances/service-instance/";
58     public static final String BUSINESS_CUSTOMERS_CUSTOMER = "business/customers/customer/";
59
60     protected String fromAppId = "VidAaiController";
61
62     private PortDetailsTranslator portDetailsTranslator;
63
64     private final AAIRestInterface restController;
65
66     /**
67      * The logger
68      */
69     EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiClient.class);
70
71     /**
72      * The Constant dateFormat.
73      */
74     static final DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
75
76     static final String GET_SERVICE_MODELS_RESPONSE_BODY = "{\"start\" : \"service-design-and-creation/models/\", \"query\" : \"query/serviceModels-byDistributionStatus?distributionStatus=DISTRIBUTION_COMPLETE_OK\"}";
77
78     @Inject
79     public AaiClient(AAIRestInterface restController, PortDetailsTranslator portDetailsTranslator) {
80         this.restController = restController;
81         this.portDetailsTranslator = portDetailsTranslator;
82     }
83
84
85     private static String checkForNull(String local) {
86         if (local != null)
87             return local;
88         else
89             return "";
90
91     }
92
93     @Override
94     public AaiResponse getServicesByOwningEntityId(List<String> owningEntityIds){
95         Response resp = doAaiGet(getUrlFromLIst("business/owning-entities?", "owning-entity-id=", owningEntityIds), false);
96         return processAaiResponse(resp, OwningEntityResponse.class, null);
97     }
98
99     @Override
100     public AaiResponse getServicesByProjectNames(List<String> projectNames){
101         Response resp = doAaiGet(getUrlFromLIst("business/projects?", "project-name=",  projectNames), false);
102         return processAaiResponse(resp, ProjectResponse.class, null);
103     }
104
105     @Override
106     public AaiResponse getServiceModelsByDistributionStatus() {
107         Response resp = doAaiPut(QUERY_FORMAT_RESOURCE, GET_SERVICE_MODELS_RESPONSE_BODY, false);
108         return processAaiResponse(resp, GetServiceModelsByDistributionStatusResponse.class, null);
109     }
110
111     @Override
112     public AaiResponse getNetworkCollectionDetails(String serviceInstanceId) {
113         Response resp = doAaiPut(QUERY_FORMAT_RESOURCE, "{\"start\": [\"nodes/service-instances/service-instance/" + serviceInstanceId + "\"],\"query\": \"query/network-collection-ByServiceInstance\"}\n", false);
114         AaiResponse<AaiGetNetworkCollectionDetailsHelper> aaiResponse = processAaiResponse(resp, AaiGetNetworkCollectionDetailsHelper.class, null, VidObjectMapperType.FASTERXML);
115         return getNetworkCollectionDetailsResponse(aaiResponse);
116     }
117
118     @Override
119     public AaiResponse getInstanceGroupsByCloudRegion(String cloudOwner, String cloudRegionId, String networkFunction) {
120         Response resp = doAaiPut(QUERY_FORMAT_RESOURCE,
121                 "{\"start\": [\"cloud-infrastructure/cloud-regions/cloud-region/" + cloudOwner + "/" + cloudRegionId + "\"]," +
122                         "\"query\": \"query/instance-group-byCloudRegion?type=L3-NETWORK&role=SUB-INTERFACE&function=" + networkFunction + "\"}\n", false);
123         return processAaiResponse(resp, AaiGetInstanceGroupsByCloudRegion.class, null, VidObjectMapperType.FASTERXML);
124     }
125
126     private AaiResponse getNetworkCollectionDetailsResponse(AaiResponse<AaiGetNetworkCollectionDetailsHelper> aaiResponse){
127         if(aaiResponse.getHttpCode() == 200) {
128             com.fasterxml.jackson.databind.ObjectMapper om = new com.fasterxml.jackson.databind.ObjectMapper();
129             AaiGetNetworkCollectionDetails aaiGetNetworkCollectionDetails = new AaiGetNetworkCollectionDetails();
130             try {
131                 for (int i = 0; i < aaiResponse.getT().getResults().size(); i++) {
132                     LinkedHashMap<String, Object> temp = ((LinkedHashMap) aaiResponse.getT().getResults().get(i));
133                     if (temp.get("service-instance") != null)
134                         aaiGetNetworkCollectionDetails.getResults().setServiceInstance(om.readValue(om.writeValueAsString(temp.get("service-instance")), org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.ServiceInstance.class));
135                     else if (temp.get("collection") != null)
136                         aaiGetNetworkCollectionDetails.getResults().setCollection(om.readValue(om.writeValueAsString(temp.get("collection")), org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Collection.class));
137                     else if (temp.get("instance-group") != null)
138                         aaiGetNetworkCollectionDetails.getResults().setInstanceGroup(om.readValue(om.writeValueAsString(temp.get("instance-group")), InstanceGroup.class));
139                     else if (temp.get("l3-network") != null)
140                         aaiGetNetworkCollectionDetails.getResults().getNetworks().add(om.readValue(om.writeValueAsString(temp.get("l3-network")), Network.class));
141                 }
142                 return new AaiResponse(aaiGetNetworkCollectionDetails, null, HttpStatus.SC_OK);
143             }
144             catch (com.fasterxml.jackson.databind.JsonMappingException e) {
145                 return new AaiResponse(e.getCause(), "AAI response parsing Error" , aaiResponse.getHttpCode());
146             }
147             catch (Exception e) {
148                 return new AaiResponse(e.getCause(), "Got " + aaiResponse.getHttpCode() + " from a&ai" , aaiResponse.getHttpCode());
149             }
150         }
151         return aaiResponse;
152     }
153
154     @Override
155     public AaiResponse getPNFData(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion, String equipVendor, String equipModel) {
156         String siQuery = BUSINESS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) + "/service-instances?model-version-id=" + modelVersionId + MODEL_INVARIANT_ID + modelInvariantId;
157         String pnfQuery = "query/pnf-fromModel-byRegion?cloudRegionId=" + encodePathSegment(cloudRegion) + "&equipVendor=" + encodePathSegment(equipVendor) + "&equipModel=" + encodePathSegment(equipModel);
158         String payload = "{\"start\":\"" + siQuery + "\",\"query\":\"" + pnfQuery + "\"}";
159         Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
160         return processAaiResponse(resp, AaiGetPnfResponse.class, null);
161     }
162
163
164     @Override
165     public AaiResponse<Pnf> getSpecificPnf(String pnfId) {
166         Response resp = doAaiGet("network/pnfs/pnf/"+pnfId, false);
167         return processAaiResponse(resp, Pnf.class, null);
168     }
169
170
171     public AaiResponse getInstanceGroupsByVnfInstanceId(String vnfInstanceId){
172         Response resp = doAaiGet("network/generic-vnfs/generic-vnf/" + vnfInstanceId + "?depth=0", false);
173         return processAaiResponse(resp, AaiGetRelatedInstanceGroupsByVnfId.class , null, null);
174     }
175
176
177     @Override
178     public List<PortDetailsTranslator.PortDetails> getPortMirroringSourcePorts(String configurationID) {
179         String payload = "{\"start\":\"/network/configurations/configuration/" + configurationID + "\",\"query\":\"query/pserver-fromConfiguration\"}";
180         Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
181         resp.bufferEntity(); // avoid later "Entity input stream has already been closed" problems
182         String rawPayload = resp.readEntity(String.class);
183         AaiResponse<AaiGetPortMirroringSourcePorts> aaiResponse = processAaiResponse(resp, AaiGetPortMirroringSourcePorts.class, rawPayload);
184         return portDetailsTranslator.extractPortDetails(aaiResponse, rawPayload);
185     }
186
187
188
189     public AaiResponse getServiceInstance(String globalCustomerId, String serviceType, String serviceInstanceId) {
190         String getServiceInstancePath = BUSINESS_CUSTOMERS_CUSTOMER + globalCustomerId+ SERVICE_SUBSCRIPTIONS_PATH +serviceType+ SERVICE_INSTANCE +serviceInstanceId;
191         Response resp = doAaiGet(getServiceInstancePath , false);
192         return processAaiResponse(resp, ServiceRelationships.class, null);
193     }
194
195     @Override
196     public AaiResponse getLogicalLink(String link) {
197         Response resp = doAaiGet("network/logical-links/logical-link/" + link , false);
198         return processAaiResponse(resp, LogicalLinkResponse.class, null);
199     }
200
201     @Override
202     public AaiResponse<AaiNodeQueryResponse> searchNodeTypeByName(String name, ResourceType type) {
203         String path = String.format(
204                 "search/nodes-query?search-node-type=%s&filter=%s:EQUALS:%s",
205                 type.getAaiFormat(),
206                 type.getNameFilter(),
207                 name
208         );
209         return typedAaiGet(path, AaiNodeQueryResponse.class);
210     }
211
212     private <T> AaiResponse<T> typedAaiGet(String path, Class<T> clz) {
213         Response resp = doAaiGet(path , false);
214         return processAaiResponse(resp, clz, null, VidObjectMapperType.FASTERXML);
215     }
216
217
218
219     private String getUrlFromLIst(String url, String paramKey, List<String> params){
220         int i = 0;
221         for(String param: params){
222             i ++;
223             url = url.concat(paramKey);
224             String encodedParam= param;
225             try {
226                 encodedParam= URLEncoder.encode(param, "UTF-8");
227             } catch (UnsupportedEncodingException e) {
228                 String methodName = "getUrlFromList";
229                 logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
230                 logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
231             }
232             url = url.concat(encodedParam);
233             if(i != params.size()){
234                 url = url.concat("&");
235             }
236         }
237         return url;
238     }
239
240
241     @Override
242     public AaiResponse<SubscriberList> getAllSubscribers() {
243         return getAllSubscribers(false).getAaiResponse();
244     }
245
246     AaiResponseWithRequestInfo<SubscriberList> getAllSubscribers(boolean propagateExceptions){
247         String depth = "0";
248         ResponseWithRequestInfo aaiGetResult = doAaiGet("business/customers?subscriber-type=INFRA&depth=" + depth, false, propagateExceptions);
249         AaiResponseWithRequestInfo<SubscriberList> responseWithRequestInfo = processAaiResponse(aaiGetResult, SubscriberList.class, propagateExceptions);
250         responseWithRequestInfo.setRequestedUrl(aaiGetResult.getRequestUrl());
251         responseWithRequestInfo.setHttpMethod(aaiGetResult.getRequestHttpMethod());
252         return responseWithRequestInfo;
253     }
254
255
256     @Override
257     public AaiResponse getAllAicZones() {
258         Response resp = doAaiGet("network/zones", false);
259         return processAaiResponse(resp, AicZones.class, null);
260     }
261
262
263     @Override
264     public AaiResponse<String> getAicZoneForPnf(String globalCustomerId , String serviceType , String serviceId) {
265         String aicZonePath = BUSINESS_CUSTOMERS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + serviceType + SERVICE_INSTANCE + serviceId;
266         Response resp = doAaiGet(aicZonePath , false);
267         AaiResponse<ServiceRelationships> aaiResponse = processAaiResponse(resp , ServiceRelationships.class , null);
268         ServiceRelationships serviceRelationships = aaiResponse.getT();
269         RelationshipList relationshipList = serviceRelationships.getRelationshipList();
270         Relationship relationship = relationshipList.getRelationship().get(0);
271         RelationshipData relationshipData=  relationship.getRelationDataList().get(0);
272         String aicZone = relationshipData.getRelationshipValue();
273         return new AaiResponse(aicZone , null ,HttpStatus.SC_OK);
274     }
275
276
277     @Override
278     public AaiResponse getVNFData() {
279         String payload = "{\"start\": [\"/business/customers/customer/e433710f-9217-458d-a79d-1c7aff376d89/service-subscriptions/service-subscription/VIRTUAL%20USP/service-instances/service-instance/3f93c7cb-2fd0-4557-9514-e189b7b04f9d\"], \"query\": \"query/vnf-topology-fromServiceInstance\"}";
280         Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
281         return processAaiResponse(resp, AaiGetVnfResponse.class, null);
282     }
283
284     @Override
285     public Response getVNFData(String globalSubscriberId, String serviceType) {
286         String payload = "{\"start\": [\"business/customers/customer/" + globalSubscriberId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) +"/service-instances\"]," +
287                 "\"query\": \"query/vnf-topology-fromServiceInstance\"}";
288         return doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
289     }
290
291     @Override
292     public AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId) {
293         String payload = "{\"start\": [\"/business/customers/customer/" + globalSubscriberId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) + SERVICE_INSTANCE + serviceInstanceId + "\"],       \"query\": \"query/vnf-topology-fromServiceInstance\"}";
294         Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
295         return processAaiResponse(resp, AaiGetVnfResponse.class, null);
296     }
297
298     @Override
299     public Response getVersionByInvariantId(List<String> modelInvariantId) {
300         StringBuilder sb = new StringBuilder();
301         for (String id : modelInvariantId){
302             sb.append(MODEL_INVARIANT_ID);
303             sb.append(id);
304
305         }
306         return doAaiGet("service-design-and-creation/models?depth=2"+ sb.toString(), false);
307     }
308
309     @Override
310     public AaiResponse getSubscriberData(String subscriberId) {
311         String depth = "2";
312         AaiResponse subscriberDataResponse;
313         Response resp = doAaiGet(BUSINESS_CUSTOMERS_CUSTOMER + subscriberId + "?depth=" + depth, false);
314         subscriberDataResponse = processAaiResponse(resp, Services.class, null);
315         return subscriberDataResponse;
316     }
317
318     @Override
319     public AaiResponse getServices() {
320         Response resp = doAaiGet("service-design-and-creation/services", false);
321         return processAaiResponse(resp, GetServicesAAIRespone.class, null);
322     }
323
324     @Override
325     public AaiResponse getOperationalEnvironments(String operationalEnvironmentType, String operationalEnvironmentStatus) {
326         String url = "cloud-infrastructure/operational-environments";
327         URIBuilder urlBuilder  = new URIBuilder();
328         if (operationalEnvironmentType != null)
329             urlBuilder.addParameter("operational-environment-type", operationalEnvironmentType);
330         if (operationalEnvironmentStatus != null)
331             urlBuilder.addParameter("operational-environment-status", operationalEnvironmentStatus);
332         url += urlBuilder.toString();
333         Response resp = doAaiGet(url, false);
334         return processAaiResponse(resp, OperationalEnvironmentList.class, null);
335     }
336
337     @Override
338     public AaiResponse getTenants(String globalCustomerId, String serviceType) {
339         AaiResponse aaiResponse;
340
341         if ((globalCustomerId == null || globalCustomerId.isEmpty()) || ((serviceType == null) || (serviceType.isEmpty())) ){
342             aaiResponse = new AaiResponse<>(null, "{\"statusText\":\" Failed to retrieve LCP Region & Tenants from A&AI, Subscriber ID or Service Type is missing.\"}", HttpStatus.SC_INTERNAL_SERVER_ERROR);
343             return  aaiResponse;
344         }
345
346         String url = BUSINESS_CUSTOMERS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + serviceType;
347
348         Response resp = doAaiGet(url, false);
349         String responseAsString = parseForTenantsByServiceSubscription(resp.readEntity(String.class));
350         if (responseAsString.equals("")){
351             return new AaiResponse<>(null, String.format("{\"statusText\":\" A&AI has no LCP Region & Tenants associated to subscriber '%s' and service type '%s'\"}", globalCustomerId, serviceType), HttpStatus.SC_INTERNAL_SERVER_ERROR);
352         }
353         else {
354             return processAaiResponse(resp, GetTenantsResponse[].class, responseAsString);
355         }
356     }
357
358     @Override
359     public AaiResponse getNodeTemplateInstances(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion) {
360
361         String siQuery = BUSINESS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) + "/service-instances?model-version-id=" + modelVersionId + MODEL_INVARIANT_ID + modelInvariantId;
362         String vnfQuery = "query/queryvnfFromModelbyRegion?cloudRegionId=" + encodePathSegment(cloudRegion);
363         String payload1 = "{\"start\":\"" + siQuery + "\",\"query\":\"" + vnfQuery + "\"}";
364
365         Response resp1 = doAaiPut(QUERY_FORMAT_SIMPLE, payload1, false);
366         AaiResponse aaiResponse1 = processAaiResponse(resp1, AaiGetVnfResponse.class, null);
367         logger.debug(EELFLoggerDelegate.debugLogger, "getNodeTemplateInstances AAI's response: {}", aaiResponse1);
368         return aaiResponse1;
369     }
370
371     @Override
372     public AaiResponse<JsonNode> getCloudRegionAndSourceByPortMirroringConfigurationId(String configurationId) {
373         final String start = "[\"network/configurations/configuration/" + configurationId + "\"]";
374         final String query = "\"query/cloud-region-and-source-FromConfiguration\"";
375         String payload = "{\"start\":" + start + ",\"query\":" + query + "}";
376
377         Response response = doAaiPut("query?format=simple&nodesOnly=true", payload, false);
378         AaiResponse<JsonNode> aaiResponse = processAaiResponse(response, JsonNode.class, null);
379
380         logger.debug(EELFLoggerDelegate.debugLogger, "getNodeTemplateInstances AAI's response: {}", aaiResponse);
381         return aaiResponse;
382     }
383
384     private <T> AaiResponseWithRequestInfo<T> processAaiResponse(ResponseWithRequestInfo responseWithRequestInfo, Class<? extends T> classType, boolean propagateExceptions) {
385         String responseBody = null;
386         Integer responseHttpCode = null;
387         try {
388             Response response = responseWithRequestInfo.getResponse();
389             responseHttpCode = (response != null) ? response.getStatus() : null;
390             responseBody = (response != null) ? response.readEntity(String.class) : null;
391             AaiResponse<T> processedAaiResponse = processAaiResponse(response, classType, responseBody, VidObjectMapperType.CODEHAUS, propagateExceptions);
392             return new AaiResponseWithRequestInfo<>(responseWithRequestInfo.getRequestHttpMethod(), responseWithRequestInfo.getRequestUrl(), processedAaiResponse,
393                     responseBody);
394         } catch (Exception e) {
395             throw new ExceptionWithRequestInfo(responseWithRequestInfo.getRequestHttpMethod(),
396                     responseWithRequestInfo.getRequestUrl(), responseBody, responseHttpCode, e);
397         }
398     }
399
400     private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody) {
401         return processAaiResponse(resp, classType, responseBody, VidObjectMapperType.CODEHAUS);
402     }
403
404     private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody, VidObjectMapperType omType) {
405         return processAaiResponse(resp, classType, responseBody, omType, false);
406     }
407
408     private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody, VidObjectMapperType omType, boolean propagateExceptions) {
409         AaiResponse subscriberDataResponse;
410         if (resp == null) {
411             subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
412             logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
413         } else {
414             logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscribers() resp=" + resp.getStatusInfo().toString());
415             if (resp.getStatus() != HttpStatus.SC_OK) {
416                 logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
417                 String rawData = resp.readEntity(String.class);
418                 subscriberDataResponse = new AaiResponse<>(null, rawData, resp.getStatus());
419             } else {
420                 subscriberDataResponse = processOkResponse(resp, classType, responseBody, omType, propagateExceptions);
421             }
422         }
423         return subscriberDataResponse;
424     }
425
426     private AaiResponse processOkResponse(Response resp, Class classType, String responseBody, VidObjectMapperType omType, boolean propagateExceptions) {
427         AaiResponse subscriberDataResponse;
428         String finalResponse = null;
429         try {
430             if (responseBody != null) {
431                 finalResponse = responseBody;
432             } else {
433                 finalResponse = resp.readEntity(String.class);
434             }
435
436             if(omType == VidObjectMapperType.CODEHAUS)
437                 subscriberDataResponse = parseCodeHausObject(classType, finalResponse);
438             else
439                 subscriberDataResponse = parseFasterXmlObject(classType, finalResponse);
440
441         } catch(Exception e){
442             if (propagateExceptions) {
443                 throw new GenericUncheckedException(e);
444             } else {
445                 subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
446                 logger.error("Failed to parse aai response: \"{}\" to class {}", finalResponse, classType, e);
447             }
448         }
449         return subscriberDataResponse;
450     }
451
452     private AaiResponse parseFasterXmlObject(Class classType, String finalResponse) throws IOException {
453         com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
454         return new AaiResponse<>((objectMapper.readValue(finalResponse, classType)), null, HttpStatus.SC_OK);
455     }
456
457     private AaiResponse parseCodeHausObject(Class classType, String finalResponse) throws IOException {
458         ObjectMapper objectMapper = new ObjectMapper();
459         return new AaiResponse<>((objectMapper.readValue(finalResponse, classType)), null, HttpStatus.SC_OK);
460     }
461
462     public Response doAaiGet(String uri, boolean xml) {
463         return doAaiGet(uri, xml, false).getResponse();
464     }
465
466
467     public ResponseWithRequestInfo doAaiGet(String uri, boolean xml, boolean propagateExceptions) {
468         String methodName = "doAaiGet";
469         String transId = UUID.randomUUID().toString();
470         logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
471
472         ResponseWithRequestInfo resp;
473         try {
474             resp = restController.RestGet(fromAppId, transId, uri, xml, propagateExceptions);
475
476         } catch (Exception e) {
477             if (propagateExceptions) {
478                 throw (e instanceof RuntimeException) ? (RuntimeException)e : new GenericUncheckedException(e);
479             } else {
480                 final Exception actual =
481                         e instanceof ExceptionWithRequestInfo ? (Exception) e.getCause() : e;
482
483                 final String message =
484                         actual instanceof WebApplicationException ? ((WebApplicationException) actual).getResponse().readEntity(String.class) : e.toString();
485
486                 //ToDo: change parameter of requestUrl to real url from RestGet function
487                 resp = new ResponseWithRequestInfo(null, null, org.springframework.http.HttpMethod.GET);
488                 logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
489                 logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
490             }
491         }
492         return resp;
493     }
494
495     private String parseForTenantsByServiceSubscription(String resp) {
496         String tenantList = "";
497
498         try {
499             JSONParser jsonParser = new JSONParser();
500
501             JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
502
503             return parseServiceSubscriptionObjectForTenants(jsonObject);
504         } catch (Exception ex) {
505             logger.debug(EELFLoggerDelegate.debugLogger, "parseForTenantsByServiceSubscription error while parsing tenants by service subscription", ex);
506         }
507         return tenantList;
508     }
509
510     protected Response doAaiPut(String uri, String payload, boolean xml) {
511         String methodName = "doAaiPut";
512         String transId = UUID.randomUUID().toString();
513         logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
514
515         Response resp = null;
516         try {
517
518             resp = restController.RestPut(fromAppId, uri, payload, xml);
519
520         } catch (Exception e) {
521             logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
522             logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
523         }
524         return resp;
525     }
526
527
528     private String parseServiceSubscriptionObjectForTenants(JSONObject jsonObject) {
529         JSONArray tenantArray = new JSONArray();
530         boolean bconvert = false;
531         try {
532             JSONObject relationShipListsObj = (JSONObject) jsonObject.get("relationship-list");
533             if (relationShipListsObj != null) {
534                 JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
535                 for (Object innerObj : defaultIfNull(rShipArray, emptyList())) {
536                     if (innerObj != null) {
537                         bconvert = parseTenant(tenantArray, bconvert, (JSONObject) innerObj);
538                     }
539                 }
540             }
541         } catch (NullPointerException ex) {
542             logger.debug(EELFLoggerDelegate.debugLogger, "parseServiceSubscriptionObjectForTenants. error while parsing service subscription object for tenants", ex);
543         }
544
545         if (bconvert)
546             return tenantArray.toJSONString();
547         else
548             return "";
549
550     }
551
552     private static boolean parseTenant(JSONArray tenantArray, boolean bconvert, JSONObject inner1Obj) {
553         String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
554         if (relatedTo.equalsIgnoreCase("tenant")) {
555             JSONObject tenantNewObj = new JSONObject();
556
557             String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
558             tenantNewObj.put("link", relatedLink);
559
560             JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
561             for (Object innerObj : defaultIfNull(rDataArray, emptyList())) {
562                 parseRelationShip(tenantNewObj, (JSONObject) innerObj);
563             }
564
565             JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
566             for (Object innerObj : defaultIfNull(relatedTPropArray, emptyList())) {
567                 parseRelatedTProp(tenantNewObj, (JSONObject) innerObj);
568             }
569             bconvert = true;
570             tenantArray.add(tenantNewObj);
571         }
572         return bconvert;
573     }
574
575     private static void parseRelatedTProp(JSONObject tenantNewObj, JSONObject innerObj) {
576         if (innerObj == null)
577             return;
578
579         String propKey = checkForNull((String) innerObj.get("property-key"));
580         String propVal = checkForNull((String) innerObj.get("property-value"));
581         if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
582             tenantNewObj.put("tenantName", propVal);
583         }
584     }
585
586     private static void parseRelationShip(JSONObject tenantNewObj, JSONObject inner2Obj) {
587         if (inner2Obj == null)
588             return;
589
590         String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
591         String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
592         if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
593             tenantNewObj.put("cloudOwner", rShipVal);
594         } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
595             tenantNewObj.put("cloudRegionID", rShipVal);
596         }
597
598         if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
599             tenantNewObj.put("tenantID", rShipVal);
600         }
601     }
602
603     private static String encodePathSegment(String segmentToEncode) {
604         try {
605             return UriUtils.encodePathSegment(segmentToEncode, "UTF-8");
606         } catch (UnsupportedEncodingException e) {
607             throw new GenericUncheckedException("URI encoding failed unexpectedly", e);
608         }
609     }
610
611     @Override
612     public ExternalComponentStatus probeAaiGetAllSubscribers(){
613         long startTime = System.currentTimeMillis();
614         try {
615             AaiResponseWithRequestInfo<SubscriberList> responseWithRequestInfo = getAllSubscribers(true);
616             AaiResponse<SubscriberList> aaiResponse = responseWithRequestInfo.getAaiResponse();
617             long duration = System.currentTimeMillis() - startTime;
618
619             SubscriberList subscribersList = (aaiResponse != null) ? aaiResponse.getT() : null;
620             boolean isAvailable = subscribersList != null && subscribersList.customer != null && !subscribersList.customer.isEmpty();
621
622             HttpRequestMetadata metadata = new HttpRequestMetadata(
623                     responseWithRequestInfo.getHttpMethod(),
624                     (aaiResponse != null) ? aaiResponse.getHttpCode() : 0,
625                     responseWithRequestInfo.getRequestedUrl(),
626                     StringUtils.substring(responseWithRequestInfo.getRawData(), 0, 500),
627                     isAvailable ? "OK" : "No subscriber received",
628                     duration
629             );
630             return new ExternalComponentStatus(ExternalComponentStatus.Component.AAI, isAvailable, metadata);
631
632         } catch (ExceptionWithRequestInfo e) {
633             long duration = System.currentTimeMillis() - startTime;
634             return new ExternalComponentStatus(ExternalComponentStatus.Component.AAI, false,
635                     new HttpRequestMetadata(
636                             e.getHttpMethod(),
637                             defaultIfNull(e.getHttpCode(), 0),
638                             e.getRequestedUrl(),
639                             e.getRawData(),
640                             Logging.exceptionToDescription(e.getCause()), duration));
641         } catch (Exception e) {
642             long duration = System.currentTimeMillis() - startTime;
643             return new ExternalComponentStatus(ExternalComponentStatus.Component.AAI, false,
644                     new ErrorMetadata(Logging.exceptionToDescription(e), duration));
645         }
646     }
647 }