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