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