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