Merge branch 'recursive-orch'
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / WorkflowAction.java
old mode 100644 (file)
new mode 100755 (executable)
index 4be497c..35e1196
@@ -10,6 +10,8 @@
  * ================================================================================
  * Modifications Copyright (c) 2020 Tech Mahindra
  * ================================================================================
+ * Modifications Copyright (c) 2021 Orange
+ * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
 
 package org.onap.so.bpmn.infrastructure.workflow.tasks;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.IS_CHILD_PROCESS;
+import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.PARENT_CORRELATION_ID;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CONTROLLER;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.RECREATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCERETAINASSIGNMENTS;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.SERVICE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPDATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.HEALTH_CHECK;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPGRADE_CNF;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.javatuples.Pair;
-import org.onap.aai.domain.yang.Relationship;
-import org.onap.aai.domain.yang.ServiceInstance;
 import org.onap.aai.domain.yang.Vnfc;
 import org.onap.aai.domain.yang.VolumeGroup;
-import org.onap.aai.domain.yang.VpnBinding;
-import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
 import org.onap.aaiclient.client.aai.AAIObjectName;
 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
 import org.onap.aaiclient.client.aai.entities.Relationships;
@@ -46,21 +71,16 @@ import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
 import org.onap.so.bpmn.common.BBConstants;
+import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.ServiceEBBLoader;
+import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.VnfEBBLoader;
+import org.onap.so.bpmn.infrastructure.workflow.tasks.excpetion.VnfcMultipleRelationshipException;
 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
-import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
-import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
-import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
 import org.onap.so.client.exception.ExceptionBuilder;
-import org.onap.so.client.orchestration.AAIConfigurationResources;
 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
-import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
-import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
-import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
-import org.onap.so.db.catalog.beans.InstanceGroup;
 import org.onap.so.db.catalog.beans.VfModuleCustomization;
 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
