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