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