@@ -78,26 +98,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGNINSTANCE;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CONTROLLER;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.NETWORKCOLLECTION;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCE;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCERETAINASSIGNMENTS;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.SERVICE;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.so.serviceinstancebeans.InstanceDirection;
 
 @Component
 public class WorkflowAction {
@@ -130,19 +132,15 @@ public class WorkflowAction {
     @Autowired
     private CatalogDbClient catalogDbClient;
     @Autowired
-    private AAIConfigurationResources aaiConfigurationResources;
-    @Autowired
-    private WorkflowActionExtractResourcesAAI workflowActionUtils;
-    @Autowired
-    private VrfValidation vrfValidation;
-    @Autowired
     private Environment environment;
     @Autowired
-    private UserParamsServiceTraversal userParamsServiceTraversal;
-    @Autowired
     private AaiResourceIdValidator aaiResourceIdValidator;
     @Autowired
     private ExecuteBuildingBlockBuilder executeBuildingBlockBuilder;
+    @Autowired
+    private VnfEBBLoader vnfEBBLoader;
+    @Autowired
+    private ServiceEBBLoader serviceEBBLoader;
 
     public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
         this.bbInputSetupUtils = bbInputSetupUtils;
@@ -204,8 +202,10 @@ public class WorkflowAction {
             }
             // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
             // enable it.
-            List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
-            if (sIRequest.getRequestDetails().getRequestParameters() != null && userParams != null) {
+            if (sIRequest.getRequestDetails().getRequestParameters() != null
+                    && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
+                List<Map<String, Object>> userParams =
+                        sIRequest.getRequestDetails().getRequestParameters().getUserParams();
                 for (Map<String, Object> params : userParams) {
                     if (params.containsKey(HOMINGSOLUTION)) {
                         execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
@@ -290,58 +290,25 @@ public class WorkflowAction {
             String cloudOwner, String serviceType, String requestId, String apiVersion, String vnfType,
             RequestDetails requestDetails) throws IOException, VrfBondingServiceException {
         List<ExecuteBuildingBlock> flowsToExecute;
-        boolean containsService = false;
         List<Resource> resourceList = new ArrayList<>();
         List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
-        List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
-        if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
-            // SERVICE-MACRO-ASSIGN will always get user params with a
-            // service.
-
-            if (userParams != null) {
-                containsService = isContainsService(sIRequest);
-                if (containsService) {
-                    resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
-                            serviceInstanceId, requestAction);
-                }
-            } else {
-                buildAndThrowException(execution,
-                        "Service-Macro-Assign request details must contain user params with a service");
-            }
-        } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATE_INSTANCE)) {
-            // SERVICE-MACRO-CREATE will get user params with a service,
-            // a service with a network, a service with a
-            // network collection, OR an empty service.
-            // If user params is just a service or null and macro
-            // queries the SI and finds a VNF, macro fails.
-
-            if (userParams != null) {
-                containsService = isContainsService(sIRequest);
-            }
-            if (containsService) {
-                resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
-                        serviceInstanceId, requestAction);
-            }
-            if (!foundRelated(resourceList)) {
-                traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
-            }
-        } else if (resourceType == WorkflowType.SERVICE && ("activateInstance".equalsIgnoreCase(requestAction)
-                || "unassignInstance".equalsIgnoreCase(requestAction)
-                || "deleteInstance".equalsIgnoreCase(requestAction)
-                || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
-            // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
-            // SERVICE-MACRO-DELETE
-            // Will never get user params with service, macro will have
-            // to query the SI in AAI to find related instances.
-            traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
-        } else if (resourceType == WorkflowType.SERVICE && "deactivateInstance".equalsIgnoreCase(requestAction)) {
-            resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
-        } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
-                || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
-            traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
+
+        if (resourceType == WorkflowType.SERVICE || isVNFCreate(resourceType, requestAction)) {
+            resourceList = serviceEBBLoader.getResourceListForService(sIRequest, requestAction, execution,
+                    serviceInstanceId, resourceId, aaiResourceIds);
+        } else if (resourceType == WorkflowType.VNF
+                && (DELETE_INSTANCE.equalsIgnoreCase(requestAction) || REPLACEINSTANCE.equalsIgnoreCase(requestAction)
+                        || (RECREATE_INSTANCE.equalsIgnoreCase(requestAction)))) {
+            vnfEBBLoader.traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
                     workflowResourceIds.getVnfId(), aaiResourceIds);
-        } else if (resourceType == WorkflowType.VNF && "updateInstance".equalsIgnoreCase(requestAction)) {
-            customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
+        } else if (resourceType == WorkflowType.VNF && UPDATE_INSTANCE.equalsIgnoreCase(requestAction)) {
+            vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
+                    workflowResourceIds.getVnfId(), aaiResourceIds);
+        } else if (resourceType == WorkflowType.VNF && HEALTH_CHECK.equalsIgnoreCase(requestAction)) {
+            vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
+                    workflowResourceIds.getVnfId(), aaiResourceIds);
+        } else if (resourceType == WorkflowType.VNF && UPGRADE_CNF.equalsIgnoreCase(requestAction)) {
+            vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
                     workflowResourceIds.getVnfId(), aaiResourceIds);
         } else {
             buildAndThrowException(execution, "Current Macro Request is not supported");
@@ -365,26 +332,62 @@ public class WorkflowAction {
         }
         flowsToExecute = executeBuildingBlockBuilder.buildExecuteBuildingBlockList(orchFlows, resourceList, requestId,
                 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
-        if (isNetworkCollectionInTheResourceList(resourceList)) {
+        if (serviceEBBLoader.isNetworkCollectionInTheResourceList(resourceList)) {
             logger.info("Sorting for Vlan Tagging");
             flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
         }
+        logger.info("Building Block Execution Order");
+        for (ExecuteBuildingBlock block : flowsToExecute) {
+            Resource res = resourceList.stream()
+                    .filter(resource -> resource.getResourceId() == block.getBuildingBlock().getKey()).findAny()
+                    .orElse(null);
+            String log = "Block: " + block.getBuildingBlock().getBpmnFlowName();
+            if (res != null) {
+                log += ", Resource: " + res.getResourceType() + "[" + res.getResourceId() + "]";
+                log += ", Priority: " + res.getProcessingPriority();
+                if (res.getResourceType() == WorkflowType.VFMODULE)
+                    log += ", Base: " + res.isBaseVfModule();
+            }
+            if (block.getBuildingBlock().getBpmnScope() != null)
+                log += ", Scope: " + block.getBuildingBlock().getBpmnScope();
+            if (block.getBuildingBlock().getBpmnAction() != null)
+                log += ", Action: " + block.getBuildingBlock().getBpmnAction();
+            logger.info(log);
+        }
+
+        RelatedInstanceList[] instanceList = sIRequest.getRequestDetails().getRelatedInstanceList();
+        execution.setVariable(IS_CHILD_PROCESS, Boolean.FALSE);
+        if (instanceList != null) {
+            for (RelatedInstanceList relatedInstanceList : instanceList) {
+                RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance();
+                if (InstanceDirection.source.equals(relatedInstance.getInstanceDirection())) {
+                    execution.setVariable(IS_CHILD_PROCESS, Boolean.TRUE);
+                    execution.setVariable(PARENT_CORRELATION_ID, requestDetails.getRequestInfo().getCorrelator());
+                }
+            }
+        }
+
         // By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
         if (resourceType == WorkflowType.SERVICE
-                && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE))
+                && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE))
                 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
             execution.setVariable(HOMING, true);
             execution.setVariable("calledHoming", false);
         }
