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++;
}
}
Aggregations