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