-        if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
+        if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)
                 || requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
             generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
         } else {
             updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds, serviceInstanceId);
         }
+        execution.setVariable("resources", resourceList);
         return flowsToExecute;
     }
 
+    private boolean isVNFCreate(WorkflowType resourceType, String requestAction) {
+        return resourceType == WorkflowType.VNF && CREATE_INSTANCE.equalsIgnoreCase(requestAction);
+    }
+
     private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
             List<String> flowNames) {
         execution.setVariable("flowNames", flowNames);
@@ -395,15 +398,6 @@ public class WorkflowAction {
         execution.setVariable("isRollbackComplete", false);
     }
 
-    private boolean isContainsService(ServiceInstancesRequest sIRequest) {
-        boolean containsService;
-        List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
-        containsService = userParams.stream().anyMatch(param -> param.containsKey(USER_PARAM_SERVICE));
-        return containsService;
-    }
-
-
-
     private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
             String errorMessage) {
         List<ExecuteBuildingBlock> flowsToExecute;
@@ -472,7 +466,7 @@ public class WorkflowAction {
                 resourceId = modelInfo.getModelCustomizationId();
             }
         }
-        return new Resource(resourceType, resourceId, true);
+        return new Resource(resourceType, resourceId, true, null);
     }
 
     private String getCloudOwner(CloudConfiguration cloudConfiguration) {
@@ -490,7 +484,7 @@ public class WorkflowAction {
                 AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId).vfModule(vfModuleId));
         AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
         Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
-        if (!relationshipsOp.isPresent()) {
+        if (relationshipsOp.isEmpty()) {
             logger.debug("No relationships were found for vfModule in AAI");
         } else {
             Relationships relationships = relationshipsOp.get();
@@ -503,21 +497,20 @@ public class WorkflowAction {
         return vnfcs;
     }
 
-    protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name) throws Exception {
+    protected <T> T getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectName name)
+            throws VnfcMultipleRelationshipException {
         T configuration = null;
         AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().vnfc(vnfc.getVnfcName()));
         AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
         Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
-        if (!relationshipsOp.isPresent()) {
+        if (relationshipsOp.isEmpty()) {
             logger.debug("No relationships were found for VNFC in AAI");
         } else {
             Relationships relationships = relationshipsOp.get();
             List<AAIResultWrapper> configurationResultWrappers =
                     this.getResultWrappersFromRelationships(relationships, name);
             if (configurationResultWrappers.size() > 1) {
-                String multipleRelationshipsError =
-                        "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
-                throw new Exception(multipleRelationshipsError);
+                throw new VnfcMultipleRelationshipException(vnfc.getVnfcName());
             }
             if (!configurationResultWrappers.isEmpty()) {
                 Optional<T> configurationOp = configurationResultWrappers.get(0).asBean(resultClass);
@@ -544,7 +537,7 @@ public class WorkflowAction {
     }
 
     protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
-            throws Exception {
+            throws AAIEntityNotFoundException, VnfcMultipleRelationshipException {
 
         List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
         List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
@@ -658,7 +651,7 @@ public class WorkflowAction {
         if (volumeGroupFromVfModule.isPresent()) {
             String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
             volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
-            logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
+            logger.debug("Volume group id of the existing volume group is: {}", volumeGroupId);
             volumeGroupExisted = true;
             dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
             dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
@@ -675,7 +668,7 @@ public class WorkflowAction {
                 String newVolumeGroupId = UUID.randomUUID().toString();
                 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
                 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
-                logger.debug("newVolumeGroupId: " + newVolumeGroupId);
+                logger.debug("newVolumeGroupId: {}", newVolumeGroupId);
             }
         }
 
@@ -697,18 +690,17 @@ public class WorkflowAction {
         return orchFlows;
     }
 
-
-
     private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
             List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
-            logger.debug(pair.getValue0() + ", " + pair.getValue1());
+            logger.debug("{}, {}", pair.getValue0(), pair.getValue1());
         }
-
-        Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
-                .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
-                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
-                                retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
+        Map<Resource, String> resourceInstanceIds = new HashMap<>();
+        Arrays.stream(WorkflowType.values()).forEach(type -> resourceList.stream()
+                .filter(resource -> type.equals(resource.getResourceType())
+                        && !(WorkflowType.SERVICE.equals(type) && !resource.hasParent()))
+                .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource,
+                        retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId, resourceInstanceIds)));
     }
 
     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
@@ -725,27 +717,53 @@ public class WorkflowAction {
 
     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
             String serviceInstanceId) {
-        Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
-                .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
-                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
-                                null, resource.getVirtualLinkKey(), serviceInstanceId)));
+        Map<Resource, String> resourceInstanceIds = new HashMap<>();
+        Arrays.stream(WorkflowType.values())
+                .forEach(type -> resourceList.stream()
+                        .filter(resource -> resource.hasParent() && type.equals(resource.getResourceType()))
+                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource, null,
+                                resource.getVirtualLinkKey(), serviceInstanceId, resourceInstanceIds)));
     }
 
     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
