Merge branch 'recursive-orch'
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / ExecuteBuildingBlockBuilder.java
old mode 100644 (file)
new mode 100755 (executable)
index b869983..d7f2b85
@@ -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
@@ -26,6 +28,7 @@
 
 package org.onap.so.bpmn.infrastructure.workflow.tasks;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
@@ -36,20 +39,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.UUID;
 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.CONFIGURATION;
-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.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.VOLUMEGROUP;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.*;
 
 @Component
 public class ExecuteBuildingBlockBuilder {
@@ -60,80 +54,138 @@ public class ExecuteBuildingBlockBuilder {
     private static final String PNF = "Pnf";
     private static final String VFMODULE = "VfModule";
     private static final String NETWORK = "Network";
+    private static final String HEALTH_CHECK = "HealthCheckBB";
+    private static final String UPGRADE_CNF = "UpgradeVfModuleBB";
 
     protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
-            List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
-            String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
-            boolean replaceVnf) {
+            List<Resource> originalResourceList, String requestId, String apiVersion, String resourceId,
+            String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
+            RequestDetails requestDetails, boolean replaceVnf) {
+        List<Resource> resourceList = getOnlyRootResourceList(originalResourceList);
+
         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
+
+        boolean ascendingOrder = requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE)
+                || requestAction.equals(ACTIVATE_INSTANCE);
+
+        ExecutionPlan plan = ExecutionPlan.build(resourceList, ascendingOrder);
+
+        logger.info("Orchestration Flows");
         for (OrchestrationFlow orchFlow : orchFlows) {
-            if (orchFlow.getFlowName().contains(SERVICE)) {
-                if (!replaceVnf) {
-                    workflowResourceIds.setServiceInstanceId(resourceId);
-                }
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
-                        apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
-                        false);
-            } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
-                    && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
-                        apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
-                        false);
-            } else if (orchFlow.getFlowName().contains(PNF) || (orchFlow.getFlowName().contains(CONTROLLER)
-                    && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
+            String flowDetails = new ToStringBuilder(this).append("id", orchFlow.getId())
+                    .append("action", orchFlow.getAction()).append("sequenceNumber", orchFlow.getSequenceNumber())
+                    .append("flowName", orchFlow.getFlowName()).append("flowVersion", orchFlow.getFlowVersion())
+                    .append("bpmnAction", orchFlow.getBpmnAction()).append("bpmnScope", orchFlow.getBpmnScope())
+                    .toString();
+            logger.info("Flow: " + flowDetails);
+            buildExecuteBuildingBlockListPlan(orchFlow, plan, requestId, apiVersion, resourceId, requestAction, vnfType,
+                    workflowResourceIds, requestDetails, replaceVnf);
+        }
+
+        plan.flushBlocksFromCache(flowsToExecute);
+
+        return flowsToExecute;
+    }
+
+    protected void buildExecuteBuildingBlockListPlan(OrchestrationFlow flow, ExecutionPlan plan, String requestId,
+            String apiVersion, String resourceId, String requestAction, String vnfType,
+            WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean replaceVnf) {
+
+        List<ExecuteBuildingBlock> mainFlows = buildExecuteBuildingBlockListRaw(flow, plan.getResource(), requestId,
+                apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, replaceVnf);
+
+        plan.pushBlockToCache(mainFlows);
+
+        for (ExecutionGroup nestedGroup : plan.getNestedExecutions()) {
+            for (ExecutionPlan nestedPlan : nestedGroup.getNestedExecutions()) {
+                buildExecuteBuildingBlockListPlan(flow, nestedPlan, requestId, apiVersion, resourceId, requestAction,
+                        vnfType, workflowResourceIds, requestDetails, replaceVnf);
+            }
+            if (nestedGroup.getCacheSize() > 0)
+                plan.changeCurrentGroup(nestedGroup);
+        }
+    }
+
+    private List<ExecuteBuildingBlock> buildExecuteBuildingBlockListRaw(OrchestrationFlow orchFlow, Resource resource,
+            String requestId, String apiVersion, String resourceId, String requestAction, String vnfType,
+            WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean replaceVnf) {
+        List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
+        if (orchFlow.getFlowName().contains(CHILD_SERVICE)) {
+            if (WorkflowType.SERVICE.equals(resource.getResourceType()) && resource.hasParent()) {
+                addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.SERVICE, orchFlow, requestId,
                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
                         false);
-            } else if (orchFlow.getFlowName().contains(NETWORK)
-                    && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
+            }
+        } else if (orchFlow.getFlowName().contains(SERVICE) || (orchFlow.getFlowName().contains(CONTROLLER)
+                && (SERVICE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
+            if (!replaceVnf) {
+                workflowResourceIds.setServiceInstanceId(resourceId);
+            }
+            if (!resource.hasParent()) {
+                addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.SERVICE, orchFlow, requestId,
                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
                         false);
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
-                        requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
-                        true, false);
-            } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
-                    && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
-                List<Resource> vfModuleResourcesSorted;
-                if (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE)
-                        || requestAction.equals("activateInstance")) {
-                    vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
-                            .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
-                } else {
-                    vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
-                            .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
-                }
-                for (Resource resource : vfModuleResourcesSorted) {
-                    flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
-                            requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
-                            false, null));
-                }
-            } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
-                if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
-                        || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
-                    logger.debug("Replacing workflow resource id by volume group id");
-                    resourceId = workflowResourceIds.getVolumeGroupId();
-                }
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
-                        requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
-                        false, false);
-            } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
-                        requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
-                        false, false);
-            } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
-                addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
-                        requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
-                        false, true);
-            } else {
-                flowsToExecute
-                        .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
-                                false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
             }
