Merge "Modify code to take care of missing scenario in US 832"
[vid.git] / vid-app-common / src / main / java / org / onap / vid / services / AaiServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2018 - 2019 Nokia. All rights reserved.
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 package org.onap.vid.services;
23
24 import static org.onap.vid.aai.AaiClient.QUERY_FORMAT_RESOURCE;
25 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
26
27 import com.fasterxml.jackson.databind.JsonNode;
28 import java.io.UnsupportedEncodingException;
29 import java.net.URLEncoder;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Objects;
36 import java.util.concurrent.ExecutorService;
37 import java.util.stream.Collectors;
38 import javax.validation.constraints.NotNull;
39 import javax.ws.rs.core.Response;
40 import org.apache.commons.lang3.StringUtils;
41 import org.apache.http.HttpStatus;
42 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
43 import org.onap.vid.aai.AaiClientInterface;
44 import org.onap.vid.aai.AaiGetVnfResponse;
45 import org.onap.vid.aai.AaiResponse;
46 import org.onap.vid.aai.AaiResponseTranslator;
47 import org.onap.vid.aai.ExceptionWithRequestInfo;
48 import org.onap.vid.aai.ServiceInstance;
49 import org.onap.vid.aai.ServiceInstancesSearchResults;
50 import org.onap.vid.aai.ServiceSubscription;
51 import org.onap.vid.aai.ServiceSubscriptions;
52 import org.onap.vid.aai.Services;
53 import org.onap.vid.aai.SubscriberFilteredResults;
54 import org.onap.vid.aai.model.AaiGetInstanceGroupsByCloudRegion;
55 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.AaiGetRelatedInstanceGroupsByVnfId;
56 import org.onap.vid.aai.model.AaiGetOperationalEnvironments.OperationalEnvironmentList;
57 import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
58 import org.onap.vid.aai.model.AaiGetServicesRequestModel.GetServicesAAIRespone;
59 import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
60 import org.onap.vid.aai.model.AaiRelationResponse;
61 import org.onap.vid.aai.model.GetServiceModelsByDistributionStatusResponse;
62 import org.onap.vid.aai.model.InstanceGroupInfo;
63 import org.onap.vid.aai.model.LogicalLinkResponse;
64 import org.onap.vid.aai.model.Model;
65 import org.onap.vid.aai.model.ModelVer;
66 import org.onap.vid.aai.model.OwningEntity;
67 import org.onap.vid.aai.model.OwningEntityResponse;
68 import org.onap.vid.aai.model.PortDetailsTranslator;
69 import org.onap.vid.aai.model.Project;
70 import org.onap.vid.aai.model.ProjectResponse;
71 import org.onap.vid.aai.model.Properties;
72 import org.onap.vid.aai.model.RelatedToProperty;
73 import org.onap.vid.aai.model.Relationship;
74 import org.onap.vid.aai.model.RelationshipData;
75 import org.onap.vid.aai.model.RelationshipList;
76 import org.onap.vid.aai.model.Result;
77 import org.onap.vid.aai.model.ServiceRelationships;
78 import org.onap.vid.asdc.beans.Service;
79 import org.onap.vid.exceptions.GenericUncheckedException;
80 import org.onap.vid.model.ServiceInstanceSearchResult;
81 import org.onap.vid.model.SubscriberList;
82 import org.onap.vid.model.aaiTree.AAITreeNode;
83 import org.onap.vid.model.aaiTree.Network;
84 import org.onap.vid.model.aaiTree.NodeType;
85 import org.onap.vid.model.aaiTree.RelatedVnf;
86 import org.onap.vid.model.aaiTree.VpnBinding;
87 import org.onap.vid.model.aaiTree.VpnBindingKt;
88 import org.onap.vid.roles.RoleValidator;
89 import org.onap.vid.utils.Intersection;
90 import org.onap.vid.utils.Logging;
91 import org.onap.vid.utils.Tree;
92 import org.slf4j.MDC;
93 import org.springframework.beans.factory.annotation.Autowired;
94 import org.springframework.http.HttpMethod;
95
96 public class AaiServiceImpl implements AaiService {
97     private static final String SERVICE_INSTANCE_ID = "service-instance.service-instance-id";
98     private static final String SERVICE_TYPE = "service-subscription.service-type";
99     private static final String CUSTOMER_ID = "customer.global-customer-id";
100     private static final String SERVICE_INSTANCE_NAME = "service-instance.service-instance-name";
101     private static final String TENANT_NODE_TYPE = "tenant";
102     private static final String CLOUD_REGION_NODE_TYPE = "cloud-region";
103     private int indexOfSubscriberName = 6;
104
105     private AaiClientInterface aaiClient;
106     private AaiResponseTranslator aaiResponseTranslator;
107     private AAIServiceTree aaiServiceTree;
108     private ExecutorService executorService;
109     private final Logging logging;
110
111
112     private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AaiServiceImpl.class);
113
114     @Autowired
115     public AaiServiceImpl(
116         AaiClientInterface aaiClient,
117         AaiResponseTranslator aaiResponseTranslator,
118         AAIServiceTree aaiServiceTree,
119         ExecutorService executorService, Logging logging)
120     {
121         this.aaiClient = aaiClient;
122         this.aaiResponseTranslator = aaiResponseTranslator;
123         this.aaiServiceTree = aaiServiceTree;
124         this.executorService = executorService;
125         this.logging = logging;
126     }
127
128     private List<Service> convertModelToService(Model model) {
129         List<Service> services = new ArrayList<>();
130
131         if(validateModel(model)){
132             for (ModelVer modelVer: model.getModelVers().getModelVer()) {
133                 Service service = new Service.ServiceBuilder()
134                         .setUuid(modelVer.getModelVersionId())
135                         .setInvariantUUID(model.getModelInvariantId())
136                         .setCategory(model.getModelType() != null ? model.getModelType() : "")
137                         .setVersion(modelVer.getModelVersion())
138                         .setName( modelVer.getModelName())
139                         .setDistributionStatus(modelVer.getDistributionStatus())
140                         .setToscaModelURL(null)
141                         .setLifecycleState(null)
142                         .setArtifacts(null)
143                         .setResources(null)
144                         .setOrchestrationType(modelVer.getOrchestrationType())
145                         .build();
146
147
148
149                 services.add(service);
150             }
151         } else {
152             return Collections.emptyList();
153         }
154
155         return services;
156     }
157
158     private boolean hasData(AaiResponse<?> aaiResponse) {
159         return aaiResponse != null && aaiResponse.getT() != null;
160     }
161
162     private boolean validateModel(Model model){
163         if (model == null) {
164             return false;
165         } else {
166             return model.getModelVers() != null && model.getModelVers().getModelVer() != null && model.getModelVers().getModelVer().get(0).getModelVersionId() != null;
167         }
168     }
169
170     private List<ServiceInstanceSearchResult> getServicesByOwningEntityId(List<String> owningEntities, RoleValidator roleValidator) {
171         AaiResponse<OwningEntityResponse> owningEntityResponse = aaiClient.getServicesByOwningEntityId(owningEntities);
172         List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
173         if (owningEntityResponse.getT() != null) {
174             for (OwningEntity owningEntity : owningEntityResponse.getT().getOwningEntity()) {
175                 if (owningEntity.getRelationshipList() != null) {
176                     serviceInstanceSearchResultList = convertRelationshipToSearchResult(owningEntity, serviceInstanceSearchResultList, roleValidator);
177                 }
178             }
179         }
180         return serviceInstanceSearchResultList;
181     }
182
183     private List<ServiceInstanceSearchResult> getServicesByProjectNames(List<String> projectNames, RoleValidator roleValidator) {
184         AaiResponse<ProjectResponse> projectByIdResponse = aaiClient.getServicesByProjectNames(projectNames);
185         List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
186         if (projectByIdResponse.getT() != null) {
187             for (Project project : projectByIdResponse.getT().getProject()) {
188                 if (project.getRelationshipList() != null) {
189                     serviceInstanceSearchResultList = convertRelationshipToSearchResult(project, serviceInstanceSearchResultList, roleValidator);
190                 }
191             }
192         }
193         return serviceInstanceSearchResultList;
194     }
195
196     private List<ServiceInstanceSearchResult> convertRelationshipToSearchResult(AaiRelationResponse owningEntityResponse, List<ServiceInstanceSearchResult> serviceInstanceSearchResultList, RoleValidator roleValidator) {
197         if (owningEntityResponse.getRelationshipList().getRelationship() != null) {
198             List<Relationship> relationshipList = owningEntityResponse.getRelationshipList().getRelationship();
199             for (Relationship relationship : relationshipList) {
200                 ServiceInstanceSearchResult serviceInstanceSearchResult = new ServiceInstanceSearchResult();
201                 extractRelationshipData(relationship, serviceInstanceSearchResult, roleValidator);
202                 extractRelatedToProperty(relationship, serviceInstanceSearchResult);
203                 serviceInstanceSearchResultList.add(serviceInstanceSearchResult);
204             }
205         }
206         return serviceInstanceSearchResultList;
207     }
208
209     private void extractRelationshipData(Relationship relationship, ServiceInstanceSearchResult serviceInstanceSearchResult, RoleValidator roleValidator) {
210         List<RelationshipData> relationshipDataList = relationship.getRelationDataList();
211         if (relationshipDataList != null) {
212             setSubscriberName(relationship, serviceInstanceSearchResult);
213             for (RelationshipData relationshipData : relationshipDataList) {
214                 String key = relationshipData.getRelationshipKey();
215                 if (key.equals(SERVICE_INSTANCE_ID)) {
216                     serviceInstanceSearchResult.setServiceInstanceId(relationshipData.getRelationshipValue());
217                 } else if (key.equals(SERVICE_TYPE)) {
218                     serviceInstanceSearchResult.setServiceType(relationshipData.getRelationshipValue());
219                 } else if (key.equals(CUSTOMER_ID)) {
220                     serviceInstanceSearchResult.setGlobalCustomerId(relationshipData.getRelationshipValue());
221                 }
222             }
223
224             boolean isPermitted = roleValidator.isServicePermitted(serviceInstanceSearchResult.getSubscriberName(), serviceInstanceSearchResult.getServiceType());
225             serviceInstanceSearchResult.setIsPermitted(isPermitted);
226         }
227     }
228
229     private void setSubscriberName(Relationship relationship, ServiceInstanceSearchResult serviceInstanceSearchResult) {
230         String relatedLink = relationship.getRelatedLink();
231         String[] subsciber = relatedLink.split("/");
232         serviceInstanceSearchResult.setSubscriberName(subsciber[indexOfSubscriberName]);
233     }
234
235     private void extractRelatedToProperty(Relationship relationship, ServiceInstanceSearchResult serviceInstanceSearchResult) {
236         List<RelatedToProperty> relatedToPropertyList = relationship.getRelatedToPropertyList();
237         if (relatedToPropertyList != null) {
238             for (RelatedToProperty relatedToProperty : relatedToPropertyList) {
239                 if (relatedToProperty.getPropertyKey().equals(SERVICE_INSTANCE_NAME)) {
240                     serviceInstanceSearchResult.setServiceInstanceName(relatedToProperty.getPropertyValue());
241                 }
242             }
243         }
244     }
245
246     @Override
247     public SubscriberFilteredResults getFullSubscriberList(RoleValidator roleValidator) {
248         AaiResponse<SubscriberList> subscriberResponse = aaiClient.getAllSubscribers();
249
250         return new SubscriberFilteredResults(roleValidator, subscriberResponse.getT(),
251                 subscriberResponse.getErrorMessage(),
252                 subscriberResponse.getHttpCode());
253     }
254
255     @Override
256     public AaiResponse<OperationalEnvironmentList> getOperationalEnvironments(String operationalEnvironmentType, String operationalEnvironmentStatus) {
257         return aaiClient.getOperationalEnvironments(operationalEnvironmentType, operationalEnvironmentStatus);
258     }
259
260     @Override
261     public AaiResponse<SubscriberList> getFullSubscriberList() {
262         return aaiClient.getAllSubscribers();
263     }
264
265     @Override
266     public AaiResponse getSubscriberData(String subscriberId, RoleValidator roleValidator, boolean omitServiceInstances) {
267         AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId, omitServiceInstances);
268         String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
269         for (ServiceSubscription serviceSubscription : subscriberResponse.getT().serviceSubscriptions.serviceSubscription) {
270             String serviceType = serviceSubscription.serviceType;
271             serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
272         }
273         return subscriberResponse;
274
275     }
276
277     @Override
278     public AaiResponse getServiceInstanceSearchResults(String subscriberId, String instanceIdentifier, RoleValidator roleValidator, List<String> owningEntities, List<String> projects) {
279         List<List<ServiceInstanceSearchResult>> resultList = new ArrayList<>();
280         ServiceInstancesSearchResults serviceInstancesSearchResults = new ServiceInstancesSearchResults();
281
282         if (subscriberId != null || instanceIdentifier != null) {
283             resultList.add(getServicesBySubscriber(subscriberId, instanceIdentifier, roleValidator));
284         }
285         if (owningEntities != null) {
286             resultList.add(getServicesByOwningEntityId(owningEntities, roleValidator));
287         }
288         if (projects != null) {
289             resultList.add(getServicesByProjectNames(projects, roleValidator));
290         }
291         if (!resultList.isEmpty()) {
292             serviceInstancesSearchResults.serviceInstances = Intersection.of(resultList);
293         }
294
295         return new AaiResponse<>(serviceInstancesSearchResults, null, HttpStatus.SC_OK);
296     }
297
298
299     private List<ServiceInstanceSearchResult> getServicesBySubscriber(String subscriberId, String instanceIdentifier, RoleValidator roleValidator) {
300         AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId, false);
301         String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
302         String subscriberName = subscriberResponse.getT().subscriberName;
303         ServiceSubscriptions serviceSubscriptions = subscriberResponse.getT().serviceSubscriptions;
304
305         return getSearchResultsForSubscriptions(serviceSubscriptions, subscriberId, instanceIdentifier, roleValidator, subscriberGlobalId, subscriberName);
306
307     }
308
309
310     private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSubscriptions(ServiceSubscriptions serviceSubscriptions, String subscriberId, String instanceIdentifier, RoleValidator roleValidator, String subscriberGlobalId, String subscriberName) {
311         ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
312
313         if (serviceSubscriptions != null) {
314             for (ServiceSubscription serviceSubscription : serviceSubscriptions.serviceSubscription) {
315                 String serviceType = serviceSubscription.serviceType;
316                 serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
317                 ArrayList<ServiceInstanceSearchResult> resultsForSubscription = getSearchResultsForSingleSubscription(serviceSubscription, subscriberId, instanceIdentifier, subscriberName, serviceType);
318                 results.addAll(resultsForSubscription);
319             }
320         }
321
322         return results;
323     }
324
325     private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSingleSubscription(ServiceSubscription serviceSubscription, String subscriberId, String instanceIdentifier, String subscriberName, String serviceType) {
326         ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
327
328         if (serviceSubscription.serviceInstances != null) {
329             for (ServiceInstance serviceInstance : serviceSubscription.serviceInstances.serviceInstance) {
330                 ServiceInstanceSearchResult serviceInstanceSearchResult =
331                         new ServiceInstanceSearchResult(serviceInstance.serviceInstanceId, subscriberId, serviceType, serviceInstance.serviceInstanceName,
332                                 subscriberName, serviceInstance.modelInvariantId, serviceInstance.modelVersionId, serviceSubscription.isPermitted);
333
334                 if ((instanceIdentifier == null) || (serviceInstanceMatchesIdentifier(instanceIdentifier, serviceInstance))){
335                     results.add(serviceInstanceSearchResult);
336                 }
337             }
338         }
339
340         return results;
341     }
342
343     private boolean serviceInstanceMatchesIdentifier(String instanceIdentifier, ServiceInstance serviceInstance) {
344         return instanceIdentifier.equals(serviceInstance.serviceInstanceId) || instanceIdentifier.equals(serviceInstance.serviceInstanceName);
345     }
346
347     @Override
348     public Response getVersionByInvariantId(List<String> modelInvariantId) {
349         try {
350             return aaiClient.getVersionByInvariantId(modelInvariantId);
351         } catch (Exception e) {
352             LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to getVersionByInvariantId from A&AI", e);
353         }
354         return null;
355     }
356
357     @Override
358     public AaiResponse<Pnf> getSpecificPnf(String pnfId) {
359         return aaiClient.getSpecificPnf(pnfId);
360     }
361
362     @Override
363     public AaiResponse getPNFData(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion, String equipVendor, String equipModel) {
364         return aaiClient.getPNFData(globalCustomerId, serviceType, modelVersionId, modelInvariantId, cloudRegion, equipVendor, equipModel);
365     }
366
367
368
369     @Override
370     public AaiResponse getServices(RoleValidator roleValidator) {
371         AaiResponse<GetServicesAAIRespone> subscriberResponse = aaiClient.getServices();
372         if (subscriberResponse.getT() != null) {
373             for (org.onap.vid.aai.model.AaiGetServicesRequestModel.Service service : subscriberResponse.getT().service) {
374                 service.isPermitted = true;
375             }
376         }
377         return subscriberResponse;
378     }
379
380     @Override
381     public AaiResponse<GetTenantsResponse[]> getTenants(String globalCustomerId, String serviceType, RoleValidator roleValidator) {
382         AaiResponse<GetTenantsResponse[]> aaiGetTenantsResponse = aaiClient.getTenants(globalCustomerId, serviceType);
383         GetTenantsResponse[] tenants = aaiGetTenantsResponse.getT();
384         if (tenants != null) {
385             for (GetTenantsResponse tenant : tenants) {
386                 tenant.isPermitted = roleValidator.isTenantPermitted(globalCustomerId, serviceType, tenant.tenantName);
387             }
388         }
389         return aaiGetTenantsResponse;
390     }
391
392     @Override
393     public AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId) {
394         return aaiClient.getVNFData(globalSubscriberId, serviceType, serviceInstanceId);
395     }
396
397     @Override
398     public AaiResponse<AaiGetVnfResponse> getVNFData(String globalSubscriberId, String serviceType) {
399         AaiResponse<AaiGetVnfResponse> response = aaiClient.getVNFData(globalSubscriberId, serviceType);
400         return hasData(response) ? response : new AaiResponse<>();
401     }
402
403     @Override
404     public AaiResponse getAaiZones() {
405         return aaiClient.getAllAicZones();
406     }
407
408     @Override
409     public AaiResponse getAicZoneForPnf(String globalCustomerId, String serviceType, String serviceId) {
410         String aicZone = "";
411
412         AaiResponse<ServiceRelationships> serviceInstanceResp = aaiClient.getServiceInstance(globalCustomerId, serviceType, serviceId);
413         if (serviceInstanceResp.getT() != null) {
414             List<String> aicZoneList = getRelationshipDataByType(serviceInstanceResp.getT().getRelationshipList(), "zone", "zone.zone-id");
415             if (!aicZoneList.isEmpty()) {
416                 aicZone = aicZoneList.get(0);
417             } else {
418                 LOGGER.warn("aic zone not found for service instance " + serviceId);
419             }
420         } else {
421             if (serviceInstanceResp.getErrorMessage() != null) {
422                 LOGGER.error("get service instance {} return error {}", serviceId, serviceInstanceResp.getErrorMessage());
423                 return new AaiResponse(aicZone , serviceInstanceResp.getErrorMessage() ,serviceInstanceResp.getHttpCode());
424             } else {
425                 LOGGER.warn("get service instance {} return empty body", serviceId);
426                 return new AaiResponse(aicZone , "get service instance " + serviceId + " return empty body" ,serviceInstanceResp.getHttpCode());
427             }
428         }
429
430         return new AaiResponse(aicZone , null ,HttpStatus.SC_OK);
431     }
432
433     @Override
434     public AaiResponse getNodeTemplateInstances(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion) {
435         return aaiClient.getNodeTemplateInstances(globalCustomerId, serviceType, modelVersionId, modelInvariantId, cloudRegion);
436     }
437
438     @Override
439     public AaiResponse getNetworkCollectionDetails(String serviceInstanceId){
440         return aaiClient.getNetworkCollectionDetails(serviceInstanceId);
441     }
442
443     @Override
444     public AaiResponse<AaiGetInstanceGroupsByCloudRegion> getInstanceGroupsByCloudRegion(String cloudOwner, String cloudRegionId, String networkFunction){
445         return aaiClient.getInstanceGroupsByCloudRegion(cloudOwner, cloudRegionId, networkFunction);
446     }
447
448     @Override
449     public Collection<Service> getServicesByDistributionStatus() {
450         AaiResponse<GetServiceModelsByDistributionStatusResponse> serviceModelsByDistributionStatusResponse = aaiClient.getServiceModelsByDistributionStatus();
451         Collection<Service> services = new ArrayList<>();
452         if (serviceModelsByDistributionStatusResponse.getT() != null) {
453             List<Result> results = serviceModelsByDistributionStatusResponse.getT().getResults();
454             for (Result result : results) {
455                 if(result.getModel() != null) {
456                     List<Service> service = convertModelToService(result.getModel());
457                     services.addAll(service);
458                 }
459             }
460         }
461         return services;
462     }
463
464     @Override
465     public List<String> getServiceInstanceAssociatedPnfs(String globalCustomerId, String serviceType, String serviceInstanceId) {
466         List<String> pnfs = new ArrayList<>();
467
468         AaiResponse<ServiceRelationships> serviceInstanceResp = aaiClient.getServiceInstance(globalCustomerId, serviceType, serviceInstanceId);
469         if (serviceInstanceResp.getT() != null) {
470
471             addPnfsToListViaLogicalLinks(pnfs, serviceInstanceResp);
472             addPnfsToListViaDirectRelations(pnfs, serviceInstanceResp);
473
474             if (pnfs.isEmpty()) {
475                 LOGGER.warn("no pnf direct relation found for service id:" + serviceInstanceId+
476                         " name: "+serviceInstanceResp.getT().getServiceInstanceName());
477             }
478         } else {
479             if (serviceInstanceResp.getErrorMessage() != null) {
480                 LOGGER.error("get service instance {} return error {}", serviceInstanceId, serviceInstanceResp.getErrorMessage());
481             } else {
482                 LOGGER.warn("get service instance {} return empty body", serviceInstanceId);
483             }
484         }
485
486         return pnfs.stream().distinct().collect(Collectors.toList());
487     }
488
489     @Override
490     public AaiResponseTranslator.PortMirroringConfigData getPortMirroringConfigData(String configurationId) {
491         AaiResponse<JsonNode> aaiResponse = aaiClient.getCloudRegionAndSourceByPortMirroringConfigurationId(configurationId);
492         return aaiResponseTranslator.extractPortMirroringConfigData(aaiResponse);
493     }
494
495     @Override
496     public AaiResponse getInstanceGroupsByVnfInstanceId(String vnfInstanceId){
497         AaiResponse<AaiGetRelatedInstanceGroupsByVnfId> aaiResponse = aaiClient.getInstanceGroupsByVnfInstanceId(vnfInstanceId);
498         if(aaiResponse.getHttpCode() == HttpStatus.SC_OK){
499             return new AaiResponse<>(convertGetInstanceGroupsResponseToSimpleResponse(aaiResponse.getT()), aaiResponse.getErrorMessage(), aaiResponse.getHttpCode());
500         }
501         return aaiResponse;
502     }
503
504     @Override
505     public GetTenantsResponse getHomingDataByVfModule(String vnfInstanceId, String vfModuleId) {
506         return aaiClient.getHomingDataByVfModule(vnfInstanceId,vfModuleId);
507     }
508
509     @Override
510     public List<RelatedVnf> searchGroupMembers(String globalCustomerId, String serviceType, String invariantId, String groupType, String groupRole) {
511         String getURL = "business/customers/customer/" +
512                 globalCustomerId + "/service-subscriptions/service-subscription/" +
513                 serviceType + "/service-instances?model-invariant-id=" + invariantId;
514
515         Tree<AAIServiceTree.AaiRelationship> pathsToSearch = new Tree<>(new AAIServiceTree.AaiRelationship(NodeType.SERVICE_INSTANCE));
516         pathsToSearch.addPath(AAIServiceTree.toAaiRelationshipList(NodeType.GENERIC_VNF, NodeType.INSTANCE_GROUP));
517
518         //get all vnfs related to service-instances from the model-invariant-id
519         List<AAITreeNode> aaiTree = aaiServiceTree.buildAAITree(getURL, null, HttpMethod.GET, pathsToSearch, true);
520
521         //filter by instance-group-role & instance-group-type properties (from getAdditionalProperties)
522         //only vnfs has related instance-group with the same groupType & groupRole - are filtered out.
523         List<AAITreeNode> filteredVnfs = filterByInstanceGroupRoleAndType(aaiTree, groupRole, groupType);
524
525         //convert vnfs to expected result
526         List<RelatedVnf> convertedVnfs = filteredVnfs.stream()
527                 .map(RelatedVnf::from)
528                 .collect(Collectors.toList());
529
530         final Map<String, String> copyOfParentMDC = MDC.getCopyOfContextMap();
531
532         try {
533             return executorService.submit(() ->
534                     convertedVnfs.parallelStream()
535                             .map(logging.withMDC(copyOfParentMDC, this::enrichRelatedVnfWithCloudRegionAndTenant))
536                             .collect(Collectors.toList())
537             ).get();
538         } catch (Exception e) {
539             LOGGER.error(EELFLoggerDelegate.errorLogger, "Search group Members - Failed to enrich vnf with cloud region", e);
540             return convertedVnfs;
541         }
542     }
543
544     private List<AAITreeNode> filterByInstanceGroupRoleAndType(List<AAITreeNode> aaiTree, String groupRole, String groupType) {
545
546         return aaiTree.stream()
547                 .map(AAITreeNode::getChildren)
548                 .flatMap(Collection::stream)
549                 .filter(vnf -> isInstanceGroupsNotMatchRoleAndType(vnf.getChildren(), groupRole, groupType))
550                 .collect(Collectors.toList());
551     }
552
553     public boolean isInstanceGroupsNotMatchRoleAndType(List<AAITreeNode> instanceGroups, String groupRole, String groupType) {
554         return instanceGroups.stream()
555                 .map(AAITreeNode::getAdditionalProperties)
556                 .allMatch(props ->
557                         (!(groupRole.equals(props.get("instance-group-role")) &&
558                                 groupType.equals(props.get("instance-group-type"))))
559                 );
560     }
561
562     public RelatedVnf enrichRelatedVnfWithCloudRegionAndTenant(RelatedVnf vnf) {
563         Map<String, Properties> cloudRegionAndTenant = aaiClient.getCloudRegionAndTenantByVnfId(vnf.getInstanceId());
564
565         if (cloudRegionAndTenant.containsKey(TENANT_NODE_TYPE)) {
566             vnf.setTenantId(cloudRegionAndTenant.get(TENANT_NODE_TYPE).getTenantId());
567             vnf.setTenantName(cloudRegionAndTenant.get(TENANT_NODE_TYPE).getTenantName());
568         }
569
570         if (cloudRegionAndTenant.containsKey(CLOUD_REGION_NODE_TYPE)) {
571             vnf.setLcpCloudRegionId(cloudRegionAndTenant.get(CLOUD_REGION_NODE_TYPE).getCloudRegionId());
572         }
573
574         return vnf;
575     }
576
577     private List<InstanceGroupInfo> convertGetInstanceGroupsResponseToSimpleResponse(AaiGetRelatedInstanceGroupsByVnfId response) {
578         List<InstanceGroupInfo> instanceGroupInfoList = new ArrayList<>();
579         for(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship relationship: response.getRelationshipList().getRelationship()){
580             getInstanceGroupInfoFromRelationship(relationship, instanceGroupInfoList);
581         }
582         return instanceGroupInfoList;
583     }
584
585     private void getInstanceGroupInfoFromRelationship(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship relationship, List<InstanceGroupInfo> instanceGroupInfoList) {
586         if(StringUtils.equals(relationship.getRelatedTo(),"instance-group")){
587             for(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.RelatedToProperty relatedToProperty: relationship.getRelatedToPropertyList()){
588                 if(StringUtils.equals(relatedToProperty.getKey(),"instance-group.instance-group-name")){
589                     instanceGroupInfoList.add(new InstanceGroupInfo(relatedToProperty.getValue()));
590                 }
591             }
592         }
593     }
594
595     @Override
596     public  List<PortDetailsTranslator.PortDetails> getPortMirroringSourcePorts(String configurationId){
597         return aaiClient.getPortMirroringSourcePorts(configurationId);
598     }
599
600     private void addPnfsToListViaDirectRelations(List<String> pnfs, AaiResponse<ServiceRelationships> serviceInstanceResp) {
601         pnfs.addAll(getRelationshipDataByType(serviceInstanceResp.getT().getRelationshipList(), "pnf", "pnf.pnf-name"));
602     }
603
604     private void addPnfsToListViaLogicalLinks(List<String> pnfs, AaiResponse<ServiceRelationships> serviceInstanceResp) {
605         List<String> logicalLinks = getRelationshipDataByType(serviceInstanceResp.getT().getRelationshipList(), "logical-link", "logical-link.link-name");
606         for (String logicalLink : logicalLinks) {
607             String link;
608             try {
609                 link = URLEncoder.encode(logicalLink, "UTF-8");
610             } catch (UnsupportedEncodingException e) {
611                 LOGGER.error("Failed to encode logical link: " + logicalLink, e);
612                 continue;
613             }
614
615             AaiResponse<LogicalLinkResponse> logicalLinkResp = aaiClient.getLogicalLink(link);
616             if (logicalLinkResp.getT() != null) {
617                 //lag-interface is the key for pnf - approved by Bracha
618                 List<String> linkPnfs = getRelationshipDataByType(logicalLinkResp.getT().getRelationshipList(), "lag-interface", "pnf.pnf-name");
619                 if (!linkPnfs.isEmpty()) {
620                     pnfs.addAll(linkPnfs);
621                 } else {
622                     LOGGER.warn("no pnf found for logical link " + logicalLink);
623                 }
624             } else {
625                 if (logicalLinkResp.getErrorMessage() != null) {
626                     LOGGER.error("get logical link " + logicalLink + " return error", logicalLinkResp.getErrorMessage());
627                 } else {
628                     LOGGER.warn("get logical link " + logicalLink + " return empty body");
629                 }
630             }
631         }
632     }
633
634     private List<String> getRelationshipDataByType(RelationshipList relationshipList, String relationshipType, String relationshipDataKey) {
635         List<String> relationshipValues = new ArrayList<>();
636         for (Relationship relationship : relationshipList.getRelationship()) {
637             if (relationship.getRelatedTo().equals(relationshipType)) {
638                 relationshipValues.addAll( relationship.getRelationDataList().stream()
639                         .filter(rel -> rel.getRelationshipKey().equals(relationshipDataKey))
640                         .map(RelationshipData::getRelationshipValue)
641                         .collect(Collectors.toList())
642                 );
643             }
644         }
645
646
647         return relationshipValues;
648     }
649
650     public String getAAIServiceTree(String globalCustomerId, String serviceType, String serviceInstanceId) {
651         String result;
652         try {
653             org.onap.vid.model.aaiTree.ServiceInstance tree = aaiServiceTree.getServiceInstanceTopology(globalCustomerId, serviceType, serviceInstanceId);
654             result = JACKSON_OBJECT_MAPPER.writeValueAsString(tree);
655         } catch (Exception e) {
656             throw new GenericUncheckedException(e);
657         }
658         return result;
659     }
660
661     @Override
662     public List<VpnBinding> getVpnListByVpnType(String vpnType) {
663         String path = "network/vpn-bindings?vpn-type=" + vpnType;
664
665         try {
666             List<AAITreeNode> aaiTree = aaiServiceTree.buildAAITreeForUniqueResource(path, NodeType.VPN_BINDING);
667             return aaiTree.stream().map(VpnBindingKt::from).collect(Collectors.toList());
668         } catch (ExceptionWithRequestInfo exception) {
669             if (Objects.equals(404, exception.getHttpCode())) {
670                 return Collections.emptyList();
671             }
672             throw exception;
673         }
674
675     }
676
677     @Override
678     public List<Network> getL3NetworksByCloudRegion(String cloudRegionId, String tenantId, String networkRole) {
679         String payload = buildPayloadForL3NetworksByCloudRegion(cloudRegionId, tenantId, networkRole);
680
681         try {
682             List<AAITreeNode> aaiTree = aaiServiceTree.buildAAITreeForUniqueResourceFromCustomQuery(QUERY_FORMAT_RESOURCE, payload, HttpMethod.PUT, NodeType.NETWORK);
683             return aaiTree.stream().map(Network::from).collect(Collectors.toList());
684         } catch (ExceptionWithRequestInfo exception) {
685             if (Objects.equals(404, exception.getHttpCode())) {
686                 return Collections.emptyList();
687             }
688             throw exception;
689         }
690     }
691
692     @NotNull
693     protected String buildPayloadForL3NetworksByCloudRegion(String cloudRegionId, String tenantId, String networkRole) {
694         String networkRolePart = StringUtils.isEmpty(networkRole) ? "" : "&networkRole=" + networkRole;
695         String cloudOwner = aaiClient.getCloudOwnerByCloudRegionId(cloudRegionId);
696         return "{\"start\":\"/cloud-infrastructure/cloud-regions/cloud-region/" + cloudOwner + "/" + cloudRegionId + "\"," +
697                 "\"query\":\"query/l3-networks-by-cloud-region?tenantId=" + tenantId + networkRolePart + "\"}";
698     }
699
700     @Override
701     public ModelVer getNewestModelVersionByInvariantId(String modelInvariantId){
702         return aaiClient.getLatestVersionByInvariantId(modelInvariantId);
703     }
704 }