acdf0afb551f8435de9d3f57a0490db7f4704ca8
[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 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2018 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 io.joshworks.restclient.http.HttpResponse;
25 import org.apache.http.HttpStatus;
26 import org.codehaus.jackson.JsonNode;
27 import org.onap.vid.aai.*;
28 import org.onap.vid.aai.ServiceInstance;
29 import org.onap.vid.aai.ServiceSubscription;
30 import org.onap.vid.aai.Services;
31 import org.onap.vid.aai.model.AaiGetAicZone.AicZones;
32 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.AaiGetNetworkCollectionDetails;
33 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.AaiGetRelatedInstanceGroupsByVnfId;
34 import org.onap.vid.aai.model.AaiGetOperationalEnvironments.OperationalEnvironmentList;
35 import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
36 import org.onap.vid.aai.model.AaiGetServicesRequestModel.GetServicesAAIRespone;
37 import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
38 import org.onap.vid.aai.model.*;
39 import org.onap.vid.asdc.beans.Service;
40 import org.onap.vid.model.ServiceInstanceSearchResult;
41 import org.onap.vid.model.SubscriberList;
42 import org.onap.vid.roles.RoleValidator;
43 import org.onap.vid.utils.Intersection;
44 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
45 import org.springframework.beans.factory.annotation.Autowired;
46
47 import javax.ws.rs.core.Response;
48 import java.io.UnsupportedEncodingException;
49 import java.net.URLEncoder;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Collections;
53 import java.util.List;
54 import java.util.stream.Collectors;
55 import org.springframework.beans.factory.annotation.Qualifier;
56
57 /**
58  * Created by Oren on 7/4/17.
59  */
60 public class AaiServiceImpl implements AaiService {
61     private static final String SERVICE_INSTANCE_ID = "service-instance.service-instance-id";
62     private static final String SERVICE_TYPE = "service-subscription.service-type";
63     private static final String CUSTOMER_ID = "customer.global-customer-id";
64     private static final String SERVICE_INSTANCE_NAME = "service-instance.service-instance-name";
65     private int indexOfSubscriberName = 6;
66
67     @Autowired
68     private AaiClientInterface aaiClient;
69
70     @Autowired
71     @Qualifier("aaiClientForCodehausMapping")
72     private AaiOverTLSClientInterface aaiOverTLSClient;
73
74     @Autowired
75     private AaiResponseTranslator aaiResponseTranslator;
76
77     private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AaiServiceImpl.class);
78
79     private List<Service> convertModelToService(Model model) {
80         List<Service> services = new ArrayList<>();
81         String category = "";
82
83         if(validateModel(model)){
84             if(model.getModelType() != null) {
85                 category = model.getModelType();
86             }
87
88             for (ModelVer modelVer: model.getModelVers().getModelVer()) {
89                 Service service = new Service(
90                         modelVer.getModelVersionId(),
91                         model.getModelInvariantId(),
92                         category, modelVer.getModelVersion(), modelVer.getModelName(),
93                         modelVer.getDistributionStatus(),
94                         null, null, null, null
95                 );
96
97                 services.add(service);
98             }
99         } else {
100             return Collections.emptyList();
101         }
102
103         return services;
104     }
105
106     private boolean validateModel(Model model){
107         if (model == null) {
108             return false;
109         } else {
110             return model.getModelVers() != null && model.getModelVers().getModelVer() != null && model.getModelVers().getModelVer().get(0).getModelVersionId() != null;
111         }
112     }
113
114     private List<ServiceInstanceSearchResult> getServicesByOwningEntityId(List<String> owningEntities, RoleValidator roleValidator) {
115         AaiResponse<OwningEntityResponse> owningEntityResponse = aaiClient.getServicesByOwningEntityId(owningEntities);
116         List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
117         if (owningEntityResponse.getT() != null) {
118             for (OwningEntity owningEntity : owningEntityResponse.getT().getOwningEntity()) {
119                 if (owningEntity.getRelationshipList() != null) {
120                     serviceInstanceSearchResultList = convertRelationshipToSearchResult(owningEntity, serviceInstanceSearchResultList, roleValidator);
121                 }
122             }
123         }
124         return serviceInstanceSearchResultList;
125     }
126
127     private List<ServiceInstanceSearchResult> getServicesByProjectNames(List<String> projectNames, RoleValidator roleValidator) {
128         AaiResponse<ProjectResponse> projectByIdResponse = aaiClient.getServicesByProjectNames(projectNames);
129         List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
130         if (projectByIdResponse.getT() != null) {
131             for (Project project : projectByIdResponse.getT().getProject()) {
132                 if (project.getRelationshipList() != null) {
133                     serviceInstanceSearchResultList = convertRelationshipToSearchResult(project, serviceInstanceSearchResultList, roleValidator);
134                 }
135             }
136         }
137         return serviceInstanceSearchResultList;
138     }
139
140     private List<ServiceInstanceSearchResult> convertRelationshipToSearchResult(AaiRelationResponse owningEntityResponse, List<ServiceInstanceSearchResult> serviceInstanceSearchResultList, RoleValidator roleValidator) {
141         if (owningEntityResponse.getRelationshipList().getRelationship() != null) {
142             List<Relationship> relationshipList = owningEntityResponse.getRelationshipList().getRelationship();
143             for (Relationship relationship : relationshipList) {
144                 ServiceInstanceSearchResult serviceInstanceSearchResult = new ServiceInstanceSearchResult();
145                 extractRelationshipData(relationship, serviceInstanceSearchResult, roleValidator);
146                 extractRelatedToProperty(relationship, serviceInstanceSearchResult);
147                 serviceInstanceSearchResultList.add(serviceInstanceSearchResult);
148             }
149         }
150         return serviceInstanceSearchResultList;
151     }
152
153     private void extractRelationshipData(Relationship relationship, ServiceInstanceSearchResult serviceInstanceSearchResult, RoleValidator roleValidator) {
154         List<RelationshipData> relationshipDataList = relationship.getRelationDataList();
155         if (relationshipDataList != null) {
156             setSubscriberName(relationship, serviceInstanceSearchResult);
157             for (RelationshipData relationshipData : relationshipDataList) {
158                 String key = relationshipData.getRelationshipKey();
159                 if (key.equals(SERVICE_INSTANCE_ID)) {
160                     serviceInstanceSearchResult.setServiceInstanceId(relationshipData.getRelationshipValue());
161                 } else if (key.equals(SERVICE_TYPE)) {
162                     serviceInstanceSearchResult.setServiceType(relationshipData.getRelationshipValue());
163                 } else if (key.equals(CUSTOMER_ID)) {
164                     serviceInstanceSearchResult.setGlobalCustomerId(relationshipData.getRelationshipValue());
165                 }
166             }
167
168             boolean isPermitted = roleValidator.isServicePermitted(serviceInstanceSearchResult.getSubscriberName(), serviceInstanceSearchResult.getServiceType());
169             serviceInstanceSearchResult.setIsPermitted(isPermitted);
170         }
171     }
172
173     private void setSubscriberName(Relationship relationship, ServiceInstanceSearchResult serviceInstanceSearchResult) {
174         String relatedLink = relationship.getRelatedLink();
175         String[] subsciber = relatedLink.split("/");
176         serviceInstanceSearchResult.setSubscriberName(subsciber[indexOfSubscriberName]);
177     }
178
179     private void extractRelatedToProperty(Relationship relationship, ServiceInstanceSearchResult serviceInstanceSearchResult) {
180         List<RelatedToProperty> relatedToPropertyList = relationship.getRelatedToPropertyList();
181         if (relatedToPropertyList != null) {
182             for (RelatedToProperty relatedToProperty : relatedToPropertyList) {
183                 if (relatedToProperty.getPropertyKey().equals(SERVICE_INSTANCE_NAME)) {
184                     serviceInstanceSearchResult.setServiceInstanceName(relatedToProperty.getPropertyValue());
185                 }
186             }
187         }
188     }
189
190     @Override
191     public SubscriberFilteredResults getFullSubscriberList(RoleValidator roleValidator) {
192         HttpResponse<SubscriberList> allSubscribers = aaiOverTLSClient.getAllSubscribers();
193         return new SubscriberFilteredResults(
194             roleValidator,
195             allSubscribers.getBody(),
196             allSubscribers.getStatusText(),
197             allSubscribers.getStatus()
198         );
199     }
200
201     @Override
202     public AaiResponse<OperationalEnvironmentList> getOperationalEnvironments(String operationalEnvironmentType, String operationalEnvironmentStatus) {
203         return aaiClient.getOperationalEnvironments(operationalEnvironmentType, operationalEnvironmentStatus);
204     }
205
206     @Override
207     public HttpResponse<SubscriberList> getFullSubscriberList() {
208         return aaiOverTLSClient.getAllSubscribers();
209     }
210
211     @Override
212     public AaiResponse getSubscriberData(String subscriberId, RoleValidator roleValidator) {
213         AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId);
214         String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
215         for (ServiceSubscription serviceSubscription : subscriberResponse.getT().serviceSubscriptions.serviceSubscription) {
216             String serviceType = serviceSubscription.serviceType;
217             serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
218         }
219         return subscriberResponse;
220
221     }
222
223     @Override
224     public AaiResponse getServiceInstanceSearchResults(String subscriberId, String instanceIdentifier, RoleValidator roleValidator, List<String> owningEntities, List<String> projects) {
225         List<List<ServiceInstanceSearchResult>> resultList = new ArrayList<>();
226         ServiceInstancesSearchResults serviceInstancesSearchResults = new ServiceInstancesSearchResults();
227
228         if (subscriberId != null || instanceIdentifier != null) {
229             resultList.add(getServicesBySubscriber(subscriberId, instanceIdentifier, roleValidator));
230         }
231         if (owningEntities != null) {
232             resultList.add(getServicesByOwningEntityId(owningEntities, roleValidator));
233         }
234         if (projects != null) {
235             resultList.add(getServicesByProjectNames(projects, roleValidator));
236         }
237         if (!resultList.isEmpty()) {
238             serviceInstancesSearchResults.serviceInstances = Intersection.of(resultList);
239         }
240
241         return new AaiResponse<>(serviceInstancesSearchResults, null, HttpStatus.SC_OK);
242     }
243
244
245     private List<ServiceInstanceSearchResult> getServicesBySubscriber(String subscriberId, String instanceIdentifier, RoleValidator roleValidator) {
246         AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId);
247         String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
248         String subscriberName = subscriberResponse.getT().subscriberName;
249         ServiceSubscriptions serviceSubscriptions = subscriberResponse.getT().serviceSubscriptions;
250
251         return getSearchResultsForSubscriptions(serviceSubscriptions, subscriberId, instanceIdentifier, roleValidator, subscriberGlobalId, subscriberName);
252
253     }
254
255
256     private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSubscriptions(ServiceSubscriptions serviceSubscriptions, String subscriberId, String instanceIdentifier, RoleValidator roleValidator, String subscriberGlobalId, String subscriberName) {
257         ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
258
259         if (serviceSubscriptions != null) {
260             for (ServiceSubscription serviceSubscription : serviceSubscriptions.serviceSubscription) {
261                 String serviceType = serviceSubscription.serviceType;
262                 serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
263                 ArrayList<ServiceInstanceSearchResult> resultsForSubscription = getSearchResultsForSingleSubscription(serviceSubscription, subscriberId, instanceIdentifier, subscriberName, serviceType);
264                 results.addAll(resultsForSubscription);
265             }
266         }
267
268         return results;
269     }
270
271     private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSingleSubscription(ServiceSubscription serviceSubscription, String subscriberId, String instanceIdentifier, String subscriberName, String serviceType) {
272         ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
273
274         if (serviceSubscription.serviceInstances != null) {
275             for (ServiceInstance serviceInstance : serviceSubscription.serviceInstances.serviceInstance) {
276                 ServiceInstanceSearchResult serviceInstanceSearchResult =
277                         new ServiceInstanceSearchResult(serviceInstance.serviceInstanceId, subscriberId, serviceType, serviceInstance.serviceInstanceName,
278                                 subscriberName, serviceInstance.modelInvariantId, serviceInstance.modelVersionId, serviceSubscription.isPermitted);
279
280                 if (instanceIdentifier == null) {
281                     results.add(serviceInstanceSearchResult);
282                 } else if (serviceInstanceMatchesIdentifier(instanceIdentifier, serviceInstance)) {
283                     results.add(serviceInstanceSearchResult);
284                 }
285             }
286         }
287
288         return results;
289     }
290
291     private boolean serviceInstanceMatchesIdentifier(String instanceIdentifier, ServiceInstance serviceInstance) {
292         return instanceIdentifier.equals(serviceInstance.serviceInstanceId) || instanceIdentifier.equals(serviceInstance.serviceInstanceName);
293     }
294
295     @Override
296     public Response getVersionByInvariantId(List<String> modelInvariantId) {
297         try {
298             return aaiClient.getVersionByInvariantId(modelInvariantId);
299         } catch (Exception e) {
300             LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to getVersionByInvariantId from A&AI", e);
301         }
302         return null;
303     }
304
305     @Override
306     public AaiResponse<Pnf> getSpecificPnf(String pnfId) {
307         return aaiClient.getSpecificPnf(pnfId);
308     }
309
310     @Override
311     public AaiResponse getPNFData(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion, String equipVendor, String equipModel) {
312         return aaiClient.getPNFData(globalCustomerId, serviceType, modelVersionId, modelInvariantId, cloudRegion, equipVendor, equipModel);
313     }
314
315
316
317     @Override
318     public AaiResponse getServices(RoleValidator roleValidator) {
319         AaiResponse<GetServicesAAIRespone> subscriberResponse = aaiClient.getServices();
320         if (subscriberResponse.getT() != null) {
321             for (org.onap.vid.aai.model.AaiGetServicesRequestModel.Service service : subscriberResponse.getT().service) {
322                 service.isPermitted = true;
323             }
324         }
325         return subscriberResponse;
326     }
327
328     @Override
329     public AaiResponse<GetTenantsResponse[]> getTenants(String globalCustomerId, String serviceType, RoleValidator roleValidator) {
330         AaiResponse<GetTenantsResponse[]> aaiGetTenantsResponse = aaiClient.getTenants(globalCustomerId, serviceType);
331         GetTenantsResponse[] tenants = aaiGetTenantsResponse.getT();
332         if (tenants != null) {
333             for (int i = 0; i < tenants.length; i++) {
334                 tenants[i].isPermitted = roleValidator.isTenantPermitted(globalCustomerId, serviceType, tenants[i].tenantName);
335             }
336         }
337         return aaiGetTenantsResponse;
338
339
340     }
341
342     @Override
343     public AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId) {
344         return aaiClient.getVNFData(globalSubscriberId, serviceType, serviceInstanceId);
345     }
346
347     @Override
348     public Response getVNFData(String globalSubscriberId, String serviceType) {
349         return aaiClient.getVNFData(globalSubscriberId, serviceType);
350     }
351
352     @Override
353     public AaiResponse getAaiZones() {
354         return (AaiResponse<AicZones>) aaiClient.getAllAicZones();
355     }
356
357     @Override
358     public AaiResponse getAicZoneForPnf(String globalCustomerId, String serviceType, String serviceId) {
359         String aicZone = "";
360
361         AaiResponse<ServiceRelationships> serviceInstanceResp = aaiClient.getServiceInstance(globalCustomerId, serviceType, serviceId);
362         if (serviceInstanceResp.getT() != null) {
363             List<String> aicZoneList = getRelationshipDataByType(serviceInstanceResp.getT().getRelationshipList(), "zone", "zone.zone-id");
364             if (!aicZoneList.isEmpty()) {
365                 aicZone = aicZoneList.get(0);
366             } else {
367                 LOGGER.warn("aic zone not found for service instance " + serviceId);
368             }
369         } else {
370             if (serviceInstanceResp.getErrorMessage() != null) {
371                 LOGGER.error("get service instance {} return error {}", serviceId, serviceInstanceResp.getErrorMessage());
372                 return new AaiResponse(aicZone , serviceInstanceResp.getErrorMessage() ,serviceInstanceResp.getHttpCode());
373             } else {
374                 LOGGER.warn("get service instance {} return empty body", serviceId);
375                 return new AaiResponse(aicZone , "get service instance " + serviceId + " return empty body" ,serviceInstanceResp.getHttpCode());
376             }
377         }
378
379         return new AaiResponse(aicZone , null ,HttpStatus.SC_OK);
380     }
381
382     @Override
383     public AaiResponse getNodeTemplateInstances(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion) {
384         return aaiClient.getNodeTemplateInstances(globalCustomerId, serviceType, modelVersionId, modelInvariantId, cloudRegion);
385     }
386
387     @Override
388     public AaiResponse getNetworkCollectionDetails(String serviceInstanceId){
389         AaiResponse<AaiGetNetworkCollectionDetails> getNetworkCollectionDetailsAaiResponse = aaiClient.getNetworkCollectionDetails(serviceInstanceId);
390         return getNetworkCollectionDetailsAaiResponse;
391     }
392
393     @Override
394     public AaiResponse<AaiGetInstanceGroupsByCloudRegion> getInstanceGroupsByCloudRegion(String cloudOwner, String cloudRegionId, String networkFunction){
395         AaiResponse<AaiGetInstanceGroupsByCloudRegion> getInstanceGroupsByCloudRegionResponse = aaiClient.getInstanceGroupsByCloudRegion(cloudOwner, cloudRegionId, networkFunction);
396         return getInstanceGroupsByCloudRegionResponse;
397     }
398
399     @Override
400     public Collection<Service> getServicesByDistributionStatus() {
401         AaiResponse<GetServiceModelsByDistributionStatusResponse> serviceModelsByDistributionStatusResponse = aaiClient.getServiceModelsByDistributionStatus();
402         Collection<Service> services = new ArrayList<>();
403         if (serviceModelsByDistributionStatusResponse.getT() != null) {
404             List<Result> results = serviceModelsByDistributionStatusResponse.getT().getResults();
405             for (Result result : results) {
406                 if(result.getModel() != null) {
407                     List<Service> service = convertModelToService(result.getModel());
408                     services.addAll(service);
409                 }
410             }
411         }
412         return services;
413     }
414
415     @Override
416     public List<String> getServiceInstanceAssociatedPnfs(String globalCustomerId, String serviceType, String serviceInstanceId) {
417         List<String> pnfs = new ArrayList<>();
418
419         AaiResponse<ServiceRelationships> serviceInstanceResp = aaiClient.getServiceInstance(globalCustomerId, serviceType, serviceInstanceId);
420         if (serviceInstanceResp.getT() != null) {
421
422             addPnfsToListViaLogicalLinks(pnfs, serviceInstanceResp);
423             addPnfsToListViaDirectRelations(pnfs, serviceInstanceResp);
424
425             if (pnfs.isEmpty()) {
426                 LOGGER.warn("no pnf direct relation found for service id:" + serviceInstanceId+
427                         " name: "+serviceInstanceResp.getT().getServiceInstanceName());
428             }
429         } else {
430             if (serviceInstanceResp.getErrorMessage() != null) {
431                 LOGGER.error("get service instance {} return error {}", serviceInstanceId, serviceInstanceResp.getErrorMessage());
432             } else {
433                 LOGGER.warn("get service instance {} return empty body", serviceInstanceId);
434             }
435         }
436
437         return pnfs.stream().distinct().collect(Collectors.toList());
438     }
439
440     @Override
441     public AaiResponseTranslator.PortMirroringConfigData getPortMirroringConfigData(String configurationId) {
442         AaiResponse<JsonNode> aaiResponse = aaiClient.getCloudRegionAndSourceByPortMirroringConfigurationId(configurationId);
443         return aaiResponseTranslator.extractPortMirroringConfigData(aaiResponse);
444     }
445
446     @Override
447     public AaiResponse getInstanceGroupsByVnfInstanceId(String vnfInstanceId){
448         AaiResponse<AaiGetRelatedInstanceGroupsByVnfId> aaiResponse = aaiClient.getInstanceGroupsByVnfInstanceId(vnfInstanceId);
449         if(aaiResponse.getHttpCode() == HttpStatus.SC_OK){
450             return new AaiResponse(convertGetInstanceGroupsResponseToSimpleResponse(aaiResponse.getT()), aaiResponse.getErrorMessage(), aaiResponse.getHttpCode());
451         }
452         return aaiClient.getInstanceGroupsByVnfInstanceId(vnfInstanceId);
453     }
454
455     private List<InstanceGroupInfo> convertGetInstanceGroupsResponseToSimpleResponse(AaiGetRelatedInstanceGroupsByVnfId response) {
456         List<InstanceGroupInfo> instanceGroupInfoList = new ArrayList<>();
457         for(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship relationship: response.getRelationshipList().getRelationship()){
458             getInstanceGroupInfoFromRelationship(relationship, instanceGroupInfoList);
459         }
460         return instanceGroupInfoList;
461     }
462
463     private void getInstanceGroupInfoFromRelationship(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship relationship, List<InstanceGroupInfo> instanceGroupInfoList) {
464         if(relationship.getRelatedTo().equals("instance-group")){
465             for(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.RelatedToProperty relatedToProperty: relationship.getRelatedToPropertyList()){
466                 if(relatedToProperty.getPropertyKey().equals("instance-group.instance-group-name")){
467                     instanceGroupInfoList.add(new InstanceGroupInfo(relatedToProperty.getPropertyValue()));
468                 }
469             }
470         }
471     }
472
473     @Override
474     public  List<PortDetailsTranslator.PortDetails> getPortMirroringSourcePorts(String configurationId){
475         return aaiClient.getPortMirroringSourcePorts(configurationId);
476     }
477
478     private void addPnfsToListViaDirectRelations(List<String> pnfs, AaiResponse<ServiceRelationships> serviceInstanceResp) {
479         pnfs.addAll(getRelationshipDataByType(serviceInstanceResp.getT().getRelationshipList(), "pnf", "pnf.pnf-name"));
480     }
481
482     private void addPnfsToListViaLogicalLinks(List<String> pnfs, AaiResponse<ServiceRelationships> serviceInstanceResp) {
483         List<String> logicalLinks = getRelationshipDataByType(serviceInstanceResp.getT().getRelationshipList(), "logical-link", "logical-link.link-name");
484         for (String logicalLink : logicalLinks) {
485             String link;
486             try {
487                 link = URLEncoder.encode(logicalLink, "UTF-8");
488             } catch (UnsupportedEncodingException e) {
489                 LOGGER.error("Failed to encode logical link: " + logicalLink, e);
490                 continue;
491             }
492
493             AaiResponse<LogicalLinkResponse> logicalLinkResp = aaiClient.getLogicalLink(link);
494             if (logicalLinkResp.getT() != null) {
495                 //lag-interface is the key for pnf - approved by Bracha
496                 List<String> linkPnfs = getRelationshipDataByType(logicalLinkResp.getT().getRelationshipList(), "lag-interface", "pnf.pnf-name");
497                 if (!linkPnfs.isEmpty()) {
498                     pnfs.addAll(linkPnfs);
499                 } else {
500                     LOGGER.warn("no pnf found for logical link " + logicalLink);
501                 }
502             } else {
503                 if (logicalLinkResp.getErrorMessage() != null) {
504                     LOGGER.error("get logical link " + logicalLink + " return error", logicalLinkResp.getErrorMessage());
505                 } else {
506                     LOGGER.warn("get logical link " + logicalLink + " return empty body");
507                 }
508             }
509         }
510     }
511
512     private List<String> getRelationshipDataByType(RelationshipList relationshipList, String relationshipType, String relationshipDataKey) {
513         List<String> relationshipValues = new ArrayList<>();
514         for (Relationship relationship : relationshipList.getRelationship()) {
515             if (relationship.getRelatedTo().equals(relationshipType)) {
516                 relationshipValues.addAll( relationship.getRelationDataList().stream()
517                         .filter(rel -> rel.getRelationshipKey().equals(relationshipDataKey))
518                         .map(RelationshipData::getRelationshipValue)
519                         .collect(Collectors.toList())
520                 );
521             }
522         }
523
524
525         return relationshipValues;
526     }
527 }