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