+        } else if (orchFlow.getFlowName().contains(VNF)
+                || (orchFlow.getFlowName().contains(CONTROLLER) && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
+                    resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+        } else if ((orchFlow.getFlowName().equalsIgnoreCase(HEALTH_CHECK))
+                && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope())) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
+                    resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+        } else if ((orchFlow.getFlowName().equalsIgnoreCase(UPGRADE_CNF))
+                && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope())) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
+                    resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+        } else if (orchFlow.getFlowName().contains(PNF)
+                || (orchFlow.getFlowName().contains(CONTROLLER) && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.PNF, orchFlow, requestId, apiVersion,
+                    resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+        } else if (orchFlow.getFlowName().contains(NETWORK) && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.NETWORK, orchFlow, requestId,
+                    apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VIRTUAL_LINK, orchFlow, requestId,
+                    apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, true, false);
+        } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
+                && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VFMODULE, orchFlow, requestId,
+                    apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+        } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
+            if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
+                    || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
+                logger.debug("Replacing workflow resource id by volume group id");
+                resourceId = workflowResourceIds.getVolumeGroupId();
+            }
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VOLUMEGROUP, orchFlow, requestId,
+                    apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
+        } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.NETWORKCOLLECTION, orchFlow,
+                    requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
+                    false, false);
+        } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
+            addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.CONFIGURATION, orchFlow, requestId,
+                    apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, true);
+        } else {
+            flowsToExecute
+                    .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
+                            false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
         }
         return flowsToExecute;
     }
 
+    protected List<Resource> getOnlyRootResourceList(List<Resource> resourceList) {
+        return resourceList.stream().filter(x -> countResourceOnTheResourceList(x, resourceList) == 1)
+                .collect(Collectors.toList());
+    }
+
+    protected int countResourceOnTheResourceList(Resource resource, List<Resource> resourceList) {
+        int count = resourceList.stream()
+                .mapToInt(x -> (x.equals(resource) ? 1 : 0) + countResourceOnTheResourceList(resource, x.getChildren()))
+                .reduce(0, Integer::sum);
+        return count;
+    }
+
     protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
             Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
@@ -169,42 +221,19 @@ public class ExecuteBuildingBlockBuilder {
         return executeBuildingBlock;
     }
 
-    protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
-        int count = 0;
-        for (Resource resource : vfModuleResources) {
-            if (resource.isBaseVfModule()) {
-                Collections.swap(vfModuleResources, 0, count);
-                break;
-            }
-            count++;
-        }
-        return vfModuleResources;
-    }
-
-    protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
-        int count = 0;
-        for (Resource resource : vfModuleResources) {
-            if (resource.isBaseVfModule()) {
-                Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
-                break;
-            }
-            count++;
-        }
-        return vfModuleResources;
-    }
-
-    private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
+    private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, Resource resource,
             WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
             String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
             RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
 
-        resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
-                .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
-                        apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
-                        isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration, null)));
+        if (resource == null || !resource.getResourceType().equals(workflowType))
+            return;
+        flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
+                requestAction, false, vnfType, workflowResourceIds, requestDetails, isVirtualLink,
+                resource.getVirtualLinkKey(), null, isConfiguration, null));
     }
 
-    private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
+    protected ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
         ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
         Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
         configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
@@ -212,6 +241,4 @@ public class ExecuteBuildingBlockBuilder {
         configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
         return configurationResourceKeys;
     }
-
-
 }