ef32ac5cbb15fee98070a0c0796fc160c90cd377
[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) 2021 Nokia
10  * ================================================================================
11  * Modifications Copyright (c) 2020 Tech Mahindra
12  * ================================================================================
13  * Modifications Copyright (c) 2021 Orange
14  * ================================================================================
15  * Licensed under the Apache License, Version 2.0 (the "License");
16  * you may not use this file except in compliance with the License.
17  * You may obtain a copy of the License at
18  *
19  *      http://www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing, software
22  * distributed under the License is distributed on an "AS IS" BASIS,
23  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24  * See the License for the specific language governing permissions and
25  * limitations under the License.
26  * ============LICENSE_END=========================================================
27  */
28
29 package org.onap.so.bpmn.infrastructure.workflow.tasks;
30
31 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
32 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CONTROLLER;
33 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
34 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
35 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
36 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.RECREATE_INSTANCE;
37 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCE;
38 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCERETAINASSIGNMENTS;
39 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.SERVICE;
40 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPDATE_INSTANCE;
41 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.HEALTH_CHECK;
42 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
43 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPGRADE_CNF;
44 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Comparator;
48 import java.util.HashMap;
49 import java.util.LinkedHashSet;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.Optional;
53 import java.util.Set;
54 import java.util.UUID;
55 import java.util.regex.Matcher;
56 import java.util.regex.Pattern;
57 import java.util.stream.Collectors;
58 import org.apache.commons.lang3.SerializationUtils;
59 import org.apache.commons.lang3.StringUtils;
60 import org.camunda.bpm.engine.delegate.DelegateExecution;
61 import org.javatuples.Pair;
62 import org.onap.aai.domain.yang.Vnfc;
63 import org.onap.aai.domain.yang.VolumeGroup;
64 import org.onap.aaiclient.client.aai.AAIObjectName;
65 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
66 import org.onap.aaiclient.client.aai.entities.Relationships;
67 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
68 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
69 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
70 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
71 import org.onap.so.bpmn.common.BBConstants;
72 import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.ServiceEBBLoader;
73 import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.VnfEBBLoader;
74 import org.onap.so.bpmn.infrastructure.workflow.tasks.excpetion.VnfcMultipleRelationshipException;
75 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
76 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
77 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
78 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
79 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
80 import org.onap.so.client.exception.ExceptionBuilder;
81 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
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.RelatedInstance;
90 import org.onap.so.serviceinstancebeans.RelatedInstanceList;
91 import org.onap.so.serviceinstancebeans.RequestDetails;
92 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
95 import org.springframework.beans.factory.annotation.Autowired;
96 import org.springframework.core.env.Environment;
97 import org.springframework.stereotype.Component;
98 import org.springframework.util.CollectionUtils;
99 import com.fasterxml.jackson.databind.ObjectMapper;
100
101 @Component
102 public class WorkflowAction {
103
104     private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
105
106     private static final String SERVICE_INSTANCES = "serviceInstances";
107     private static final String VF_MODULES = "vfModules";
108     private static final String VNF_TYPE = "vnfType";
109     private static final String CONFIGURATION = "Configuration";
110     private static final String SUPPORTEDTYPES =
111             "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
112     private static final String HOMINGSOLUTION = "Homing_Solution";
113     private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
114     private static final String SERVICE_TYPE_BONDING = "BONDING";
115     private static final String CLOUD_OWNER = "DEFAULT";
116     private static final String CREATENETWORKBB = "CreateNetworkBB";
117     private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
118     private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
119     private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
120     private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
121     private static final String HOMING = "homing";
122
123     @Autowired
124     protected BBInputSetup bbInputSetup;
125     @Autowired
126     protected BBInputSetupUtils bbInputSetupUtils;
127     @Autowired
128     private ExceptionBuilder exceptionBuilder;
129     @Autowired
130     private CatalogDbClient catalogDbClient;
131     @Autowired
132     private Environment environment;
133     @Autowired
134     private AaiResourceIdValidator aaiResourceIdValidator;
135     @Autowired
136     private ExecuteBuildingBlockBuilder executeBuildingBlockBuilder;
137     @Autowired
138     private VnfEBBLoader vnfEBBLoader;
139     @Autowired
140     private ServiceEBBLoader serviceEBBLoader;
141
142     public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
143         this.bbInputSetupUtils = bbInputSetupUtils;
144     }
145
146     public void setBbInputSetup(BBInputSetup bbInputSetup) {
147         this.bbInputSetup = bbInputSetup;
148     }
149
150     public void selectExecutionList(DelegateExecution execution) throws Exception {
151         try {
152             fillExecutionDefault(execution);
153             final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
154             ServiceInstancesRequest sIRequest =
155                     new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
156
157             final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
158
159             String uri = (String) execution.getVariable(BBConstants.G_URI);
160             boolean isResume = isUriResume(uri);
161
162             final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
163             Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
164
165             WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
166             RequestDetails requestDetails = sIRequest.getRequestDetails();
167             String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
168             String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
169             WorkflowType resourceType = resource.getResourceType();
170
171             String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
172
173             fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
174             List<ExecuteBuildingBlock> flowsToExecute;
175             if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
176                 String errorMessage = "Could not resume Macro flow. Error loading execution path.";
177                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
178             } else if (isALaCarte && isResume) {
179                 String errorMessage =
180                         "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
181                 flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
182             } else {
183                 String vnfType = (String) execution.getVariable(VNF_TYPE);
184                 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
185                 List<OrchestrationFlow> orchFlows =
186                         (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
187                 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
188                 final String serviceType =
189                         Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
190                 if (isALaCarte) {
191                     flowsToExecute = loadExecuteBuildingBlocksForAlaCarte(orchFlows, execution, requestAction,
192                             resourceType, cloudOwner, serviceType, sIRequest, requestId, workflowResourceIds,
193                             requestDetails, resourceId, vnfType, apiVersion);
194                 } else {
195                     flowsToExecute = loadExecuteBuildingBlocksForMacro(sIRequest, resourceType, requestAction,
196                             execution, serviceInstanceId, resourceId, workflowResourceIds, orchFlows, cloudOwner,
197                             serviceType, requestId, apiVersion, vnfType, requestDetails);
198                 }
199             }
200             // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
201             // enable it.
202             if (sIRequest.getRequestDetails().getRequestParameters() != null
203                     && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
204                 List<Map<String, Object>> userParams =
205                         sIRequest.getRequestDetails().getRequestParameters().getUserParams();
206                 for (Map<String, Object> params : userParams) {
207                     if (params.containsKey(HOMINGSOLUTION)) {
208                         execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
209                     }
210                 }
211             }
212
213             if (CollectionUtils.isEmpty(flowsToExecute)) {
214                 throw new IllegalStateException("Macro did not come up with a valid execution path.");
215             }
216
217             List<String> flowNames = new ArrayList<>();
218             logger.info("List of BuildingBlocks to execute:");
219
220             flowsToExecute.forEach(ebb -> {
221                 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
222                 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
223             });
224
225             if (!isResume) {
226                 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
227             }
228             setExecutionVariables(execution, flowsToExecute, flowNames);
229
230         } catch (Exception ex) {
231             if (!(execution.hasVariable("WorkflowException")
232                     || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
233                 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
234             } else {
235                 throw ex;
236             }
237         }
238     }
239
240     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocksForAlaCarte(List<OrchestrationFlow> orchFlows,
241             DelegateExecution execution, String requestAction, WorkflowType resourceType, String cloudOwner,
242             String serviceType, ServiceInstancesRequest sIRequest, String requestId,
243             WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, String resourceId, String vnfType,
244             String apiVersion) throws Exception {
245         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
246         if (orchFlows == null || orchFlows.isEmpty()) {
247             orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true, cloudOwner,
248                     serviceType);
249         }
250         Resource resourceKey = getResourceKey(sIRequest, resourceType);
251
252         ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
253         if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
254                 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
255                 && resourceType.equals(WorkflowType.VFMODULE)) {
256             logger.debug("Build a BB list for replacing BB modules");
257             ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
258                     workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, orchFlows, apiVersion,
259                     resourceKey, replaceInfo);
260             orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
261
262             createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds, requestDetails,
263                     requestAction, resourceId, flowsToExecute, vnfType, orchFlows, apiVersion, resourceKey,
264                     replaceInfo);
265         } else {
266             if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
267                 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
268                         requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
269                         replaceInfo, orchFlows);
270             }
271             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
272                     .collect(Collectors.toList());
273
274             for (OrchestrationFlow orchFlow : orchFlows) {
275                 ExecuteBuildingBlock ebb = executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, requestId,
276                         resourceKey, apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
277                         requestDetails, false, null, null, false, replaceInfo);
278                 flowsToExecute.add(ebb);
279             }
280         }
281         return flowsToExecute;
282     }
283
284     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocksForMacro(ServiceInstancesRequest sIRequest,
285             WorkflowType resourceType, String requestAction, DelegateExecution execution, String serviceInstanceId,
286             String resourceId, WorkflowResourceIds workflowResourceIds, List<OrchestrationFlow> orchFlows,
287             String cloudOwner, String serviceType, String requestId, String apiVersion, String vnfType,
288             RequestDetails requestDetails) throws IOException, VrfBondingServiceException {
289         List<ExecuteBuildingBlock> flowsToExecute;
290         List<Resource> resourceList = new ArrayList<>();
291         List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
292
293         if (resourceType == WorkflowType.SERVICE || isVNFCreate(resourceType, requestAction)) {
294             resourceList = serviceEBBLoader.getResourceListForService(sIRequest, requestAction, execution,
295                     serviceInstanceId, resourceId, aaiResourceIds);
296         } else if (resourceType == WorkflowType.VNF
297                 && (DELETE_INSTANCE.equalsIgnoreCase(requestAction) || REPLACEINSTANCE.equalsIgnoreCase(requestAction)
298                         || (RECREATE_INSTANCE.equalsIgnoreCase(requestAction)))) {
299             vnfEBBLoader.traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
300                     workflowResourceIds.getVnfId(), aaiResourceIds);
301         } else if (resourceType == WorkflowType.VNF && UPDATE_INSTANCE.equalsIgnoreCase(requestAction)) {
302             vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
303                     workflowResourceIds.getVnfId(), aaiResourceIds);
304         } else if (resourceType == WorkflowType.VNF && HEALTH_CHECK.equalsIgnoreCase(requestAction)) {
305             vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
306                     workflowResourceIds.getVnfId(), aaiResourceIds);
307         } else if (resourceType == WorkflowType.VNF && UPGRADE_CNF.equalsIgnoreCase(requestAction)) {
308             vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
309                     workflowResourceIds.getVnfId(), aaiResourceIds);
310         } else {
311             buildAndThrowException(execution, "Current Macro Request is not supported");
312         }
313         StringBuilder foundObjects = new StringBuilder();
314         for (WorkflowType type : WorkflowType.values()) {
315             foundObjects.append(type).append(" - ")
316                     .append((int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
317                     .append("    ");
318         }
319         logger.info("Found {}", foundObjects);
320
321         if (orchFlows == null || orchFlows.isEmpty()) {
322             orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, false, cloudOwner,
323                     serviceType);
324         }
325         boolean vnfReplace = false;
326         if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
327                 || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
328             vnfReplace = true;
329         }
330         flowsToExecute = executeBuildingBlockBuilder.buildExecuteBuildingBlockList(orchFlows, resourceList, requestId,
331                 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
332         if (serviceEBBLoader.isNetworkCollectionInTheResourceList(resourceList)) {
333             logger.info("Sorting for Vlan Tagging");
334             flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
335         }
336         logger.info("Building Block Execution Order");
337         for (ExecuteBuildingBlock block : flowsToExecute) {
338             Resource res = resourceList.stream()
339                     .filter(resource -> resource.getResourceId() == block.getBuildingBlock().getKey()).findAny()
340                     .orElse(null);
341             String log = "Block: " + block.getBuildingBlock().getBpmnFlowName();
342             if (res != null) {
343                 log += ", Resource: " + res.getResourceType() + "[" + res.getResourceId() + "]";
344                 log += ", Priority: " + res.getProcessingPriority();
345                 if (res.getResourceType() == WorkflowType.VFMODULE)
346                     log += ", Base: " + res.isBaseVfModule();
347             }
348             if (block.getBuildingBlock().getBpmnScope() != null)
349                 log += ", Scope: " + block.getBuildingBlock().getBpmnScope();
350             if (block.getBuildingBlock().getBpmnAction() != null)
351                 log += ", Action: " + block.getBuildingBlock().getBpmnAction();
352             logger.info(log);
353         }
354         // By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
355         if (resourceType == WorkflowType.SERVICE
356                 && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE))
357                 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
358             execution.setVariable(HOMING, true);
359             execution.setVariable("calledHoming", false);
360         }
361         if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)
362                 || requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
363             generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
364         } else {
365             updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds, serviceInstanceId);
366         }
367         execution.setVariable("resources", resourceList);
368         return flowsToExecute;
369     }
370
371     private boolean isVNFCreate(WorkflowType resourceType, String requestAction) {
372         return resourceType == WorkflowType.VNF && CREATE_INSTANCE.equalsIgnoreCase(requestAction);
373     }
374
375     private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
376             List<String> flowNames) {
377         execution.setVariable("flowNames", flowNames);
378         execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
379         execution.setVariable("retryCount", 0);
380         execution.setVariable("isRollback", false);
381         execution.setVariable("flowsToExecute", flowsToExecute);
382         execution.setVariable("isRollbackComplete", false);
383     }
384
385     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
386             String errorMessage) {
387         List<ExecuteBuildingBlock> flowsToExecute;
388         flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
389         if (flowsToExecute == null) {
390             buildAndThrowException(execution, errorMessage);
391         }
392         return flowsToExecute;
393     }
394
395     private ConfigBuildingBlocksDataObject createConfigBuildingBlocksDataObject(DelegateExecution execution,
396             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
397             RequestDetails requestDetails, String requestAction, String resourceId, String vnfType,
398             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
399             ReplaceInstanceRelatedInformation replaceInfo) {
400
401         return new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
402                 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
403                 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
404                 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails).setExecution(execution)
405                 .setReplaceInformation(replaceInfo);
406     }
407
408     private void createBuildingBlocksForOrchFlows(DelegateExecution execution, ServiceInstancesRequest sIRequest,
409             String requestId, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
410             String requestAction, String resourceId, List<ExecuteBuildingBlock> flowsToExecute, String vnfType,
411             List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
412             ReplaceInstanceRelatedInformation replaceInfo) throws Exception {
413
414         for (OrchestrationFlow orchFlow : orchFlows) {
415             if (orchFlow.getFlowName().contains(CONFIGURATION)) {
416                 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
417                 configOrchFlows.add(orchFlow);
418                 addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
419                         requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
420                         replaceInfo, configOrchFlows);
421             } else {
422                 ExecuteBuildingBlock ebb = executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, requestId,
423                         resourceKey, apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
424                         requestDetails, false, null, null, false, replaceInfo);
425                 flowsToExecute.add(ebb);
426             }
427         }
428     }
429
430     private void addConfigBuildingBlocksToFlowsToExecuteList(DelegateExecution execution,
431             ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
432             RequestDetails requestDetails, String requestAction, String resourceId,
433             List<ExecuteBuildingBlock> flowsToExecute, String vnfType, String apiVersion, Resource resourceKey,
434             ReplaceInstanceRelatedInformation replaceInfo, List<OrchestrationFlow> configOrchFlows) throws Exception {
435
436         ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
437                 workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, configOrchFlows, apiVersion,
438                 resourceKey, replaceInfo);
439         List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(cbbdo);
440         flowsToExecute.addAll(configBuildingBlocks);
441     }
442
443     private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
444         String resourceId = "";
445         ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
446         if (modelInfo != null) {
447             if (modelInfo.getModelType().equals(ModelType.service)) {
448                 resourceId = modelInfo.getModelVersionId();
449             } else {
450                 resourceId = modelInfo.getModelCustomizationId();
451             }
452         }
453         return new Resource(resourceType, resourceId, true, null);
454     }
455
456     private String getCloudOwner(CloudConfiguration cloudConfiguration) {
457         if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
458             return cloudConfiguration.getCloudOwner();
459         }
460         logger.warn("cloud owner value not found in request details, it will be set as default");
461         return environment.getProperty(DEFAULT_CLOUD_OWNER);
462     }
463
464     protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
465             AAIObjectName name) {
466         List<T> vnfcs = new ArrayList<>();
467         AAIResourceUri uri =
468                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
469         AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
470         Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
471         if (relationshipsOp.isEmpty()) {
472             logger.debug("No relationships were found for vfModule in AAI");
473         } else {
474             Relationships relationships = relationshipsOp.get();
475             List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(name);
476             for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
477                 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
478                 vnfcOp.ifPresent(vnfcs::add);
479             }
480         }
481         return vnfcs;
482     }
483
484     protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name)
485             throws VnfcMultipleRelationshipException {
486         T configuration = null;
487         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
488         AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
489         Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
490         if (relationshipsOp.isEmpty()) {
491             logger.debug("No relationships were found for VNFC in AAI");
492         } else {
493             Relationships relationships = relationshipsOp.get();
494             List<AAIResultWrapper> configurationResultWrappers =
495                     this.getResultWrappersFromRelationships(relationships, name);
496             if (configurationResultWrappers.size() > 1) {
497                 throw new VnfcMultipleRelationshipException(vnfc.getVnfcName());
498             }
499             if (!configurationResultWrappers.isEmpty()) {
500                 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
501                 if (configurationOp.isPresent()) {
502                     configuration = configurationOp.get();
503                 }
504             }
505         }
506         return configuration;
507     }
508
509     protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
510             AAIObjectName name) {
511         return relationships.getByType(name);
512     }
513
514     protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
515         for (OrchestrationFlow flow : orchFlows) {
516             if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
517                 return true;
518             }
519         }
520         return false;
521     }
522
523     protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
524             throws AAIEntityNotFoundException, VnfcMultipleRelationshipException {
525
526         List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
527         List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
528                 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
529         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
530         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
531
532         String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
533         String vfModuleCustomizationUUID;
534         org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
535
536         if (aaiVfModule == null) {
537             logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
538                     vfModuleId);
539             throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
540                     + vnfId + " and vfModuleId : " + vfModuleId);
541         } else {
542             vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
543         }
544         String replaceVfModuleCustomizationUUID = "";
545         String replaceVnfModuleCustomizationUUID = "";
546         boolean isReplace = false;
547         if (dataObj.getRequestAction().equalsIgnoreCase("replaceInstance")
548                 || dataObj.getRequestAction().equalsIgnoreCase("replaceInstanceRetainAssignments")) {
549             for (RelatedInstanceList relatedInstList : dataObj.getRequestDetails().getRelatedInstanceList()) {
550                 RelatedInstance relatedInstance = relatedInstList.getRelatedInstance();
551                 if (relatedInstance.getModelInfo().getModelType().equals(ModelType.vnf)) {
552                     replaceVnfModuleCustomizationUUID = relatedInstance.getModelInfo().getModelCustomizationId();
553                 }
554             }
555             replaceVfModuleCustomizationUUID = dataObj.getRequestDetails().getModelInfo().getModelCustomizationId();
556             isReplace = true;
557         }
558
559         List<org.onap.aai.domain.yang.Vnfc> vnfcs =
560                 getRelatedResourcesInVfModule(vnfId, vfModuleId, org.onap.aai.domain.yang.Vnfc.class, Types.VNFC);
561         for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
562             WorkflowResourceIds workflowIdsCopy = SerializationUtils.clone(dataObj.getWorkflowResourceIds());
563             org.onap.aai.domain.yang.Configuration configuration =
564                     getRelatedResourcesInVnfc(vnfc, org.onap.aai.domain.yang.Configuration.class, Types.CONFIGURATION);
565             if (configuration == null) {
566                 logger.warn(String.format("No configuration found for VNFC %s in AAI", vnfc.getVnfcName()));
567                 continue;
568             }
569             workflowIdsCopy.setConfigurationId(configuration.getConfigurationId());
570             for (OrchestrationFlow orchFlow : result) {
571                 if (!isReplace || (isReplace && (orchFlow.getFlowName().contains("Delete")))) {
572                     if (!isReplace) {
573                         dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
574                         dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
575                     } else {
576                         if (orchFlow.getFlowName().contains("Delete")) {
577                             dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
578                             dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
579                         } else {
580                             dataObj.getResourceKey().setVfModuleCustomizationId(replaceVfModuleCustomizationUUID);
581                             dataObj.getResourceKey().setVnfCustomizationId(replaceVnfModuleCustomizationUUID);
582                         }
583                     }
584                     dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
585                     String vnfcName = vnfc.getVnfcName();
586                     if (vnfcName == null || vnfcName.isEmpty()) {
587                         buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
588                                 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
589                                 new Exception("Vnfc and Configuration do not match"));
590                     }
591                     ExecuteBuildingBlock ebb =
592                             executeBuildingBlockBuilder.buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
593                                     dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
594                                     dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
595                                     workflowIdsCopy, dataObj.getRequestDetails(), false, null, vnfcName, true, null);
596                     flowsToExecuteConfigs.add(ebb);
597                 }
598             }
599         }
600         return flowsToExecuteConfigs;
601     }
602
603     protected void buildAndThrowException(DelegateExecution execution, String msg) {
604         logger.error(msg);
605         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
606         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
607     }
608
609     protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
610         logger.error(msg, ex);
611         execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
612         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
613     }
614
615     protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
616             throws Exception {
617
618         String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
619         String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
620
621         logger.debug("BUILDING REPLACE LIST");
622
623         boolean volumeGroupExisted = false;
624         boolean volumeGroupWillExist = false;
625         boolean keepVolumeGroup = false;
626
627         boolean rebuildVolumeGroups = false;
628         if (dataObj.getRequestDetails().getRequestParameters() != null
629                 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
630             rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
631         }
632         String volumeGroupName = "";
633         Optional<VolumeGroup> volumeGroupFromVfModule =
634                 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
635         if (volumeGroupFromVfModule.isPresent()) {
636             String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
637             volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
638             logger.debug("Volume group id of the existing volume group is: {}", volumeGroupId);
639             volumeGroupExisted = true;
640             dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
641             dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
642         }
643
644         List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
645         VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
646                 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
647         if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
648                 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
649                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
650             volumeGroupWillExist = true;
651             if (!volumeGroupExisted) {
652                 String newVolumeGroupId = UUID.randomUUID().toString();
653                 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
654                 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
655                 logger.debug("newVolumeGroupId: {}", newVolumeGroupId);
656             }
657         }
658
659         if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
660             keepVolumeGroup = true;
661         }
662
663         if (!volumeGroupExisted || keepVolumeGroup) {
664             logger.debug("Filtering out deletion of volume groups");
665             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
666                     .collect(Collectors.toList());
667         }
668         if (!volumeGroupWillExist || keepVolumeGroup) {
669             logger.debug("Filtering out creation of volume groups");
670             orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
671                     .collect(Collectors.toList());
672         }
673
674         return orchFlows;
675     }
676
677     private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
678             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
679         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
680             logger.debug("{}, {}", pair.getValue0(), pair.getValue1());
681         }
682         Map<Resource, String> resourceInstanceIds = new HashMap<>();
683         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
684                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
685                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource,
686                                 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId,
687                                 resourceInstanceIds)));
688     }
689
690     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
691         String id = null;
692         for (int i = 0; i < aaiResourceIds.size(); i++) {
693             if (aaiResourceIds.get(i).getValue0() == resource) {
694                 id = aaiResourceIds.get(i).getValue1();
695                 aaiResourceIds.remove(i);
696                 break;
697             }
698         }
699         return id;
700     }
701
702     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
703             String serviceInstanceId) {
704         Map<Resource, String> resourceInstanceIds = new HashMap<>();
705         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
706                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
707                         .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource, null,
708                                 resource.getVirtualLinkKey(), serviceInstanceId, resourceInstanceIds)));
709     }
710
711     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
712             Resource resource, String id, String virtualLinkKey, String serviceInstanceId,
713             Map<Resource, String> resourceInstanceIds) {
714         String key = resource.getResourceId();
715         String resourceId = id;
716         if (resourceId == null) {
717             resourceId = UUID.randomUUID().toString();
718         }
719         resourceInstanceIds.put(resource, resourceId);
720         Set<String> assignedFlows = new LinkedHashSet<>();
721         for (ExecuteBuildingBlock ebb : flowsToExecute) {
722             String resourceTypeStr = resourceType.toString();
723             String flowName = ebb.getBuildingBlock().getBpmnFlowName();
724             String scope = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnScope());
725             String action = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnAction());
726
727             if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey())
728                     && isFlowAssignable(assignedFlows, ebb, resourceType, flowName + action)
729                     && (flowName.contains(resourceTypeStr)
730                             || (flowName.contains(CONTROLLER) && resourceTypeStr.equalsIgnoreCase(scope)))) {
731                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
732                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
733                 Resource parent = resource.getParent();
734                 if (parent != null && resourceInstanceIds.containsKey(parent)) {
735                     WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, parent.getResourceType(),
736                             resourceInstanceIds.get(parent));
737                 }
738                 WorkflowResourceIdsUtils.setInstanceNameByWorkflowType(workflowResourceIds, resourceType,
739                         resource.getInstanceName());
740                 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
741                 ebb.setWorkflowResourceIds(workflowResourceIds);
742                 assignedFlows.add(flowName + action);
743             }
744             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
745                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
746                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
747                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
748                 workflowResourceIds.setNetworkId(resourceId);
749                 ebb.setWorkflowResourceIds(workflowResourceIds);
750             }
751         }
752     }
753
754     private boolean isFlowAssignable(Set<String> assignedFlows, ExecuteBuildingBlock ebb, WorkflowType resourceType,
755             String assignedFlowName) {
756         String id = WorkflowResourceIdsUtils.getResourceIdByWorkflowType(ebb.getWorkflowResourceIds(), resourceType);
757         return !assignedFlows.contains(assignedFlowName) && id.isEmpty();
758     }
759
760     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
761         return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
762     }
763
764     protected Resource extractResourceIdAndTypeFromUri(String uri) {
765         Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
766                 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
767         Matcher m = patt.matcher(uri);
768         boolean generated = false;
769
770         if (m.find()) {
771             logger.debug("found match on {} : {} ", uri, m);
772             String type = m.group("type");
773             String id = m.group("id");
774             String action = m.group("action");
775             if (type == null) {
776                 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
777             }
778             if (action == null) {
779                 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
780                     id = UUID.randomUUID().toString();
781                     generated = true;
782                 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
783                     id = UUID.randomUUID().toString();
784                     generated = true;
785                 }
786             } else {
787                 if (action.matches(SUPPORTEDTYPES)) {
788                     id = UUID.randomUUID().toString();
789                     generated = true;
790                     type = action;
791                 }
792             }
793             return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated, null);
794         } else {
795             throw new IllegalArgumentException("Uri could not be parsed: " + uri);
796         }
797     }
798
799     protected String convertTypeFromPlural(String type) {
800         if (!type.matches(SUPPORTEDTYPES)) {
801             return type;
802         } else {
803             if (type.equals(SERVICE_INSTANCES)) {
804                 return SERVICE;
805             } else {
806                 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
807             }
808         }
809     }
810
811     protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
812             String requestAction) {
813         List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
814         if (requestAction.equals(CREATE_INSTANCE)) {
815             for (ExecuteBuildingBlock ebb : orchFlows) {
816                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
817                     String key = ebb.getBuildingBlock().getKey();
818                     boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
819                     String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
820                     sortedOrchFlows.add(ebb);
821                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
822                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
823                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
824                             sortedOrchFlows.add(ebb2);
825                             break;
826                         }
827                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
828                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
829                             sortedOrchFlows.add(ebb2);
830                             break;
831                         }
832                     }
833                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
834                         if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
835                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
836                             sortedOrchFlows.add(ebb2);
837                             break;
838                         }
839                         if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
840                                 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
841                             sortedOrchFlows.add(ebb2);
842                             break;
843                         }
844                     }
845                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
846                         || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
847                     continue;
848                 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
849                     sortedOrchFlows.add(ebb);
850                 }
851             }
852         } else if (requestAction.equals("deleteInstance")) {
853             for (ExecuteBuildingBlock ebb : orchFlows) {
854                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
855                     sortedOrchFlows.add(ebb);
856                     String key = ebb.getBuildingBlock().getKey();
857                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
858                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
859                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
860                             sortedOrchFlows.add(ebb2);
861                             break;
862                         }
863                     }
864                     for (ExecuteBuildingBlock ebb2 : orchFlows) {
865                         if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
866                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
867                             sortedOrchFlows.add(ebb2);
868                             break;
869                         }
870                     }
871                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
872                         || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
873                     continue;
874                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
875                     sortedOrchFlows.add(ebb);
876                 }
877             }
878         }
879         return sortedOrchFlows;
880     }
881
882     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
883             WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
884         return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
885     }
886
887     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
888             WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
889         List<OrchestrationFlow> listToExecute = new ArrayList<>();
890         NorthBoundRequest northBoundRequest;
891         if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
892                 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
893             northBoundRequest =
894                     catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
895                             requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
896         } else {
897             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
898                     requestAction, resourceName.toString(), aLaCarte, cloudOwner);
899         }
900         if (northBoundRequest == null) {
901             northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
902                     requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
903         }
904         if (northBoundRequest == null) {
905             buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
906                     (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
907         } else {
908             if (northBoundRequest.getIsToplevelflow() != null) {
909                 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
910             }
911             List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
912             if (flows == null) {
913                 flows = new ArrayList<>();
914             } else {
915                 flows.sort(Comparator.comparingInt(OrchestrationFlow::getSequenceNumber));
916             }
917             for (OrchestrationFlow flow : flows) {
918                 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
919                     List<OrchestrationFlow> macroQueryFlows =
920                             catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
921                     listToExecute.addAll(macroQueryFlows);
922                 } else {
923                     listToExecute.add(flow);
924                 }
925             }
926         }
927         return listToExecute;
928     }
929
930     public void handleRuntimeException(DelegateExecution execution) {
931         StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
932         String runtimeErrorMessage;
933         try {
934             String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
935             if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
936                 wfeExpMsg.append(": ").append(javaExpMsg);
937             }
938             runtimeErrorMessage = wfeExpMsg.toString();
939             logger.error(runtimeErrorMessage);
940             execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
941         } catch (Exception e) {
942             logger.error("Runtime error", e);
943             // if runtime message was mulformed
944             runtimeErrorMessage = "Runtime error";
945         }
946         exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
947     }
948
949     protected boolean isUriResume(String uri) {
950         return uri.endsWith("/resume");
951     }
952
953     protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
954             String serviceInstanceId) {
955         return (!aLaCarte && resourceType == WorkflowType.SERVICE
956                 && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
957                 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
958                 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
959     }
960
961     private void fillExecutionDefault(DelegateExecution execution) {
962         execution.setVariable("sentSyncResponse", false);
963         execution.setVariable(HOMING, false);
964         execution.setVariable("calledHoming", false);
965         execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
966     }
967
968     private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
969             WorkflowType resourceType) {
970         execution.setVariable("suppressRollback", suppressRollback);
971         execution.setVariable("resourceId", resourceId);
972         execution.setVariable("resourceType", resourceType);
973         execution.setVariable("resourceName", resourceType.toString());
974     }
975
976     private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
977             String requestId) {
978         if (!alaCarte && isResume) {
979             logger.debug("replacing URI {}", uri);
980             uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
981             logger.debug("for RESUME with original value {}", uri);
982         }
983         return extractResourceIdAndTypeFromUri(uri);
984     }
985
986     private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
987             WorkflowResourceIds workflowResourceIds) throws Exception {
988         if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
989                 && requestDetails.getRequestInfo().getInstanceName() != null) {
990             return aaiResourceIdValidator.validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
991                     requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
992         } else {
993             return resource.getResourceId();
994         }
995     }
996
997     private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
998         String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
999         if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1000             serviceInstanceId = resourceId;
1001         }
1002         return serviceInstanceId;
1003     }
1004
1005 }