79c846bb12be1ec4d78caf4d4fba375fbe0dd97c
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / WorkflowAction.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Modifications Copyright (c) 2020 Nokia
10  * ================================================================================
11  * Modifications Copyright (c) 2020 Tech Mahindra
12  * ================================================================================
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  *      http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  * ============LICENSE_END=========================================================
25  */
26
27 package org.onap.so.bpmn.infrastructure.workflow.tasks;
28
29 import com.fasterxml.jackson.core.JsonProcessingException;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import org.apache.commons.lang3.SerializationUtils;
32 import org.camunda.bpm.engine.delegate.DelegateExecution;
33 import org.javatuples.Pair;
34 import org.onap.aai.domain.yang.GenericVnf;
35 import org.onap.aai.domain.yang.GenericVnfs;
36 import org.onap.aai.domain.yang.L3Network;
37 import org.onap.aai.domain.yang.Relationship;
38 import org.onap.aai.domain.yang.ServiceInstance;
39 import org.onap.aai.domain.yang.ServiceInstances;
40 import org.onap.aai.domain.yang.Vnfc;
41 import org.onap.aai.domain.yang.VolumeGroup;
42 import org.onap.aai.domain.yang.VpnBinding;
43 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
44 import org.onap.aaiclient.client.aai.AAIObjectName;
45 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
46 import org.onap.aaiclient.client.aai.entities.Relationships;
47 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
48 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
49 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
50 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
51 import org.onap.so.bpmn.common.BBConstants;
52 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
53 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
54 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
55 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
56 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
57 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
58 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
59 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
60 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
61 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
62 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
63 import org.onap.so.client.exception.ExceptionBuilder;
64 import org.onap.so.client.orchestration.AAIConfigurationResources;
65 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
66 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
67 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
68 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
69 import org.onap.so.db.catalog.beans.InstanceGroup;
70 import org.onap.so.db.catalog.beans.VfModuleCustomization;
71 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
72 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
73 import org.onap.so.db.catalog.client.CatalogDbClient;
74 import org.onap.so.serviceinstancebeans.CloudConfiguration;
75 import org.onap.so.serviceinstancebeans.ModelInfo;
76 import org.onap.so.serviceinstancebeans.ModelType;
77 import org.onap.so.serviceinstancebeans.RelatedInstance;
78 import org.onap.so.serviceinstancebeans.RelatedInstanceList;
79 import org.onap.so.serviceinstancebeans.RequestDetails;
80 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
83 import org.springframework.beans.factory.annotation.Autowired;
84 import org.springframework.core.env.Environment;
85 import org.springframework.stereotype.Component;
86 import org.springframework.util.CollectionUtils;
87 import java.util.ArrayList;
88 import java.util.Arrays;
89 import java.util.Collections;
90 import java.util.Comparator;
91 import java.util.List;
92 import java.util.Map;
93 import java.util.Optional;
94 import java.util.UUID;
95 import java.util.regex.Matcher;
96 import java.util.regex.Pattern;
97 import java.util.stream.Collectors;
98 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
99 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
100 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
101 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
102
103 @Component
104 public class WorkflowAction {
105
106     private static final String SERVICE_INSTANCES = "serviceInstances";
107     private static final String SERVICE_INSTANCE = "serviceInstance";
108     private static final String VF_MODULES = "vfModules";
109     private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
110             "WorkflowAction was unable to verify if the instance name already exist in AAI.";
111     private static final String VNF_TYPE = "vnfType";
112     private static final String SERVICE = "Service";
113     private static final String VNF = "Vnf";
114     private static final String PNF = "Pnf";
115     private static final String VFMODULE = "VfModule";
116     private static final String VOLUMEGROUP = "VolumeGroup";
117     private static final String NETWORK = "Network";
118     private static final String NETWORKCOLLECTION = "NetworkCollection";
119     private static final String CONFIGURATION = "Configuration";
120     private static final String ASSIGNINSTANCE = "assignInstance";
121     private static final String REPLACEINSTANCE = "replaceInstance";
122     private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
123     private static final String SUPPORTEDTYPES =
124             "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
125     private static final String HOMINGSOLUTION = "Homing_Solution";
126     private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
127     private static final String SERVICE_TYPE_BONDING = "BONDING";
128     private static final String CLOUD_OWNER = "DEFAULT";
129     private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
130     private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
131     private static final String NAME_EXISTS_MULTIPLE =
132             "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
133     private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
134             "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
135     private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
136             "(%s), same parent and different customization id (%s)";
137     private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
138     private static final String CREATENETWORKBB = "CreateNetworkBB";
139     private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
140     private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
141     private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
142     private static final String CONTROLLER = "Controller";
143     private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
144     private static final String HOMING = "homing";
145
146     @Autowired
147     protected BBInputSetup bbInputSetup;
148     @Autowired
149     protected BBInputSetupUtils bbInputSetupUtils;
150     @Autowired
151     private ExceptionBuilder exceptionBuilder;
152     @Autowired
153     private CatalogDbClient catalogDbClient;
154     @Autowired
155     private AAIConfigurationResources aaiConfigurationResources;
156     @Autowired
157     private WorkflowActionExtractResourcesAAI workflowActionUtils;
158     @Autowired
159     private VrfValidation vrfValidation;
160     @Autowired
161     private Environment environment;
162     @Autowired
163     private UserParamsServiceTraversal userParamsServiceTraversal;
164
165     public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
166         this.bbInputSetupUtils = bbInputSetupUtils;
167     }
168
169     public void setBbInputSetup(BBInputSetup bbInputSetup) {
170         this.bbInputSetup = bbInputSetup;
171     }
172
173     public void selectExecutionList(DelegateExecution execution) throws Exception {
174         try {
175             fillExecutionDefault(execution);
176             final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
177             ServiceInstancesRequest sIRequest =
178                     new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
179
180             final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
181
182             String uri = (String) execution.getVariable(BBConstants.G_URI);
183             boolean isResume = isUriResume(uri);
184
185             final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
186             Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
187
188             WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
189             RequestDetails requestDetails = sIRequest.getRequestDetails();
190             String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
191             String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
192             WorkflowType resourceType = resource.getResourceType();
193
194             String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
195
196             fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
197             List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
198
199             if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
200                 String errorMessage = "Could not resume Macro flow. Error loading execution path.";
201                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
202             } else if (isALaCarte && isResume) {
203                 String errorMessage =
204                         "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
205                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
206             } else {
207                 String vnfType = (String) execution.getVariable(VNF_TYPE);
208                 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
209                 List<OrchestrationFlow> orchFlows =
210                         (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
211                 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
212                 final String serviceType =
213                         Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
214                 if (isALaCarte) {
215                     if (orchFlows == null || orchFlows.isEmpty()) {
216                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
217                                 cloudOwner, serviceType);
218                     }
219                     Resource resourceKey = getResourceKey(sIRequest, resourceType);
220
221                     ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
222                     if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
223                             || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
224                             && resourceType.equals(WorkflowType.VFMODULE)) {
225                         logger.debug("Build a BB list for replacing BB modules");
226                         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution,
227                                 sIRequest, requestId, workflowResourceIds, requestDetails, requestAction, resourceId,
228                                 vnfType, orchFlows, apiVersion, resourceKey, replaceInfo);
229                         orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
230
231                         createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds,
232                                 requestDetails, requestAction, resourceId, flowsToExecute, vnfType, orchFlows,
233                                 apiVersion, resourceKey, replaceInfo);
234                     } else {
235                         if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
236                             addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId,
237                                     workflowResourceIds, requestDetails, requestAction, resourceId, flowsToExecute,
238                                     vnfType, apiVersion, resourceKey, replaceInfo, orchFlows);
239                         }
240                         orchFlows =
241                                 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
242                                         .collect(Collectors.toList());
243
244                         for (OrchestrationFlow orchFlow : orchFlows) {
245                             ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
246                                     apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
247                                     requestDetails, false, null, null, false, replaceInfo);
248                             flowsToExecute.add(ebb);
249                         }
250                     }
251                 } else {
252                     boolean containsService = false;
253                     List<Resource> resourceList = new ArrayList<>();
254                     List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
255                     List<Map<String, Object>> userParams =
256                             sIRequest.getRequestDetails().getRequestParameters().getUserParams();
257                     if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
258                         // SERVICE-MACRO-ASSIGN will always get user params with a
259                         // service.
260
261                         if (userParams != null) {
262                             containsService = isContainsService(sIRequest);
263                             if (containsService) {
264                                 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution,
265                                         userParams, serviceInstanceId, requestAction);
266                             }
267                         } else {
268                             buildAndThrowException(execution,
269                                     "Service-Macro-Assign request details must contain user params with a service");
270                         }
271                     } else if (resourceType == WorkflowType.SERVICE
272                             && requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
273                         // SERVICE-MACRO-CREATE will get user params with a service,
274                         // a service with a network, a service with a
275                         // network collection, OR an empty service.
276                         // If user params is just a service or null and macro
277                         // queries the SI and finds a VNF, macro fails.
278
279                         if (userParams != null) {
280                             containsService = isContainsService(sIRequest);
281                         }
282                         if (containsService) {
283                             resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution,
284                                     userParams, serviceInstanceId, requestAction);
285                         }
286                         if (!foundRelated(resourceList)) {
287                             traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
288                         }
289                     } else if (resourceType == WorkflowType.SERVICE
290                             && ("activateInstance".equalsIgnoreCase(requestAction)
291                                     || "unassignInstance".equalsIgnoreCase(requestAction)
292                                     || "deleteInstance".equalsIgnoreCase(requestAction)
293                                     || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
294                         // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
295                         // SERVICE-MACRO-DELETE
296                         // Will never get user params with service, macro will have
297                         // to query the SI in AAI to find related instances.
298                         traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
299                     } else if (resourceType == WorkflowType.SERVICE
300                             && "deactivateInstance".equalsIgnoreCase(requestAction)) {
301                         resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
302                     } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
303                             || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
304                         traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
305                                 workflowResourceIds.getVnfId(), aaiResourceIds);
306                     } else if (resourceType == WorkflowType.VNF && "updateInstance".equalsIgnoreCase(requestAction)) {
307                         customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
308                                 workflowResourceIds.getVnfId(), aaiResourceIds);
309                     } else {
310                         buildAndThrowException(execution, "Current Macro Request is not supported");
311                     }
312                     StringBuilder foundObjects = new StringBuilder();
313                     for (WorkflowType type : WorkflowType.values()) {
314                         foundObjects.append(type).append(" - ").append(
315                                 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
316                                 .append("    ");
317                     }
318                     logger.info("Found {}", foundObjects);
319
320                     if (orchFlows == null || orchFlows.isEmpty()) {
321                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
322                                 cloudOwner, serviceType);
323                     }
324                     boolean vnfReplace = false;
325                     if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
326                             || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
327                         vnfReplace = true;
328                     }
329                     flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
330                             resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
331                     if (isNetworkCollectionInTheResourceList(resourceList)) {
332                         logger.info("Sorting for Vlan Tagging");
333                         flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
334                     }
335                     // By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
336                     if (resourceType == WorkflowType.SERVICE
337                             && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE))
338                             && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
339                         execution.setVariable(HOMING, true);
340                         execution.setVariable("calledHoming", false);
341                     }
342                     if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
343                             || requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
344                         generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
345                     } else {
346                         updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
347                                 serviceInstanceId);
348                     }
349                 }
350             }
351             // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
352             // enable it.
353             List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
354             if (sIRequest.getRequestDetails().getRequestParameters() != null && userParams != null) {
355                 for (Map<String, Object> params : userParams) {
356                     if (params.containsKey(HOMINGSOLUTION)) {
357                         execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
358                     }
359                 }
360             }
361
362             if (CollectionUtils.isEmpty(flowsToExecute)) {
363                 throw new IllegalStateException("Macro did not come up with a valid execution path.");
364             }
365
366             List<String> flowNames = new ArrayList<>();
367             logger.info("List of BuildingBlocks to execute:");
368
369             flowsToExecute.forEach(ebb -> {
370                 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
371                 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
372             });
373
374             if (!isResume) {
375                 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
376             }
377             setExecutionVariables(execution, flowsToExecute, flowNames);
378
379         } catch (Exception ex) {
380             if (!(execution.hasVariable("WorkflowException")
381                     || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
382                 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
383             } else {
384                 throw ex;
385             }
386         }
387     }
388
389     private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
390             List<String> flowNames) {
391         execution.setVariable("flowNames", flowNames);
392         execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
393         execution.setVariable("retryCount", 0);
394         execution.setVariable("isRollback", false);
395         execution.setVariable("flowsToExecute", flowsToExecute);
396         execution.setVariable("isRollbackComplete", false);
397     }
398
399     private boolean isContainsService(ServiceInstancesRequest sIRequest) {
400         boolean containsService;
401         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
402         containsService = userParams.stream().anyMatch(param -> param.containsKey(USER_PARAM_SERVICE));
403         return containsService;
404     }
405
406
407
408     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
409             String errorMessage) {
410         List<ExecuteBuildingBlock> flowsToExecute;
411         flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
412         if (flowsToExecute == null) {
413             buildAndThrowException(execution, errorMessage);
414         }
415         return flowsToExecute;
416     }
417
418     private ConfigBuildingBlocksDataObject createConfigBuildingBlocksDataObject(DelegateExecution execution,
419             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
420             RequestDetails requestDetails, String requestAction, String resourceId, String vnfType,
421             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
422             ReplaceInstanceRelatedInformation replaceInfo) {
423
424         return new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
425                 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
426                 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
427                 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails).setExecution(execution)
428                 .setReplaceInformation(replaceInfo);
429     }
430
431     private void createBuildingBlocksForOrchFlows(DelegateExecution execution, ServiceInstancesRequest sIRequest,
432             String requestId, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
433             String requestAction, String resourceId, List<ExecuteBuildingBlock> flowsToExecute, String vnfType,
434             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
435             ReplaceInstanceRelatedInformation replaceInfo) throws Exception {
436
437         for (OrchestrationFlow orchFlow : orchFlows) {
438             if (orchFlow.getFlowName().contains(CONFIGURATION)) {
439                 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
440                 configOrchFlows.add(orchFlow);
441                 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
442                         requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
443                         replaceInfo, configOrchFlows);
444             } else {
445                 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey, apiVersion,
446                         resourceId, requestAction, true, vnfType, workflowResourceIds, requestDetails, false, null,
447                         null, false, replaceInfo);
448                 flowsToExecute.add(ebb);
449             }
450         }
451     }
452
453     private void addConfigBuildingBlocksToFlowsToExecuteList(DelegateExecution execution,
454             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
455             RequestDetails requestDetails, String requestAction, String resourceId,
456             List<ExecuteBuildingBlock> flowsToExecute, String vnfType, String apiVersion, Resource resourceKey,
457             ReplaceInstanceRelatedInformation replaceInfo, List<OrchestrationFlow> configOrchFlows) throws Exception {
458
459         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
460                 workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, configOrchFlows, apiVersion,
461                 resourceKey, replaceInfo);
462         List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(cbbdo);
463         flowsToExecute.addAll(configBuildingBlocks);
464     }
465
466     private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
467         String resourceId = "";
468         ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
469         if (modelInfo != null) {
470             if (modelInfo.getModelType().equals(ModelType.service)) {
471                 resourceId = modelInfo.getModelVersionId();
472             } else {
473                 resourceId = modelInfo.getModelCustomizationId();
474             }
475         }
476         return new Resource(resourceType, resourceId, true);
477     }
478
479     private String getCloudOwner(CloudConfiguration cloudConfiguration) {
480         if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
481             return cloudConfiguration.getCloudOwner();
482         }
483         logger.warn("cloud owner value not found in request details, it will be set as default");
484         return environment.getProperty(DEFAULT_CLOUD_OWNER);
485     }
486
487     protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
488             AAIObjectName name) {
489         List<T> vnfcs = new ArrayList<>();
490         AAIResourceUri uri =
491                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
492         AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
493         Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
494         if (!relationshipsOp.isPresent()) {
495             logger.debug("No relationships were found for vfModule in AAI");
496         } else {
497             Relationships relationships = relationshipsOp.get();
498             List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(name);
499             for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
500                 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
501                 vnfcOp.ifPresent(vnfcs::add);
502             }
503         }
504         return vnfcs;
505     }
506
507     protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name) throws Exception {
508         T configuration = null;
509         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
510         AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
511         Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
512         if (!relationshipsOp.isPresent()) {
513             logger.debug("No relationships were found for VNFC in AAI");
514         } else {
515             Relationships relationships = relationshipsOp.get();
516             List<AAIResultWrapper> configurationResultWrappers =
517                     this.getResultWrappersFromRelationships(relationships, name);
518             if (configurationResultWrappers.size() > 1) {
519                 String multipleRelationshipsError =
520                         "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
521                 throw new Exception(multipleRelationshipsError);
522             }
523             if (!configurationResultWrappers.isEmpty()) {
524                 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
525                 if (configurationOp.isPresent()) {
526                     configuration = configurationOp.get();
527                 }
528             }
529         }
530         return configuration;
531     }
532
533     protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
534             AAIObjectName name) {
535         return relationships.getByType(name);
536     }
537
538     protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
539         for (OrchestrationFlow flow : orchFlows) {
540             if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
541                 return true;
542             }
543         }
544         return false;
545     }
546
547     protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
548             throws Exception {
549
550         List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
551         List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
552                 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
553         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
554         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
555
556         String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
557         String vfModuleCustomizationUUID;
558         org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
559
560         if (aaiVfModule == null) {
561             logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
562                     vfModuleId);
563             throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
564                     + vnfId + " and vfModuleId : " + vfModuleId);
565         } else {
566             vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
567         }
568         String replaceVfModuleCustomizationUUID = "";
569         String replaceVnfModuleCustomizationUUID = "";
570         boolean isReplace = false;
571         if (dataObj.getRequestAction().equalsIgnoreCase("replaceInstance")
572                 || dataObj.getRequestAction().equalsIgnoreCase("replaceInstanceRetainAssignments")) {
573             for (RelatedInstanceList relatedInstList : dataObj.getRequestDetails().getRelatedInstanceList()) {
574                 RelatedInstance relatedInstance = relatedInstList.getRelatedInstance();
575                 if (relatedInstance.getModelInfo().getModelType().equals(ModelType.vnf)) {
576                     replaceVnfModuleCustomizationUUID = relatedInstance.getModelInfo().getModelCustomizationId();
577                 }
578             }
579             replaceVfModuleCustomizationUUID = dataObj.getRequestDetails().getModelInfo().getModelCustomizationId();
580             isReplace = true;
581         }
582
583         List<org.onap.aai.domain.yang.Vnfc> vnfcs =
584                 getRelatedResourcesInVfModule(vnfId, vfModuleId, org.onap.aai.domain.yang.Vnfc.class, Types.VNFC);
585         for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
586             WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
587             org.onap.aai.domain.yang.Configuration configuration =
588                     getRelatedResourcesInVnfc(vnfc, org.onap.aai.domain.yang.Configuration.class, Types.CONFIGURATION);
589             if (configuration == null) {
590                 logger.warn(String.format("No configuration found for VNFC %s in AAI", vnfc.getVnfcName()));
591                 continue;
592             }
593             workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
594             for (OrchestrationFlow orchFlow : result) {
595                 if (!isReplace) {
596                     dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
597                     dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
598                 } else {
599                     if (orchFlow.getFlowName().contains("Delete")) {
600                         dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
601                         dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
602                     } else {
603                         dataObj.getResourceKey().setVfModuleCustomizationId(replaceVfModuleCustomizationUUID);
604                         dataObj.getResourceKey().setVnfCustomizationId(replaceVnfModuleCustomizationUUID);
605                     }
606                 }
607                 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
608                 String vnfcName = vnfc.getVnfcName();
609                 if (vnfcName == null || vnfcName.isEmpty()) {
610                     buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
611                             + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
612                             new Exception("Vnfc and Configuration do not match"));
613                 }
614                 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
615                         dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
616                         dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(), workflowIdsCopy,
617                         dataObj.getRequestDetails(), false, null, vnfcName, true, null);
618                 flowsToExecuteConfigs.add(ebb);
619             }
620         }
621         return flowsToExecuteConfigs;
622     }
623
624     protected void buildAndThrowException(DelegateExecution execution, String msg) {
625         logger.error(msg);
626         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
627         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
628     }
629
630     protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
631         logger.error(msg, ex);
632         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
633         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
634     }
635
636     protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
637             throws Exception {
638
639         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
640         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
641
642         logger.debug("BUILDING REPLACE LIST");
643
644         boolean volumeGroupExisted = false;
645         boolean volumeGroupWillExist = false;
646         boolean keepVolumeGroup = false;
647
648         boolean rebuildVolumeGroups = false;
649         if (dataObj.getRequestDetails().getRequestParameters() != null
650                 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
651             rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
652         }
653         String volumeGroupName = "";
654         Optional<VolumeGroup> volumeGroupFromVfModule =
655                 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
656         if (volumeGroupFromVfModule.isPresent()) {
657             String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
658             volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
659             logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
660             volumeGroupExisted = true;
661             dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
662             dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
663         }
664
665         List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
666         VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
667                 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
668         if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
669                 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
670                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
671             volumeGroupWillExist = true;
672             if (!volumeGroupExisted) {
673                 String newVolumeGroupId = UUID.randomUUID().toString();
674                 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
675                 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
676                 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
677             }
678         }
679
680         if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
681             keepVolumeGroup = true;
682         }
683
684         if (!volumeGroupExisted || keepVolumeGroup) {
685             logger.debug("Filtering out deletion of volume groups");
686             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
687                     .collect(Collectors.toList());
688         }
689         if (!volumeGroupWillExist || keepVolumeGroup) {
690             logger.debug("Filtering out creation of volume groups");
691             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
692                     .collect(Collectors.toList());
693         }
694
695         return orchFlows;
696     }
697
698     protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
699         int count = 0;
700         for (Resource resource : vfModuleResources) {
701             if (resource.isBaseVfModule()) {
702                 Collections.swap(vfModuleResources, 0, count);
703                 break;
704             }
705             count++;
706         }
707         return vfModuleResources;
708     }
709
710     protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
711         int count = 0;
712         for (Resource resource : vfModuleResources) {
713             if (resource.isBaseVfModule()) {
714                 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
715                 break;
716             }
717             count++;
718         }
719         return vfModuleResources;
720     }
721
722     private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
723             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
724         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
725             logger.debug(pair.getValue0() + ", " + pair.getValue1());
726         }
727
728         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
729                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
730                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
731                                 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
732     }
733
734     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
735         String id = null;
736         for (int i = 0; i < aaiResourceIds.size(); i++) {
737             if (aaiResourceIds.get(i).getValue0() == resource) {
738                 id = aaiResourceIds.get(i).getValue1();
739                 aaiResourceIds.remove(i);
740                 break;
741             }
742         }
743         return id;
744     }
745
746     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
747             String serviceInstanceId) {
748         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
749                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
750                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
751                                 null, resource.getVirtualLinkKey(), serviceInstanceId)));
752     }
753
754     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
755             String key, String id, String virtualLinkKey, String serviceInstanceId) {
756         String resourceId = id;
757         if (resourceId == null) {
758             resourceId = UUID.randomUUID().toString();
759         }
760         for (ExecuteBuildingBlock ebb : flowsToExecute) {
761             if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
762                     .getBpmnFlowName().contains(resourceType.toString())
763                     || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
764                             && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
765                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
766                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
767                 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
768                 ebb.setWorkflowResourceIds(workflowResourceIds);
769             }
770             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
771                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
772                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
773                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
774                 workflowResourceIds.setNetworkId(resourceId);
775                 ebb.setWorkflowResourceIds(workflowResourceIds);
776             }
777         }
778     }
779
780     protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
781             org.onap.so.db.catalog.beans.Service service) {
782         CollectionResourceCustomization networkCollection = null;
783         int count = 0;
784         for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
785             if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
786                     collectionCust.getModelCustomizationUUID()) != null) {
787                 networkCollection = collectionCust;
788                 count++;
789             }
790         }
791         if (count == 0) {
792             return null;
793         } else if (count > 1) {
794             buildAndThrowException(execution,
795                     "Found multiple Network Collections in the Service model, only one per Service is supported.");
796         }
797         return networkCollection;
798     }
799
800     protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
801             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
802             throws JsonProcessingException, VrfBondingServiceException {
803         String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
804         org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
805
806         if (service == null) {
807             buildAndThrowException(execution, "Could not find the service model in catalog db.");
808         } else {
809             resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
810             RelatedInstance relatedVpnBinding =
811                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
812             RelatedInstance relatedLocalNetwork =
813                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
814
815             if (relatedVpnBinding != null && relatedLocalNetwork != null) {
816                 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
817             } else {
818                 traverseNetworkCollection(execution, resourceList, service);
819             }
820         }
821     }
822
823     protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
824             List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
825             RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
826             throws VrfBondingServiceException, JsonProcessingException {
827         org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
828                 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
829         vrfValidation.vrfServiceValidation(service);
830         vrfValidation.vrfCatalogDbChecks(service);
831         vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
832                 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
833         vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
834         vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
835         vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
836         vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
837         String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
838         if (existingAAIVrfConfiguration != null) {
839             aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
840         }
841         resourceList.add(new Resource(WorkflowType.CONFIGURATION,
842                 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
843
844     }
845
846     protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
847             org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
848             throws JsonProcessingException, VrfBondingServiceException {
849         Optional<Relationships> relationshipsOp = new AAIResultWrapper(
850                 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
851         if (relationshipsOp.isPresent()) {
852             List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
853                     relationshipsOp.get().getByType(Types.CONFIGURATION);
854             if (configurationsRelatedToLocalNetwork.size() > 1) {
855                 throw new VrfBondingServiceException(
856                         "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
857             }
858             if (configurationsRelatedToLocalNetwork.size() == 1) {
859                 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
860                 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
861                 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
862                         relatedConfiguration.get(), configWrapper)) {
863                     return relatedConfiguration.get().getConfigurationId();
864                 }
865             }
866         }
867         return null;
868     }
869
870     protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
871             AAIResultWrapper configWrapper) throws VrfBondingServiceException {
872         if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
873             Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
874             if (relationshipsConfigOp.isPresent()) {
875                 Optional<VpnBinding> relatedInfraVpnBindingOp =
876                         workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
877                 if (relatedInfraVpnBindingOp.isPresent()) {
878                     VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
879                     if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
880                         throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
881                                 + " is not connected to the same vpn binding id provided in request: "
882                                 + relatedVpnBinding.getInstanceId());
883                     } else {
884                         return true;
885                     }
886                 }
887             }
888         }
889         return false;
890     }
891
892     protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
893             org.onap.so.db.catalog.beans.Service service) {
894         if (isVnfCustomizationsInTheService(service)) {
895             buildAndThrowException(execution,
896                     "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");
897         }
898         if (isPnfCustomizationsInTheService(service)) {
899             buildAndThrowException(execution,
900                     "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");
901         }
902         List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
903         if (customizations.isEmpty()) {
904             logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
905         } else {
906             CollectionResourceCustomization collectionResourceCustomization =
907                     findCatalogNetworkCollection(execution, service);
908             traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
909         }
910         traverseNetworkCollectionCustomization(resourceList, service);
911     }
912
913     private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
914             CollectionResourceCustomization collectionResourceCustomization) {
915         if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
916             return;
917         int minNetworks = 0;
918         org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
919                 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
920         CollectionResourceInstanceGroupCustomization collectionInstCust = null;
921         if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
922             for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
923                     .getCollectionInstanceGroupCustomizations()) {
924                 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
925                         .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
926                     collectionInstCust = collectionInstanceGroupTemp;
927                     break;
928                 }
929             }
930             if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
931                 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
932             }
933         }
934         logger.debug("minNetworks: {}", minNetworks);
935         CollectionNetworkResourceCustomization collectionNetworkResourceCust =
936                 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
937         for (int i = 0; i < minNetworks; i++) {
938             if (collectionNetworkResourceCust != null) {
939                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
940                         collectionNetworkResourceCust.getModelCustomizationUUID(), false);
941                 resource.setVirtualLinkKey(Integer.toString(i));
942                 resourceList.add(resource);
943             }
944         }
945     }
946
947     private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
948             CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
949         CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
950         for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
951                 .getCollectionNetworkResourceCustomizations()) {
952             if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
953                     .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
954                 collectionNetworkResourceCust = collectionNetworkTemp;
955                 break;
956             }
957         }
958         return collectionNetworkResourceCust;
959     }
960
961     private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
962             CollectionResourceCustomization collectionResourceCustomization) {
963         if (collectionResourceCustomization == null) {
964             logger.debug("No Network Collection Customization found");
965             return true;
966         }
967         resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
968                 collectionResourceCustomization.getModelCustomizationUUID(), false));
969         logger.debug("Found a network collection");
970         if (collectionResourceCustomization.getCollectionResource() == null) {
971             logger.debug("No Network Collection found. collectionResource is null");
972             return true;
973         }
974         if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
975             logger.debug("No Instance Group found for network collection.");
976             return true;
977         }
978         String toscaNodeType =
979                 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
980         if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
981             logger.debug("Instance Group tosca node type does not contain NetworkCollection:  {}", toscaNodeType);
982             return true;
983         }
984         return false;
985     }
986
987     private boolean interfaceNetworkQuantityIsAvailableInCollection(
988             CollectionResourceInstanceGroupCustomization collectionInstCust) {
989         return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
990     }
991
992     private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
993         return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
994     }
995
996     private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
997             org.onap.so.db.catalog.beans.Service service) {
998         if (isNetworkCollectionInTheResourceList(resourceList)) {
999             return;
1000         }
1001         if (service.getNetworkCustomizations() == null) {
1002             logger.debug("No networks were found on this service model");
1003             return;
1004         }
1005         for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
1006             resourceList.add(new Resource(WorkflowType.NETWORK,
1007                     service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
1008         }
1009     }
1010
1011     private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
1012         return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
1013     }
1014
1015     private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
1016         return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
1017     }
1018
1019     private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
1020         return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
1021     }
1022
1023     protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
1024             List<Pair<WorkflowType, String>> aaiResourceIds) {
1025         try {
1026             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
1027             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1028                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1029             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1030             traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
1031             traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
1032             if (serviceInstanceMSO.getNetworks() != null) {
1033                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
1034                         .getNetworks()) {
1035                     aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
1036                     resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
1037                 }
1038             }
1039             if (serviceInstanceMSO.getCollection() != null) {
1040                 logger.debug("found networkcollection");
1041                 aaiResourceIds
1042                         .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
1043                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
1044                         serviceInstanceMSO.getCollection().getId(), false));
1045             }
1046             if (serviceInstanceMSO.getConfigurations() != null) {
1047                 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
1048                     Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
1049                             aaiConfigurationResources.getConfiguration(config.getConfigurationId());
1050                     if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
1051                         for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
1052                             if (relationship.getRelatedTo().contains("vnfc")
1053                                     || relationship.getRelatedTo().contains("vpn-binding")) {
1054                                 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
1055                                 resourceList.add(
1056                                         new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
1057                                 break;
1058                             }
1059                         }
1060                     }
1061                 }
1062             }
1063         } catch (Exception ex) {
1064             logger.error("Exception in traverseAAIService", ex);
1065             buildAndThrowException(execution,
1066                     "Could not find existing Service Instance or related Instances to execute the request on.");
1067         }
1068     }
1069
1070     private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
1071             List<Pair<WorkflowType, String>> aaiResourceIds,
1072             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1073         if (serviceInstanceMSO.getVnfs() == null) {
1074             return;
1075         }
1076         for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1077             aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1078             resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1079             traverseVnfModules(resourceList, aaiResourceIds, vnf);
1080             if (vnf.getVolumeGroups() != null) {
1081                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
1082                     aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1083                     resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1084                 }
1085             }
1086         }
1087     }
1088
1089     private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
1090             List<Pair<WorkflowType, String>> aaiResourceIds,
1091             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
1092         if (serviceInstanceMSO.getPnfs() == null) {
1093             return;
1094         }
1095         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
1096             aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
1097             resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
1098         }
1099     }
1100
1101     private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1102             org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1103         if (vnf.getVfModules() == null) {
1104             return;
1105         }
1106         for (VfModule vfModule : vnf.getVfModules()) {
1107             aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1108             Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1109             resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1110             resourceList.add(resource);
1111         }
1112     }
1113
1114     private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1115             String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1116         try {
1117             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1118             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1119                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1120             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1121             if (serviceInstanceMSO.getVnfs() != null) {
1122                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1123                     if (vnf.getVnfId().equals(vnfId)) {
1124                         aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1125                         resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1126                         if (vnf.getVfModules() != null) {
1127                             for (VfModule vfModule : vnf.getVfModules()) {
1128                                 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1129                                 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1130                                 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1131                                         resourceList, aaiResourceIds);
1132                             }
1133                         }
1134                         if (vnf.getVolumeGroups() != null) {
1135                             for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1136                                     .getVolumeGroups()) {
1137                                 aaiResourceIds
1138                                         .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1139                                 resourceList.add(
1140                                         new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1141                             }
1142                         }
1143                         break;
1144                     }
1145                 }
1146             }
1147         } catch (Exception ex) {
1148             logger.error("Exception in traverseAAIVnf", ex);
1149             buildAndThrowException(execution,
1150                     "Could not find existing Vnf or related Instances to execute the request on.");
1151         }
1152     }
1153
1154     private void customTraverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1155             String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1156         try {
1157             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1158             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1159                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1160             resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1161             if (serviceInstanceMSO.getVnfs() != null) {
1162                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1163                     if (vnf.getVnfId().equals(vnfId)) {
1164                         aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1165
1166                         String vnfCustomizationUUID =
1167                                 bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
1168                         resourceList.add(new Resource(WorkflowType.VNF, vnfCustomizationUUID, false));
1169
1170                         if (vnf.getVfModules() != null) {
1171                             for (VfModule vfModule : vnf.getVfModules()) {
1172                                 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1173                                 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1174                                 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1175                                         resourceList, aaiResourceIds);
1176                             }
1177                         }
1178                         if (vnf.getVolumeGroups() != null) {
1179                             for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1180                                     .getVolumeGroups()) {
1181                                 aaiResourceIds
1182                                         .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1183                                 resourceList.add(
1184                                         new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1185                             }
1186                         }
1187                         break;
1188                     }
1189                 }
1190             }
1191         } catch (Exception ex) {
1192             logger.error("Exception in customTraverseAAIVnf", ex);
1193             buildAndThrowException(execution,
1194                     "Could not find existing Vnf or related Instances to execute the request on.");
1195         }
1196
1197     }
1198
1199     private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1200             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1201         try {
1202             org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1203             AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1204                     new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1205             Optional<Relationships> relationshipsOp;
1206             relationshipsOp = vfModuleWrapper.getRelationships();
1207             if (relationshipsOp.isPresent()) {
1208                 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1209                 if (relationshipsOp.isPresent()) {
1210                     Optional<Configuration> config =
1211                             workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1212                     if (config.isPresent()) {
1213                         aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1214                         resourceList.add(
1215                                 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1216                     }
1217                 }
1218             }
1219         } catch (Exception ex) {
1220             logger.error("Exception in findConfigurationsInsideVfModule", ex);
1221             buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1222         }
1223     }
1224
1225     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1226         return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1227     }
1228
1229     protected Resource extractResourceIdAndTypeFromUri(String uri) {
1230         Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1231                 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1232         Matcher m = patt.matcher(uri);
1233         boolean generated = false;
1234
1235         if (m.find()) {
1236             logger.debug("found match on {} : {} ", uri, m);
1237             String type = m.group("type");
1238             String id = m.group("id");
1239             String action = m.group("action");
1240             if (type == null) {
1241                 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1242             }
1243             if (action == null) {
1244                 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1245                     id = UUID.randomUUID().toString();
1246                     generated = true;
1247                 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1248                     id = UUID.randomUUID().toString();
1249                     generated = true;
1250                 }
1251             } else {
1252                 if (action.matches(SUPPORTEDTYPES)) {
1253                     id = UUID.randomUUID().toString();
1254                     generated = true;
1255                     type = action;
1256                 }
1257             }
1258             return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1259         } else {
1260             throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1261         }
1262     }
1263
1264     protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1265             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1266         try {
1267             if ("SERVICE".equalsIgnoreCase(type.toString())) {
1268                 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1269             } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1270                 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1271                         workflowResourceIds);
1272             } else if ("VNF".equalsIgnoreCase(type.toString())) {
1273                 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1274             } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1275                 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1276                         workflowResourceIds);
1277             } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1278                 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1279                         workflowResourceIds);
1280             } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1281                 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1282                         workflowResourceIds);
1283             }
1284             return generatedResourceId;
1285         } catch (DuplicateNameException dne) {
1286             throw dne;
1287         } catch (Exception ex) {
1288             logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1289             throw new IllegalStateException(
1290                     WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1291         }
1292     }
1293
1294     protected String convertTypeFromPlural(String type) {
1295         if (!type.matches(SUPPORTEDTYPES)) {
1296             return type;
1297         } else {
1298             if (type.equals(SERVICE_INSTANCES)) {
1299                 return SERVICE;
1300             } else {
1301                 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1302             }
1303         }
1304     }
1305
1306     protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1307             String requestAction) {
1308         List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1309         if (requestAction.equals(CREATE_INSTANCE)) {
1310             for (ExecuteBuildingBlock ebb : orchFlows) {
1311                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1312                     String key = ebb.getBuildingBlock().getKey();
1313                     boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1314                     String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1315                     sortedOrchFlows.add(ebb);
1316                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1317                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1318                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1319                             sortedOrchFlows.add(ebb2);
1320                             break;
1321                         }
1322                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1323                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1324                             sortedOrchFlows.add(ebb2);
1325                             break;
1326                         }
1327                     }
1328                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1329                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1330                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1331                             sortedOrchFlows.add(ebb2);
1332                             break;
1333                         }
1334                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1335                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1336                             sortedOrchFlows.add(ebb2);
1337                             break;
1338                         }
1339                     }
1340                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1341                         || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1342                     continue;
1343                 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1344                     sortedOrchFlows.add(ebb);
1345                 }
1346             }
1347         } else if (requestAction.equals("deleteInstance")) {
1348             for (ExecuteBuildingBlock ebb : orchFlows) {
1349                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1350                     sortedOrchFlows.add(ebb);
1351                     String key = ebb.getBuildingBlock().getKey();
1352                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1353                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1354                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1355                             sortedOrchFlows.add(ebb2);
1356                             break;
1357                         }
1358                     }
1359                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
1360                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1361                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1362                             sortedOrchFlows.add(ebb2);
1363                             break;
1364                         }
1365                     }
1366                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1367                         || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1368                     continue;
1369                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1370                     sortedOrchFlows.add(ebb);
1371                 }
1372             }
1373         }
1374         return sortedOrchFlows;
1375     }
1376
1377     private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1378             WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1379             String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1380             RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1381
1382         resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1383                 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1384                         apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1385                         isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration, null)));
1386     }
1387
1388     protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1389             List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1390             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1391             boolean replaceVnf) {
1392         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1393         for (OrchestrationFlow orchFlow : orchFlows) {
1394             if (orchFlow.getFlowName().contains(SERVICE)) {
1395                 if (!replaceVnf) {
1396                     workflowResourceIds.setServiceInstanceId(resourceId);
1397                 }
1398                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1399                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1400                         false);
1401             } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1402                     && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1403                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1404                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1405                         false);
1406             } else if (orchFlow.getFlowName().contains(PNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1407                     && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1408                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1409                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1410                         false);
1411             } else if (orchFlow.getFlowName().contains(NETWORK)
1412                     && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1413                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1414                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1415                         false);
1416                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1417                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1418                         true, false);
1419             } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1420                     && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1421                 List<Resource> vfModuleResourcesSorted;
1422                 if (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1423                         || requestAction.equals("activateInstance")) {
1424                     vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1425                             .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1426                 } else {
1427                     vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1428                             .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1429                 }
1430                 for (Resource resource : vfModuleResourcesSorted) {
1431                     flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
1432                             requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
1433                             false, null));
1434                 }
1435             } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1436                 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1437                         || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1438                     logger.debug("Replacing workflow resource id by volume group id");
1439                     resourceId = workflowResourceIds.getVolumeGroupId();
1440                 }
1441                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1442                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1443                         false, false);
1444             } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1445                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1446                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1447                         false, false);
1448             } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1449                 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1450                         requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1451                         false, true);
1452             } else {
1453                 flowsToExecute
1454                         .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
1455                                 false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
1456             }
1457         }
1458         return flowsToExecute;
1459     }
1460
1461     protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1462             Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1463             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1464             boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
1465             ReplaceInstanceRelatedInformation replaceInfo) {
1466
1467         BuildingBlock buildingBlock =
1468                 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1469                         .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1470                         .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1471         Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
1472         Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
1473         String oldVolumeGroupName = "";
1474         if (replaceInfo != null) {
1475             oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
1476         }
1477         if (resource != null
1478                 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1479                         || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1480             logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1481             resourceId = workflowResourceIds.getVolumeGroupId();
1482         }
1483
1484         ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1485                 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1486                 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1487                 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
1488
1489         if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1490             ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
1491             executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1492         }
1493         return executeBuildingBlock;
1494     }
1495
1496     private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1497         ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1498         Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1499         configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1500         configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1501         configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1502         return configurationResourceKeys;
1503     }
1504
1505     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1506             WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1507         return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1508     }
1509
1510     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1511             WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1512         List<OrchestrationFlow> listToExecute = new ArrayList<>();
1513         NorthBoundRequest northBoundRequest;
1514         if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1515                 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1516             northBoundRequest =
1517                     catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1518                             requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1519         } else {
1520             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1521                     requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1522         }
1523         if (northBoundRequest == null) {
1524             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1525                     requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1526         }
1527         if (northBoundRequest == null) {
1528             buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1529                     (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1530         } else {
1531             if (northBoundRequest.getIsToplevelflow() != null) {
1532                 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1533             }
1534             List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1535             if (flows == null) {
1536                 flows = new ArrayList<>();
1537             } else {
1538                 flows.sort(Comparator.comparingInt(OrchestrationFlow::getSequenceNumber));
1539             }
1540             for (OrchestrationFlow flow : flows) {
1541                 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1542                     List<OrchestrationFlow> macroQueryFlows =
1543                             catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1544                     listToExecute.addAll(macroQueryFlows);
1545                 } else {
1546                     listToExecute.add(flow);
1547                 }
1548             }
1549         }
1550         return listToExecute;
1551     }
1552
1553     public void handleRuntimeException(DelegateExecution execution) {
1554         StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1555         String runtimeErrorMessage;
1556         try {
1557             String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1558             if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1559                 wfeExpMsg.append(": ").append(javaExpMsg);
1560             }
1561             runtimeErrorMessage = wfeExpMsg.toString();
1562             logger.error(runtimeErrorMessage);
1563             execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1564         } catch (Exception e) {
1565             logger.error("Runtime error", e);
1566             // if runtime message was mulformed
1567             runtimeErrorMessage = "Runtime error";
1568         }
1569         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1570     }
1571
1572     protected boolean isUriResume(String uri) {
1573         return uri.endsWith("/resume");
1574     }
1575
1576     protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1577             String serviceInstanceId) {
1578         return (!aLaCarte && resourceType == WorkflowType.SERVICE
1579                 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
1580                 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1581                 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1582     }
1583
1584     protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1585             RequestDetails reqDetails) throws DuplicateNameException {
1586         String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1587         String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1588         if (instanceName != null) {
1589             Optional<ServiceInstance> serviceInstanceAAI =
1590                     bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1591             if (serviceInstanceAAI.isPresent()) {
1592                 if (serviceInstanceAAI.get().getModelVersionId()
1593                         .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1594                     return serviceInstanceAAI.get().getServiceInstanceId();
1595                 } else {
1596                     throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1597                             instanceName, reqDetails.getModelInfo().getModelVersionId()));
1598                 }
1599             } else {
1600                 ServiceInstances aaiServiceInstances =
1601                         bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1602                 if (aaiServiceInstances != null) {
1603                     if (aaiServiceInstances.getServiceInstance() != null
1604                             && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1605                         if (aaiServiceInstances.getServiceInstance().size() > 1) {
1606                             throw new DuplicateNameException(SERVICE_INSTANCE,
1607                                     String.format(NAME_EXISTS_MULTIPLE, instanceName));
1608                         } else {
1609                             ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1610                             Map<String, String> keys =
1611                                     bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1612
1613                             throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1614                                     NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1615                                     keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1616                                     keys.get(
1617                                             AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1618                                     si.getModelVersionId()));
1619                         }
1620                     }
1621                 }
1622             }
1623         }
1624         return generatedResourceId;
1625     }
1626
1627     protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1628             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1629             throws DuplicateNameException, MultipleObjectsFoundException {
1630         Optional<L3Network> network = bbInputSetupUtils
1631                 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1632         if (network.isPresent()) {
1633             if (network.get().getModelCustomizationId()
1634                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1635                 return network.get().getNetworkId();
1636             } else {
1637                 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1638                         instanceName, network.get().getModelCustomizationId()));
1639             }
1640         }
1641         if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1642             throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1643                     workflowResourceIds.getServiceInstanceId()));
1644         }
1645         return generatedResourceId;
1646     }
1647
1648     protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1649             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1650         Optional<GenericVnf> vnf = bbInputSetupUtils
1651                 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1652         if (vnf.isPresent()) {
1653             if (vnf.get().getModelCustomizationId()
1654                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1655                 return vnf.get().getVnfId();
1656             } else {
1657                 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1658                         instanceName, vnf.get().getModelCustomizationId()));
1659             }
1660         }
1661         GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1662         if (vnfs != null) {
1663             throw new DuplicateNameException("generic-vnf",
1664                     String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1665         }
1666         return generatedResourceId;
1667     }
1668
1669     protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1670             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1671         GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1672         if (vnf != null && vnf.getVfModules() != null) {
1673             for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1674                 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1675                     if (vfModule.getModelCustomizationId()
1676                             .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1677                         return vfModule.getVfModuleId();
1678                     } else {
1679                         throw new DuplicateNameException("vfModule",
1680                                 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1681                                         reqDetails.getModelInfo().getModelCustomizationId()));
1682                     }
1683                 }
1684             }
1685         }
1686         if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1687             throw new DuplicateNameException("vfModule", instanceName);
1688         }
1689         return generatedResourceId;
1690     }
1691
1692     protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1693             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1694         Optional<VolumeGroup> volumeGroup =
1695                 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1696         if (volumeGroup.isPresent()) {
1697             if (volumeGroup.get().getVfModuleModelCustomizationId()
1698                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1699                 return volumeGroup.get().getVolumeGroupId();
1700             } else {
1701                 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1702             }
1703         }
1704         if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1705             throw new DuplicateNameException("volumeGroup", instanceName);
1706         }
1707         return generatedResourceId;
1708     }
1709
1710     protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1711             RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1712         Optional<org.onap.aai.domain.yang.Configuration> configuration =
1713                 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1714                         workflowResourceIds.getServiceInstanceId(), instanceName);
1715         if (configuration.isPresent()) {
1716             if (configuration.get().getModelCustomizationId()
1717                     .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1718                 return configuration.get().getConfigurationId();
1719             } else {
1720                 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1721                         instanceName, configuration.get().getConfigurationId()));
1722             }
1723         }
1724         if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1725             throw new DuplicateNameException("configuration", instanceName);
1726         }
1727         return generatedResourceId;
1728     }
1729
1730     protected boolean foundRelated(List<Resource> resourceList) {
1731         return (containsWorkflowType(resourceList, WorkflowType.VNF)
1732                 || containsWorkflowType(resourceList, WorkflowType.PNF)
1733                 || containsWorkflowType(resourceList, WorkflowType.NETWORK)
1734                 || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
1735     }
1736
1737     protected boolean containsWorkflowType(List<Resource> resourceList, WorkflowType workflowType) {
1738         return resourceList.stream().anyMatch(resource -> resource.getResourceType().equals(workflowType));
1739     }
1740
1741     private void fillExecutionDefault(DelegateExecution execution) {
1742         execution.setVariable("sentSyncResponse", false);
1743         execution.setVariable(HOMING, false);
1744         execution.setVariable("calledHoming", false);
1745         execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1746     }
1747
1748     private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1749             WorkflowType resourceType) {
1750         execution.setVariable("suppressRollback", suppressRollback);
1751         execution.setVariable("resourceId", resourceId);
1752         execution.setVariable("resourceType", resourceType);
1753         execution.setVariable("resourceName", resourceType.toString());
1754     }
1755
1756     private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1757             String requestId) {
1758         if (!alaCarte && isResume) {
1759             logger.debug("replacing URI {}", uri);
1760             uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1761             logger.debug("for RESUME with original value {}", uri);
1762         }
1763         return extractResourceIdAndTypeFromUri(uri);
1764     }
1765
1766     private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1767             WorkflowResourceIds workflowResourceIds) throws Exception {
1768         if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1769                 && requestDetails.getRequestInfo().getInstanceName() != null) {
1770             return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1771                     requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1772         } else {
1773             return resource.getResourceId();
1774         }
1775     }
1776
1777     private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1778         String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1779         if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1780             serviceInstanceId = resourceId;
1781         }
1782         return serviceInstanceId;
1783     }
1784
1785 }