-            String key, String id, String virtualLinkKey, String serviceInstanceId) {
+            Resource resource, String id, String virtualLinkKey, String serviceInstanceId,
+            Map<Resource, String> resourceInstanceIds) {
+        String key = resource.getResourceId();
         String resourceId = id;
         if (resourceId == null) {
             resourceId = UUID.randomUUID().toString();
         }
+        resourceInstanceIds.put(resource, resourceId);
+        Set<String> assignedFlows = new LinkedHashSet<>();
         for (ExecuteBuildingBlock ebb : flowsToExecute) {
-            if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
-                    .getBpmnFlowName().contains(resourceType.toString())
-                    || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
-                            && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
+            String resourceTypeStr = resourceType.toString();
+            String flowName = ebb.getBuildingBlock().getBpmnFlowName();
+            String scope = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnScope());
+            String action = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnAction());
+
+            if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey())
+                    && isFlowAssignable(assignedFlows, ebb, resourceType, flowName + action)
+                    && (flowName.contains(resourceTypeStr)
+                            || (flowName.contains(CONTROLLER) && resourceTypeStr.equalsIgnoreCase(scope)))) {
                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
-                WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
+                Resource parent = resource.getParent();
+                if (resource.hasParent() && resourceInstanceIds.containsKey(parent)) {
+                    WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, parent.getResourceType(),
+                            resourceInstanceIds.get(parent));
+                }
+                if (resource.hasParent() && WorkflowType.SERVICE.equals(resourceType)
+                        && WorkflowType.SERVICE.equals(parent.getResourceType())) {
+                    String childServiceInstanceId = resource.isGenerated() ? resourceId : resource.getResourceId();
+                    workflowResourceIds.setChildServiceInstanceId(childServiceInstanceId);
+                    workflowResourceIds.setChildServiceInstanceName(resource.getInstanceName());
+                } else {
+                    WorkflowResourceIdsUtils.setInstanceNameByWorkflowType(workflowResourceIds, resourceType,
+                            resource.getInstanceName());
+                    WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
+                }
                 ebb.setWorkflowResourceIds(workflowResourceIds);
+                assignedFlows.add(flowName + action);
             }
             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
@@ -757,449 +775,12 @@ public class WorkflowAction {
         }
     }
 
