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