Bump the version for the SO core to Kohn
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / ebb / loader / ServiceEBBLoader.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (c) 2020 Nokia
6  * ================================================================================
7  * Modifications Copyright (c) 2021 Orange
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader;
24
25 import com.fasterxml.jackson.core.JsonProcessingException;
26 import org.camunda.bpm.engine.delegate.DelegateExecution;
27 import org.javatuples.Pair;
28 import org.onap.aai.domain.yang.GenericVnf;
29 import org.onap.aai.domain.yang.Relationship;
30 import org.onap.aai.domain.yang.ServiceInstance;
31 import org.onap.aai.domain.yang.VpnBinding;
32 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
33 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
34 import org.onap.aaiclient.client.aai.entities.Relationships;
35 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
36 import org.onap.so.bpmn.infrastructure.workflow.tasks.Resource;
37 import org.onap.so.bpmn.infrastructure.workflow.tasks.VrfBondingServiceException;
38 import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowType;
39 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
40 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
41 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoNetwork;
42 import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoPnf;
43 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
44 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
45 import org.onap.so.client.exception.ExceptionBuilder;
46 import org.onap.so.client.orchestration.AAIConfigurationResources;
47 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
48 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
49 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
50 import org.onap.so.db.catalog.beans.InstanceGroup;
51 import org.onap.so.db.catalog.client.CatalogDbClient;
52 import org.onap.so.serviceinstancebeans.ModelType;
53 import org.onap.so.serviceinstancebeans.RelatedInstance;
54 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.stereotype.Component;
58 import java.io.IOException;
59 import java.util.ArrayList;
60 import java.util.List;
61 import java.util.Map;
62 import java.util.Optional;
63 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ACTIVATE_INSTANCE;
64 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DEACTIVATE_INSTANCE;
65 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
66 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UNASSIGN_INSTANCE;
67 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPGRADE_INSTANCE;
68 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
69 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
70 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
71 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.NETWORKCOLLECTION;
72 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
73 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
74
75
76 @Component
77 public class ServiceEBBLoader {
78
79     private static final Logger logger = LoggerFactory.getLogger(ServiceEBBLoader.class);
80
81     private final UserParamsServiceTraversal userParamsServiceTraversal;
82     private final CatalogDbClient catalogDbClient;
83     private final VrfValidation vrfValidation;
84     private final AAIConfigurationResources aaiConfigurationResources;
85     private final WorkflowActionExtractResourcesAAI workflowActionUtils;
86     private final BBInputSetupUtils bbInputSetupUtils;
87     private final BBInputSetup bbInputSetup;
88     private final ExceptionBuilder exceptionBuilder;
89
90     public ServiceEBBLoader(UserParamsServiceTraversal userParamsServiceTraversal, CatalogDbClient catalogDbClient,
91             VrfValidation vrfValidation, AAIConfigurationResources aaiConfigurationResources,
92             WorkflowActionExtractResourcesAAI workflowActionUtils, BBInputSetupUtils bbInputSetupUtils,
93             BBInputSetup bbInputSetup, ExceptionBuilder exceptionBuilder) {
94         this.userParamsServiceTraversal = userParamsServiceTraversal;
95         this.catalogDbClient = catalogDbClient;
96         this.vrfValidation = vrfValidation;
97         this.aaiConfigurationResources = aaiConfigurationResources;
98         this.workflowActionUtils = workflowActionUtils;
99         this.bbInputSetupUtils = bbInputSetupUtils;
100         this.bbInputSetup = bbInputSetup;
101         this.exceptionBuilder = exceptionBuilder;
102     }
103
104     public List<Resource> getResourceListForService(ServiceInstancesRequest sIRequest, String requestAction,
105             DelegateExecution execution, String serviceInstanceId, String resourceId,
106             List<Pair<WorkflowType, String>> aaiResourceIds) throws IOException, VrfBondingServiceException {
107         boolean containsService = false;
108         List<Resource> resourceList = new ArrayList<>();
109         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
110         if (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)) {
111             // SERVICE-MACRO-ASSIGN will always get user params with a
112             // service.
113
114             if (userParams != null) {
115                 containsService = isContainsService(sIRequest);
116                 if (containsService) {
117                     resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
118                             serviceInstanceId, requestAction);
119                 }
120             } else {
121                 buildAndThrowException(execution,
122                         "Service-Macro-Assign request details must contain user params with a service");
123             }
124         } else if (requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
125             // SERVICE-MACRO-CREATE will get user params with a service,
126             // a service with a network, a service with a
127             // network collection, OR an empty service.
128             // If user params is just a service or null and macro
129             // queries the SI and finds a VNF, macro fails.
130
131             if (userParams != null) {
132                 containsService = isContainsService(sIRequest);
133             }
134             if (containsService) {
135                 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
136                         serviceInstanceId, requestAction);
137             }
138             if (!foundRelated(resourceList)) {
139                 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
140             }
141         } else if ((ACTIVATE_INSTANCE.equalsIgnoreCase(requestAction)
142                 || UNASSIGN_INSTANCE.equalsIgnoreCase(requestAction) || DELETE_INSTANCE.equalsIgnoreCase(requestAction)
143                 || UPGRADE_INSTANCE.equalsIgnoreCase(requestAction)
144                 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
145             // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
146             // SERVICE-MACRO-DELETE
147             // Will never get user params with service, macro will have
148             // to query the SI in AAI to find related instances.
149             traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
150         } else if (DEACTIVATE_INSTANCE.equalsIgnoreCase(requestAction)) {
151             resourceList.add(new Resource(WorkflowType.SERVICE, "", false, null));
152         }
153         return resourceList;
154     }
155
156     private boolean isContainsService(ServiceInstancesRequest sIRequest) {
157         boolean containsService;
158         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
159         containsService = userParams.stream().anyMatch(param -> param.containsKey(USER_PARAM_SERVICE));
160         return containsService;
161     }
162
163     public void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
164             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
165             throws JsonProcessingException, VrfBondingServiceException {
166         String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
167         org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
168
169         if (service == null) {
170             buildAndThrowException(execution, "Could not find the service model in catalog db.");
171         } else {
172             Resource serviceResource = new Resource(WorkflowType.SERVICE, service.getModelUUID(), false, null);
173             resourceList.add(serviceResource);
174             RelatedInstance relatedVpnBinding =
175                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
176             RelatedInstance relatedLocalNetwork =
177                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
178
179             if (relatedVpnBinding != null && relatedLocalNetwork != null) {
180                 traverseVrfConfiguration(aaiResourceIds, resourceList, serviceResource, service, relatedVpnBinding,
181                         relatedLocalNetwork);
182             } else {
183                 traverseNetworkCollection(execution, resourceList, serviceResource, service);
184             }
185         }
186     }
187
188     public boolean foundRelated(List<Resource> resourceList) {
189         return (containsWorkflowType(resourceList, WorkflowType.VNF)
190                 || containsWorkflowType(resourceList, WorkflowType.PNF)
191                 || containsWorkflowType(resourceList, WorkflowType.NETWORK)
192                 || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
193     }
194
195     public void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
196             List<Pair<WorkflowType, String>> aaiResourceIds) {
197         try {
198             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
199             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
200                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
201             var serviceResource =
202                     new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false, null);
203             serviceResource.setModelInvariantId(serviceInstanceAAI.getModelInvariantId());
204             serviceResource.setModelVersionId(serviceInstanceAAI.getModelVersionId());
205             resourceList.add(serviceResource);
206             traverseServiceInstanceMSOVnfs(resourceList, serviceResource, aaiResourceIds, serviceInstanceMSO);
207             traverseServiceInstanceMSOPnfs(resourceList, serviceResource, aaiResourceIds, serviceInstanceMSO);
208             if (serviceInstanceMSO.getNetworks() != null) {
209                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
210                         .getNetworks()) {
211                     aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
212                     Resource networkResource =
213                             new Resource(WorkflowType.NETWORK, network.getNetworkId(), false, serviceResource);
214                     ModelInfoNetwork modelInfoNetwork = network.getModelInfoNetwork();
215                     if (modelInfoNetwork != null) {
216                         networkResource.setModelCustomizationId(modelInfoNetwork.getModelCustomizationUUID());
217                         networkResource.setModelVersionId(modelInfoNetwork.getModelUUID());
218                         networkResource.setModelCustomizationId(modelInfoNetwork.getModelCustomizationUUID());
219                     }
220                     resourceList.add(networkResource);
221                 }
222             }
223             if (serviceInstanceMSO.getCollection() != null) {
224                 logger.debug("found networkcollection");
225                 aaiResourceIds
226                         .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
227                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
228                         serviceInstanceMSO.getCollection().getId(), false, serviceResource));
229             }
230             if (serviceInstanceMSO.getConfigurations() != null) {
231                 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
232                     Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
233                             aaiConfigurationResources.getConfiguration(config.getConfigurationId());
234                     if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
235                         for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
236                             if (relationship.getRelatedTo().contains("vnfc")
237                                     || relationship.getRelatedTo().contains("vpn-binding")) {
238                                 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
239                                 resourceList.add(new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(),
240                                         false, serviceResource));
241                                 break;
242                             }
243                         }
244                     }
245                 }
246             }
247         } catch (Exception ex) {
248             logger.error("Exception in traverseAAIService", ex);
249             buildAndThrowException(execution,
250                     "Could not find existing Service Instance or related Instances to execute the request on.");
251         }
252     }
253
254     private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList, Resource serviceResource,
255             List<Pair<WorkflowType, String>> aaiResourceIds,
256             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
257         if (serviceInstanceMSO.getVnfs() == null) {
258             return;
259         }
260         for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
261             aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
262             GenericVnf genericVnf = bbInputSetupUtils.getAAIGenericVnf(vnf.getVnfId());
263             Resource vnfResource = new Resource(WorkflowType.VNF, vnf.getVnfId(), false, serviceResource);
264             vnfResource.setVnfCustomizationId(genericVnf.getModelCustomizationId());
265             vnfResource.setModelCustomizationId(genericVnf.getModelCustomizationId());
266             vnfResource.setModelVersionId(genericVnf.getModelVersionId());
267             resourceList.add(vnfResource);
268             traverseVnfModules(resourceList, vnfResource, aaiResourceIds, vnf);
269             if (vnf.getVolumeGroups() != null) {
270                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
271                     aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
272                     resourceList.add(
273                             new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false, vnfResource));
274                 }
275             }
276         }
277     }
278
279     private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList, Resource serviceResource,
280             List<Pair<WorkflowType, String>> aaiResourceIds,
281             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
282         if (serviceInstanceMSO.getPnfs() == null) {
283             return;
284         }
285         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
286             aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
287             Resource resource = new Resource(WorkflowType.PNF, pnf.getPnfId(), false, serviceResource);
288             ModelInfoPnf modelInfo = pnf.getModelInfoPnf();
289             if (modelInfo != null) {
290                 resource.setModelVersionId(modelInfo.getModelUuid());
291                 resource.setModelCustomizationId(modelInfo.getModelCustomizationUuid());
292             }
293             resourceList.add(resource);
294         }
295     }
296
297     protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
298             List<Resource> resourceList, Resource serviceResource, org.onap.so.db.catalog.beans.Service service,
299             RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
300             throws VrfBondingServiceException, JsonProcessingException {
301         org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
302                 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
303         vrfValidation.vrfServiceValidation(service);
304         vrfValidation.vrfCatalogDbChecks(service);
305         vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
306                 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
307         vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
308         vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
309         vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
310         vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
311         String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
312         if (existingAAIVrfConfiguration != null) {
313             aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
314         }
315         resourceList.add(new Resource(WorkflowType.CONFIGURATION,
316                 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false, serviceResource));
317
318     }
319
320     protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
321             Resource serviceResource, org.onap.so.db.catalog.beans.Service service) {
322         if (isVnfCustomizationsInTheService(service)) {
323             buildAndThrowException(execution,
324                     "Cannot orchestrate Service-Macro-Create without user params with a vnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
325         }
326         if (isPnfCustomizationsInTheService(service)) {
327             buildAndThrowException(execution,
328                     "Cannot orchestrate Service-Macro-Create without user params with a pnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
329         }
330         List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
331         if (customizations.isEmpty()) {
332             logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
333         } else {
334             CollectionResourceCustomization collectionResourceCustomization =
335                     findCatalogNetworkCollection(execution, service);
336             traverseNetworkCollectionResourceCustomization(resourceList, serviceResource,
337                     collectionResourceCustomization);
338         }
339         traverseNetworkCollectionCustomization(resourceList, serviceResource, service);
340     }
341
342     private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList, Resource serviceResource,
343             CollectionResourceCustomization collectionResourceCustomization) {
344         if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, serviceResource,
345                 collectionResourceCustomization))
346             return;
347         int minNetworks = 0;
348         org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
349                 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
350         CollectionResourceInstanceGroupCustomization collectionInstCust = null;
351         if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
352             for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
353                     .getCollectionInstanceGroupCustomizations()) {
354                 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
355                         .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
356                     collectionInstCust = collectionInstanceGroupTemp;
357                     break;
358                 }
359             }
360             if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
361                 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
362             }
363         }
364         logger.debug("minNetworks: {}", minNetworks);
365         CollectionNetworkResourceCustomization collectionNetworkResourceCust =
366                 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
367         for (int i = 0; i < minNetworks; i++) {
368             if (collectionNetworkResourceCust != null) {
369                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
370                         collectionNetworkResourceCust.getModelCustomizationUUID(), false, serviceResource);
371                 resource.setVirtualLinkKey(Integer.toString(i));
372                 resourceList.add(resource);
373             }
374         }
375     }
376
377     private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
378             CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
379         CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
380         for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
381                 .getCollectionNetworkResourceCustomizations()) {
382             if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
383                     .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
384                 collectionNetworkResourceCust = collectionNetworkTemp;
385                 break;
386             }
387         }
388         return collectionNetworkResourceCust;
389     }
390
391     private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
392             Resource serviceResource, CollectionResourceCustomization collectionResourceCustomization) {
393         if (collectionResourceCustomization == null) {
394             logger.debug("No Network Collection Customization found");
395             return true;
396         }
397         resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
398                 collectionResourceCustomization.getModelCustomizationUUID(), false, serviceResource));
399         logger.debug("Found a network collection");
400         if (collectionResourceCustomization.getCollectionResource() == null) {
401             logger.debug("No Network Collection found. collectionResource is null");
402             return true;
403         }
404         if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
405             logger.debug("No Instance Group found for network collection.");
406             return true;
407         }
408         String toscaNodeType =
409                 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
410         if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
411             logger.debug("Instance Group tosca node type does not contain NetworkCollection:  {}", toscaNodeType);
412             return true;
413         }
414         return false;
415     }
416
417     private boolean interfaceNetworkQuantityIsAvailableInCollection(
418             CollectionResourceInstanceGroupCustomization collectionInstCust) {
419         return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
420     }
421
422     private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
423         return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
424     }
425
426     private void traverseNetworkCollectionCustomization(List<Resource> resourceList, Resource serviceResource,
427             org.onap.so.db.catalog.beans.Service service) {
428         if (isNetworkCollectionInTheResourceList(resourceList)) {
429             return;
430         }
431         if (service.getNetworkCustomizations() == null) {
432             logger.debug("No networks were found on this service model");
433             return;
434         }
435         for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
436             resourceList.add(new Resource(WorkflowType.NETWORK,
437                     service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false, serviceResource));
438         }
439     }
440
441     private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
442         return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
443     }
444
445     private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
446         return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
447     }
448
449     private void traverseVnfModules(List<Resource> resourceList, Resource vnfResource,
450             List<Pair<WorkflowType, String>> aaiResourceIds,
451             org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
452         if (vnf.getVfModules() == null) {
453             return;
454         }
455         for (VfModule vfModule : vnf.getVfModules()) {
456             aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
457             Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false, vnfResource);
458             org.onap.aai.domain.yang.VfModule aaiVfModule =
459                     bbInputSetupUtils.getAAIVfModule(vnf.getVnfId(), vfModule.getVfModuleId());
460             resource.setModelCustomizationId(aaiVfModule.getModelCustomizationId());
461             resource.setModelInvariantId(aaiVfModule.getModelInvariantId());
462             resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
463             resourceList.add(resource);
464         }
465     }
466
467
468     protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
469             org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
470             throws JsonProcessingException, VrfBondingServiceException {
471         Optional<Relationships> relationshipsOp = new AAIResultWrapper(
472                 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
473         if (relationshipsOp.isPresent()) {
474             List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
475                     relationshipsOp.get().getByType(AAIFluentTypeBuilder.Types.CONFIGURATION);
476             if (configurationsRelatedToLocalNetwork.size() > 1) {
477                 throw new VrfBondingServiceException(
478                         "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
479             }
480             if (configurationsRelatedToLocalNetwork.size() == 1) {
481                 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
482                 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
483                 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
484                         relatedConfiguration.get(), configWrapper)) {
485                     return relatedConfiguration.get().getConfigurationId();
486                 }
487             }
488         }
489         return null;
490     }
491
492     protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
493             AAIResultWrapper configWrapper) throws VrfBondingServiceException {
494         if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
495             Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
496             if (relationshipsConfigOp.isPresent()) {
497                 Optional<VpnBinding> relatedInfraVpnBindingOp =
498                         workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
499                 if (relatedInfraVpnBindingOp.isPresent()) {
500                     VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
501                     if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
502                         throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
503                                 + " is not connected to the same vpn binding id provided in request: "
504                                 + relatedVpnBinding.getInstanceId());
505                     } else {
506                         return true;
507                     }
508                 }
509             }
510         }
511         return false;
512     }
513
514     public boolean containsWorkflowType(List<Resource> resourceList, WorkflowType workflowType) {
515         return resourceList.stream().anyMatch(resource -> resource.getResourceType().equals(workflowType));
516     }
517
518     public boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
519         return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
520     }
521
522     public CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
523             org.onap.so.db.catalog.beans.Service service) {
524         CollectionResourceCustomization networkCollection = null;
525         int count = 0;
526         for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
527             if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
528                     collectionCust.getModelCustomizationUUID()) != null) {
529                 networkCollection = collectionCust;
530                 count++;
531             }
532         }
533         if (count == 0) {
534             return null;
535         } else if (count > 1) {
536             buildAndThrowException(execution,
537                     "Found multiple Network Collections in the Service model, only one per Service is supported.");
538         }
539         return networkCollection;
540     }
541
542     protected void buildAndThrowException(DelegateExecution execution, String msg) {
543         logger.error(msg);
544         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
545         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
546     }
547 }