-    protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
-            org.onap.so.db.catalog.beans.Service service) {
-        CollectionResourceCustomization networkCollection = null;
-        int count = 0;
-        for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
-            if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
-                    collectionCust.getModelCustomizationUUID()) != null) {
-                networkCollection = collectionCust;
-                count++;
-            }
-        }
-        if (count == 0) {
-            return null;
-        } else if (count > 1) {
-            buildAndThrowException(execution,
-                    "Found multiple Network Collections in the Service model, only one per Service is supported.");
-        }
-        return networkCollection;
-    }
-
-    protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
-            List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
-            throws JsonProcessingException, VrfBondingServiceException {
-        String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
-        org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
-
-        if (service == null) {
-            buildAndThrowException(execution, "Could not find the service model in catalog db.");
-        } else {
-            resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
-            RelatedInstance relatedVpnBinding =
-                    bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
-            RelatedInstance relatedLocalNetwork =
-                    bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
-
-            if (relatedVpnBinding != null && relatedLocalNetwork != null) {
-                traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
-            } else {
-                traverseNetworkCollection(execution, resourceList, service);
-            }
-        }
-    }
-
-    protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
-            List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
-            RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
-            throws VrfBondingServiceException, JsonProcessingException {
-        org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
-                bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
-        vrfValidation.vrfServiceValidation(service);
-        vrfValidation.vrfCatalogDbChecks(service);
-        vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
-                bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
-        vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
-        vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
-        vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
-        vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
-        String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
-        if (existingAAIVrfConfiguration != null) {
-            aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
-        }
-        resourceList.add(new Resource(WorkflowType.CONFIGURATION,
-                service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
-
-    }
-
-    protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
-            org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
-            throws JsonProcessingException, VrfBondingServiceException {
-        Optional<Relationships> relationshipsOp = new AAIResultWrapper(
-                new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
-        if (relationshipsOp.isPresent()) {
-            List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
-                    relationshipsOp.get().getByType(Types.CONFIGURATION);
-            if (configurationsRelatedToLocalNetwork.size() > 1) {
-                throw new VrfBondingServiceException(
-                        "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
-            }
-            if (configurationsRelatedToLocalNetwork.size() == 1) {
-                AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
-                Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
-                if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
-                        relatedConfiguration.get(), configWrapper)) {
-                    return relatedConfiguration.get().getConfigurationId();
-                }
-            }
-        }
-        return null;
-    }
-
-    protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
-            AAIResultWrapper configWrapper) throws VrfBondingServiceException {
-        if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
-            Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
-            if (relationshipsConfigOp.isPresent()) {
-                Optional<VpnBinding> relatedInfraVpnBindingOp =
-                        workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
-                if (relatedInfraVpnBindingOp.isPresent()) {
-                    VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
-                    if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
-                        throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
-                                + " is not connected to the same vpn binding id provided in request: "
-                                + relatedVpnBinding.getInstanceId());
-                    } else {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
-            org.onap.so.db.catalog.beans.Service service) {
-        if (isVnfCustomizationsInTheService(service)) {
-            buildAndThrowException(execution,
-                    "Cannot orchestrate Service-Macro-Create without user params with a vnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
-        }
-        if (isPnfCustomizationsInTheService(service)) {
-            buildAndThrowException(execution,
-                    "Cannot orchestrate Service-Macro-Create without user params with a pnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
-        }
-        List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
-        if (customizations.isEmpty()) {
-            logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
-        } else {
-            CollectionResourceCustomization collectionResourceCustomization =
-                    findCatalogNetworkCollection(execution, service);
-            traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
-        }
-        traverseNetworkCollectionCustomization(resourceList, service);
-    }
-
-    private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
-            CollectionResourceCustomization collectionResourceCustomization) {
-        if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
-            return;
-        int minNetworks = 0;
-        org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
-                collectionResourceCustomization.getCollectionResource().getInstanceGroup();
-        CollectionResourceInstanceGroupCustomization collectionInstCust = null;
-        if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
-            for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
-                    .getCollectionInstanceGroupCustomizations()) {
-                if (collectionInstanceGroupTemp.getModelCustomizationUUID()
-                        .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
-                    collectionInstCust = collectionInstanceGroupTemp;
-                    break;
-                }
-            }
-            if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
-                minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
-            }
-        }
-        logger.debug("minNetworks: {}", minNetworks);
-        CollectionNetworkResourceCustomization collectionNetworkResourceCust =
-                getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
-        for (int i = 0; i < minNetworks; i++) {
-            if (collectionNetworkResourceCust != null) {
-                Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
-                        collectionNetworkResourceCust.getModelCustomizationUUID(), false);
-                resource.setVirtualLinkKey(Integer.toString(i));
-                resourceList.add(resource);
-            }
-        }
-    }
-
-    private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
-            CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
-        CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
-        for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
-                .getCollectionNetworkResourceCustomizations()) {
-            if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
-                    .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
-                collectionNetworkResourceCust = collectionNetworkTemp;
-                break;
-            }
-        }
-        return collectionNetworkResourceCust;
-    }
-
-    private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
-            CollectionResourceCustomization collectionResourceCustomization) {
-        if (collectionResourceCustomization == null) {
-            logger.debug("No Network Collection Customization found");
-            return true;
-        }
-        resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
-                collectionResourceCustomization.getModelCustomizationUUID(), false));
-        logger.debug("Found a network collection");
-        if (collectionResourceCustomization.getCollectionResource() == null) {
-            logger.debug("No Network Collection found. collectionResource is null");
-            return true;
-        }
-        if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
-            logger.debug("No Instance Group found for network collection.");
-            return true;
-        }
-        String toscaNodeType =
-                collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
-        if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
-            logger.debug("Instance Group tosca node type does not contain NetworkCollection:  {}", toscaNodeType);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean interfaceNetworkQuantityIsAvailableInCollection(
-            CollectionResourceInstanceGroupCustomization collectionInstCust) {
-        return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
-    }
-
-    private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
-        return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
-    }
-
-    private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
-            org.onap.so.db.catalog.beans.Service service) {
-        if (isNetworkCollectionInTheResourceList(resourceList)) {
-            return;
-        }
-        if (service.getNetworkCustomizations() == null) {
-            logger.debug("No networks were found on this service model");
-            return;
-        }
-        for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
-            resourceList.add(new Resource(WorkflowType.NETWORK,
-                    service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
-        }
-    }
-
-    private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
-        return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
-    }
-
-    private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
-        return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
-    }
-
-    private boolean isPnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
-        return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
-    }
-
-    protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
-            List<Pair<WorkflowType, String>> aaiResourceIds) {
-        try {
-            ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
-            org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
-                    bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
-            resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
-            traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
-            traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
-            if (serviceInstanceMSO.getNetworks() != null) {
-                for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
-                        .getNetworks()) {
-                    aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
-                    resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
-                }
-            }
-            if (serviceInstanceMSO.getCollection() != null) {
-                logger.debug("found networkcollection");
-                aaiResourceIds
-                        .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
-                resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
-                        serviceInstanceMSO.getCollection().getId(), false));
-            }
-            if (serviceInstanceMSO.getConfigurations() != null) {
-                for (Configuration config : serviceInstanceMSO.getConfigurations()) {
-                    Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
-                            aaiConfigurationResources.getConfiguration(config.getConfigurationId());
-                    if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
-                        for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
-                            if (relationship.getRelatedTo().contains("vnfc")
-                                    || relationship.getRelatedTo().contains("vpn-binding")) {
-                                aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
-                                resourceList.add(
-                                        new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            logger.error("Exception in traverseAAIService", ex);
-            buildAndThrowException(execution,
-                    "Could not find existing Service Instance or related Instances to execute the request on.");
-        }
-    }
-
-    private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
-            List<Pair<WorkflowType, String>> aaiResourceIds,
-            org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
-        if (serviceInstanceMSO.getVnfs() == null) {
-            return;
-        }
-        for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
-            aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
-            resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
-            traverseVnfModules(resourceList, aaiResourceIds, vnf);
-            if (vnf.getVolumeGroups() != null) {
-                for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
-                    aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
-                    resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
-                }
-            }
-        }
-    }
-
-    private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
-            List<Pair<WorkflowType, String>> aaiResourceIds,
-            org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
-        if (serviceInstanceMSO.getPnfs() == null) {
-            return;
-        }
-        for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
-            aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
-            resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
-        }
-    }
-
-    private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
-            org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
-        if (vnf.getVfModules() == null) {
-            return;
-        }
-        for (VfModule vfModule : vnf.getVfModules()) {
-            aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
-            Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
-            resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
-            resourceList.add(resource);
-        }
-    }
-
-    private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
-            String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
-        try {
-            ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
-            org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
-                    bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
-            resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
-            if (serviceInstanceMSO.getVnfs() != null) {
-                for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
-                    if (vnf.getVnfId().equals(vnfId)) {
-                        aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
-                        resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
-                        if (vnf.getVfModules() != null) {
-                            for (VfModule vfModule : vnf.getVfModules()) {
-                                aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
-                                resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
-                                findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
-                                        resourceList, aaiResourceIds);
-                            }
-                        }
-                        if (vnf.getVolumeGroups() != null) {
-                            for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
-                                    .getVolumeGroups()) {
-                                aaiResourceIds
-                                        .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
-                                resourceList.add(
-                                        new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
-                            }
-                        }
-                        break;
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            logger.error("Exception in traverseAAIVnf", ex);
-            buildAndThrowException(execution,
-                    "Could not find existing Vnf or related Instances to execute the request on.");
-        }
-    }
-
-    private void customTraverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
-            String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
-        try {
-            ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
-            org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
-                    bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
-            resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
-            if (serviceInstanceMSO.getVnfs() != null) {
-                for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
-                    if (vnf.getVnfId().equals(vnfId)) {
-                        aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
-
-                        String vnfCustomizationUUID =
-                                bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
-                        resourceList.add(new Resource(WorkflowType.VNF, vnfCustomizationUUID, false));
-
-                        if (vnf.getVfModules() != null) {
-                            for (VfModule vfModule : vnf.getVfModules()) {
-                                aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
-                                resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
-                                findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
-                                        resourceList, aaiResourceIds);
-                            }
-                        }
-                        if (vnf.getVolumeGroups() != null) {
-                            for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
-                                    .getVolumeGroups()) {
-                                aaiResourceIds
-                                        .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
-                                resourceList.add(
-                                        new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
-                            }
-                        }
-                        break;
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            logger.error("Exception in customTraverseAAIVnf", ex);
-            buildAndThrowException(execution,
-                    "Could not find existing Vnf or related Instances to execute the request on.");
-        }
-
-    }
-
-    private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
-            List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
-        try {
-            org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
-            AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
-                    new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
-            Optional<Relationships> relationshipsOp;
-            relationshipsOp = vfModuleWrapper.getRelationships();
-            if (relationshipsOp.isPresent()) {
-                relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
-                if (relationshipsOp.isPresent()) {
-                    Optional<Configuration> config =
-                            workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
-                    if (config.isPresent()) {
-                        aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
-                        resourceList.add(
-                                new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            logger.error("Exception in findConfigurationsInsideVfModule", ex);
-            buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
-        }
+    private boolean isFlowAssignable(Set<String> assignedFlows, ExecuteBuildingBlock ebb, WorkflowType resourceType,
+            String assignedFlowName) {
+        String id = WorkflowType.SERVICE.equals(resourceType)
+                ? StringUtils.defaultString(ebb.getWorkflowResourceIds().getChildServiceInstanceId())
+                : WorkflowResourceIdsUtils.getResourceIdByWorkflowType(ebb.getWorkflowResourceIds(), resourceType);
+        return !assignedFlows.contains(assignedFlowName) && id.isEmpty();
     }
 
     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
@@ -1235,7 +816,7 @@ public class WorkflowAction {
                     type = action;
                 }
             }
-            return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
+            return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated, null);
         } else {
             throw new IllegalArgumentException("Uri could not be parsed: " + uri);
         }
@@ -1324,15 +905,6 @@ public class WorkflowAction {
         return sortedOrchFlows;
     }
 
-    private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
-        ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
-        Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
-        configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
-        configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
-        configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
-        return configurationResourceKeys;
-    }
-
     protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
             WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
         return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
@@ -1407,22 +979,11 @@ public class WorkflowAction {
     protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
             String serviceInstanceId) {
         return (!aLaCarte && resourceType == WorkflowType.SERVICE
-                && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
+                && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
                 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
                 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
     }
 
-    protected boolean foundRelated(List<Resource> resourceList) {
-        return (containsWorkflowType(resourceList, WorkflowType.VNF)
-                || containsWorkflowType(resourceList, WorkflowType.PNF)
-                || containsWorkflowType(resourceList, WorkflowType.NETWORK)
-                || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
-    }
-
-    protected boolean containsWorkflowType(List<Resource> resourceList, WorkflowType workflowType) {
-        return resourceList.stream().anyMatch(resource -> resource.getResourceType().equals(workflowType));
-    }
-
     private void fillExecutionDefault(DelegateExecution execution) {
         execution.setVariable("sentSyncResponse", false);
         execution.setVariable(HOMING, false);