Search in sources :

Example 1 with SubGraph

use of alien4cloud.paas.wf.util.SubGraph in project alien4cloud by alien4cloud.

the class WorkflowSimplifyService method removeUnnecessarySteps.

private void removeUnnecessarySteps(TopologyContext topologyContext, Workflow workflow, SubGraph subGraph) {
    LastPathGraphConsumer consumer = new LastPathGraphConsumer();
    subGraph.browse(consumer);
    if (consumer.getAllNodes().isEmpty()) {
        // This is really strange as we have a node template without any workflow step
        return;
    }
    Set<String> allStepIds = consumer.getAllNodes().keySet();
    List<WorkflowStep> sortedByWeightsSteps = consumer.getLastPath();
    List<Integer> nonEmptyIndexes = new ArrayList<>();
    LinkedHashSet<Integer> emptyIndexes = new LinkedHashSet<>();
    int lastIndexWithOutgoingLinks = -1;
    int firstIndexWithOutgoingLinks = -1;
    for (int i = 0; i < sortedByWeightsSteps.size(); i++) {
        WorkflowStep step = sortedByWeightsSteps.get(i);
        if (!allStepIds.containsAll(step.getOnSuccess())) {
            lastIndexWithOutgoingLinks = i;
            if (firstIndexWithOutgoingLinks == -1) {
                firstIndexWithOutgoingLinks = i;
            }
        }
        if (!WorkflowGraphUtils.isStepEmpty(step, topologyContext)) {
            nonEmptyIndexes.add(i);
        } else {
            emptyIndexes.add(i);
        }
    }
    Map<Integer, Integer> emptyIndexToFollowingSubstituteMap = new HashMap<>();
    Map<Integer, Integer> emptyIndexToPrecedingSubstituteMap = new HashMap<>();
    for (Integer emptyIndex : emptyIndexes) {
        Optional<Integer> substitutePrecedingIndex = nonEmptyIndexes.stream().filter(nonEmptyIndex -> nonEmptyIndex > emptyIndex).findFirst();
        Optional<Integer> substituteFollowingIndex = nonEmptyIndexes.stream().filter(nonEmptyIndex -> nonEmptyIndex < emptyIndex).reduce((first, second) -> second);
        substitutePrecedingIndex.ifPresent(index -> emptyIndexToPrecedingSubstituteMap.put(emptyIndex, index));
        substituteFollowingIndex.ifPresent(index -> emptyIndexToFollowingSubstituteMap.put(emptyIndex, index));
    }
    for (int index = 0; index < sortedByWeightsSteps.size(); index++) {
        WorkflowStep step = sortedByWeightsSteps.get(index);
        boolean stepIsEmpty = emptyIndexes.contains(index);
        Integer followingSubstitutedIndex = emptyIndexToFollowingSubstituteMap.get(index);
        Integer precedingSubstitutedIndex = emptyIndexToPrecedingSubstituteMap.get(index);
        if (stepIsEmpty) {
            if (followingSubstitutedIndex == null && !allStepIds.containsAll(step.getOnSuccess())) {
                // the step is empty but no substitute for following links, it means that before the step there are no non empty steps
                if (firstIndexWithOutgoingLinks >= 0 && firstIndexWithOutgoingLinks <= index) {
                    // the step or before the step, outgoing links exist out of the sub graph so we should not remove it, because it will impact the
                    // structure of the graph
                    emptyIndexes.remove(index);
                    continue;
                }
            }
            if (precedingSubstitutedIndex == null && !allStepIds.containsAll(step.getPrecedingSteps())) {
                // the step is empty but no substitute for preceding links, it means that after the step there are no non empty steps
                if (lastIndexWithOutgoingLinks >= index) {
                    // the step or after the step, outgoing links exist out of the sub graph so we should not remove it, because it will impact the
                    // structure of the graph
                    emptyIndexes.remove(index);
                    continue;
                }
            }
            // Empty so the step will be removed, so unlink all
            for (String following : step.getOnSuccess()) {
                workflow.getSteps().get(following).removePreceding(step.getName());
            }
            for (String preceding : step.getPrecedingSteps()) {
                workflow.getSteps().get(preceding).removeFollowing(step.getName());
            }
            if (followingSubstitutedIndex != null) {
                WorkflowStep substitutedFollowingStep = sortedByWeightsSteps.get(followingSubstitutedIndex);
                for (String following : step.getOnSuccess()) {
                    workflow.getSteps().get(following).addPreceding(substitutedFollowingStep.getName());
                }
                // Copy all links to the substituted node
                substitutedFollowingStep.addAllFollowings(step.getOnSuccess());
            }
            if (precedingSubstitutedIndex != null) {
                WorkflowStep substitutedPrecedingStep = sortedByWeightsSteps.get(precedingSubstitutedIndex);
                for (String preceding : step.getPrecedingSteps()) {
                    workflow.getSteps().get(preceding).addFollowing(substitutedPrecedingStep.getName());
                }
                substitutedPrecedingStep.addAllPrecedings(step.getPrecedingSteps());
            }
        }
    }
    int index = 0;
    Iterator<WorkflowStep> stepIterator = sortedByWeightsSteps.iterator();
    while (stepIterator.hasNext()) {
        WorkflowStep step = stepIterator.next();
        if (emptyIndexes.contains(index)) {
            stepIterator.remove();
            workflow.getSteps().remove(step.getName());
        }
        index++;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Iterator(java.util.Iterator) Getter(lombok.Getter) AlienUtils(alien4cloud.utils.AlienUtils) Workflow(org.alien4cloud.tosca.model.workflow.Workflow) WorkflowStepWeightComparator(alien4cloud.paas.wf.util.WorkflowStepWeightComparator) Set(java.util.Set) HashMap(java.util.HashMap) SubGraph(alien4cloud.paas.wf.util.SubGraph) SubGraphFilter(alien4cloud.paas.wf.util.SubGraphFilter) ArrayList(java.util.ArrayList) List(java.util.List) Component(org.springframework.stereotype.Component) WorkflowGraphUtils(alien4cloud.paas.wf.util.WorkflowGraphUtils) Slf4j(lombok.extern.slf4j.Slf4j) SimpleGraphConsumer(alien4cloud.paas.wf.util.SimpleGraphConsumer) Map(java.util.Map) Optional(java.util.Optional) NodeSubGraphFilter(alien4cloud.paas.wf.util.NodeSubGraphFilter) LinkedList(java.util.LinkedList) WorkflowStep(org.alien4cloud.tosca.model.workflow.WorkflowStep) LinkedHashSet(java.util.LinkedHashSet) WorkflowStep(org.alien4cloud.tosca.model.workflow.WorkflowStep) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList)

Aggregations

NodeSubGraphFilter (alien4cloud.paas.wf.util.NodeSubGraphFilter)1 SimpleGraphConsumer (alien4cloud.paas.wf.util.SimpleGraphConsumer)1 SubGraph (alien4cloud.paas.wf.util.SubGraph)1 SubGraphFilter (alien4cloud.paas.wf.util.SubGraphFilter)1 WorkflowGraphUtils (alien4cloud.paas.wf.util.WorkflowGraphUtils)1 WorkflowStepWeightComparator (alien4cloud.paas.wf.util.WorkflowStepWeightComparator)1 AlienUtils (alien4cloud.utils.AlienUtils)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Set (java.util.Set)1 Getter (lombok.Getter)1 Slf4j (lombok.extern.slf4j.Slf4j)1 Workflow (org.alien4cloud.tosca.model.workflow.Workflow)1 WorkflowStep (org.alien4cloud.tosca.model.workflow.WorkflowStep)1