Skip to content

Commit

Permalink
TE-624: Check next element of parallel task
Browse files Browse the repository at this point in the history
  • Loading branch information
trungmaihova committed Jul 5, 2024
1 parent e8ad45e commit b0c40ce
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 125 deletions.
61 changes: 49 additions & 12 deletions process-inspector-test/processes/FlowParallelInOrder.p.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"signature" : "start"
},
"visual" : {
"at" : { "x" : 128, "y" : 168 }
"at" : { "x" : 128, "y" : 104 }
},
"connect" : [
{ "id" : "f2", "to" : "f3", "var" : "in1" }
Expand All @@ -21,7 +21,7 @@
"id" : "f1",
"type" : "TaskEnd",
"visual" : {
"at" : { "x" : 864, "y" : 168 }
"at" : { "x" : 736, "y" : 104 }
}
}, {
"id" : "f3",
Expand All @@ -48,15 +48,22 @@
"",
"APAConfig.setEstimate(2,TimeUnit.HOURS,UseCase.SMALLPROJECT);"
]
}, {
"id" : "TaskC",
"name" : "Task 1C",
"responsible" : {
"activator" : "SYSTEM"
}
} ]
},
"visual" : {
"at" : { "x" : 200, "y" : 168 },
"at" : { "x" : 200, "y" : 104 },
"labelOffset" : { "x" : -8, "y" : -8 }
},
"connect" : [
{ "id" : "f5", "to" : "f4", "via" : [ { "x" : 200, "y" : 112 } ], "condition" : "ivp==\"TaskA.ivp\"" },
{ "id" : "f9", "to" : "f8", "via" : [ { "x" : 200, "y" : 224 } ], "condition" : "ivp==\"TaskB.ivp\"" }
{ "id" : "f5", "to" : "f4", "via" : [ { "x" : 200, "y" : 56 } ], "condition" : "ivp==\"TaskA.ivp\"" },
{ "id" : "f9", "to" : "f8", "via" : [ { "x" : 216, "y" : 144 } ], "condition" : "ivp==\"TaskB.ivp\"" },
{ "id" : "f132", "to" : "f115", "via" : [ { "x" : 200, "y" : 224 } ], "condition" : "ivp==\"TaskC.ivp\"" }
]
}, {
"id" : "f4",
Expand All @@ -77,7 +84,7 @@
}
},
"visual" : {
"at" : { "x" : 312, "y" : 112 }
"at" : { "x" : 280, "y" : 56 }
},
"connect" : [
{ "id" : "f7", "to" : "f6" }
Expand All @@ -101,10 +108,10 @@
}
},
"visual" : {
"at" : { "x" : 480, "y" : 112 }
"at" : { "x" : 432, "y" : 56 }
},
"connect" : [
{ "id" : "f11", "to" : "f10", "via" : [ { "x" : 576, "y" : 112 } ], "var" : "in1" }
{ "id" : "f11", "to" : "f10", "via" : [ { "x" : 520, "y" : 56 } ], "var" : "in1" }
]
}, {
"id" : "f8",
Expand All @@ -125,10 +132,10 @@
}
},
"visual" : {
"at" : { "x" : 400, "y" : 224 }
"at" : { "x" : 352, "y" : 144 }
},
"connect" : [
{ "id" : "f12", "to" : "f10", "via" : [ { "x" : 576, "y" : 224 } ], "var" : "in2" }
{ "id" : "f12", "to" : "f10", "via" : [ { "x" : 520, "y" : 144 } ], "var" : "in2" }
]
}, {
"id" : "f10",
Expand All @@ -143,7 +150,7 @@
} ]
},
"visual" : {
"at" : { "x" : 576, "y" : 168 },
"at" : { "x" : 520, "y" : 104 },
"labelOffset" : { "x" : -16, "y" : 24 }
},
"connect" : [
Expand All @@ -160,7 +167,7 @@
}
},
"visual" : {
"at" : { "x" : 712, "y" : 168 }
"at" : { "x" : 624, "y" : 104 }
},
"connect" : [
{ "id" : "f15", "to" : "f1" }
Expand Down Expand Up @@ -1093,6 +1100,36 @@
"connect" : [
{ "id" : "f114", "to" : "f102", "var" : "in2" }
]
}, {
"id" : "f115",
"type" : "UserTask",
"name" : "Task E",
"config" : {
"dialog" : "com.axonivy.utils.process.inspector.test.Dummy:start()",
"task" : {
"name" : "Task E",
"code" : [
"import com.axonivy.utils.process.inspector.test.UseCase;",
"import com.axonivy.utils.process.inspector.APAConfig;",
"import java.util.concurrent.TimeUnit;",
"",
"APAConfig.setEstimate(5,TimeUnit.HOURS,UseCase.BIGPROJECT);",
"APAConfig.setEstimate(3,TimeUnit.HOURS,UseCase.SMALLPROJECT);"
]
}
},
"visual" : {
"at" : { "x" : 360, "y" : 224 }
},
"connect" : [
{ "id" : "f144", "to" : "f135" }
]
}, {
"id" : "f135",
"type" : "TaskEnd",
"visual" : {
"at" : { "x" : 552, "y" : 224 }
}
} ],
"layout" : {
"colors" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void shouldshouldFindAllTasksAtStart(BpmClient bpmClient) throws Exception {

var detectedTasks = processInspector.findAllTasks(icase, null);

var expected = Arrays.array("Task 1A", "Task A", "Task B", "Task 1B", "Task C", "Task D");
var expected = Arrays.array("Task E", "Task 1A", "Task A", "Task B", "Task 1B", "Task C", "Task D");
var taskNames = getTaskNames(detectedTasks);
assertArrayEquals(expected, taskNames);
}
Expand All @@ -60,7 +60,7 @@ void shouldFindTasksOnPathByCaseAtTaskBAndTaskC(BpmClient bpmClient) throws Exce
ExecutionResult result = bpmClient.start().process(FLOW_PARALLEL_IN_ORDER.elementName("start")).execute();
List<ITask> parallelTasks = result.workflow().activeTasks();
for (ITask task : parallelTasks) {
result = bpmClient.start().task(task).as().everybody().execute();
result = bpmClient.start().task(task).as().systemUser().execute();
}

List<ITask> activeTasks = result.workflow().activeTasks();
Expand All @@ -74,7 +74,7 @@ void shouldFindTasksOnPathByCaseAtTaskBAndTaskC(BpmClient bpmClient) throws Exce

var detectedTasks = processInspector.findTasksOnPath(icase, null, null);

var expected = Arrays.array("Task C", "Task B", "Task D");
var expected = Arrays.array("Task E", "Task C", "Task B", "Task D");
var taskNames = getTaskNames(detectedTasks);
assertArrayEquals(expected, taskNames);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void shouldFindAllTasksAtStart() throws Exception {
List<DetectedTask> detectedTasks = processInspector.findAllTasks(start, null).stream()
.map(DetectedTask.class::cast).toList();

var expected = Arrays.array("Task 1A", "Task A", "Task B", "Task 1B", "Task C", "Task D");
var expected = Arrays.array("Task E", "Task 1A", "Task A", "Task B", "Task 1B", "Task C", "Task D");
var taskNames = getTaskNames(detectedTasks);
assertArrayEquals(expected, taskNames);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.addAllToPath;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.addToPath;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.convertToAnalysisPath;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.findIncomingsFromPaths;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.getAllStartElementOfTaskSwitchGateways;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.getAnalysisPathFrom;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.getAnalysisPathTo;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.getInternalPath;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.getLastProcessElements;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.getPathByStartElements;
import static com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper.replaceFirstElement;
import static java.util.Collections.emptyList;
Expand All @@ -27,8 +30,6 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections4.MapUtils;

import com.axonivy.utils.process.inspector.internal.helper.AnalysisPathHelper;
import com.axonivy.utils.process.inspector.internal.model.AnalysisPath;
import com.axonivy.utils.process.inspector.internal.model.CommonElement;
Expand Down Expand Up @@ -166,7 +167,7 @@ private Map<ProcessElement, List<AnalysisPath>> mergePath(Map<ProcessElement, Li

TaskParallelGroup taskGroup = convertToTaskParallelGroup(pathBeforeIntersection);

List<AnalysisPath> fullPathWithIntersection = addToPath(List.of(new AnalysisPath(List.of(taskGroup))), subPath);
List<AnalysisPath> fullPathWithIntersection = addToPath(new AnalysisPath(List.of(taskGroup)), subPath);

Map<ProcessElement, List<AnalysisPath>> result = new LinkedHashMap<>();
result.putAll(pathNotIntersection);
Expand Down Expand Up @@ -231,7 +232,7 @@ private List<AnalysisPath> convertToAnalysisPaths(Map<ProcessElement, List<Analy

List<AnalysisPath> subPathAfterIntersection = getAnalysisPathFrom(paths, intersection);

result.addAll(addToPath(List.of(new AnalysisPath(List.of(taskGroup))), subPathAfterIntersection));
result.addAll(addToPath(new AnalysisPath(List.of(taskGroup)), subPathAfterIntersection));
}

return result;
Expand All @@ -251,15 +252,14 @@ private Map<ProcessElement, List<AnalysisPath>> getPathHaveNoIntersection(
}

private TaskParallelGroup convertToTaskParallelGroupWithInternalPath(Map<ProcessElement, List<AnalysisPath>> internalPaths) {
TaskParallelGroup taskGroup = new TaskParallelGroup(null);


Map<SequenceFlow, List<AnalysisPath>> result = new LinkedHashMap<>();
internalPaths.entrySet().forEach(it -> {
SequenceFlow sequenceFlow = processGraph.getFirstIncoming(it.getKey().getElement());
result.put(sequenceFlow, it.getValue());
});

taskGroup.setInternalPaths(result);
TaskParallelGroup taskGroup = new TaskParallelGroup(null, convertToAnalysisPath(result));
return taskGroup;
}

Expand Down Expand Up @@ -374,23 +374,55 @@ private Map<SequenceFlow, List<AnalysisPath>> findAnalysisPathForNextNode(Proces
return pathOptions;
}

private TaskParallelGroup getTaskParallelGroup(ProcessElement from, String flowName, FindType findType,
List<AnalysisPath> currentPath) throws Exception {
TaskParallelGroup result = new TaskParallelGroup(from.getElement());
private TaskParallelGroup getTaskParallelGroup(ProcessElement from, String flowName, FindType findType, List<AnalysisPath> currentPath) throws Exception {

List<SequenceFlow> outs = getSequenceFlows((NodeElement) from.getElement(), flowName, findType);

Map<SequenceFlow, List<AnalysisPath>> paths = new LinkedHashMap<>();
Map<SequenceFlow, List<AnalysisPath>> paths = new LinkedHashMap<>();
for (SequenceFlow out : outs) {
CommonElement outElement = new CommonElement(out);
List<AnalysisPath> newPath = addAllToPath(currentPath, Arrays.asList(from, outElement));

ProcessElement nextStartElement = new CommonElement(out.getTarget());
List<AnalysisPath> nextOfPath = findAnalysisPaths(nextStartElement, flowName, findType, newPath);
paths.put(out, nextOfPath);
paths.put(out, nextOfPath);
}

List<AnalysisPath> convertedPaths = convertToAnalysisPath(paths);
List<ProcessElement> lastElements = getLastProcessElements(new TaskParallelGroup(from.getElement(), convertedPaths));
ProcessElement joinTask = lastElements.stream().filter(it -> it.getElement()instanceof TaskSwitchGateway ).findFirst().orElse(null);

List<AnalysisPath> internalPaths = new ArrayList<>() ;
//Map<SequenceFlow, List<AnalysisPath>> internalPaths = new LinkedHashMap<>();
//Check join incoming is less then split task
if (joinTask != null && ((NodeElement) joinTask.getElement()).getIncoming().size() < outs.size()) {
List<SequenceFlow> startPathWithoutTaskEnd = getInternalPath(convertedPaths, false).stream()
.map(AnalysisPathHelper::getFirsElement)
.map(ProcessElement::getElement)
.filter(SequenceFlow.class::isInstance)
.map(SequenceFlow.class::cast)
.distinct().toList();

Map<SequenceFlow, List<AnalysisPath>> subInteralPaths = new LinkedHashMap<>();
for(Entry<SequenceFlow, List<AnalysisPath>> entry : paths.entrySet()) {
if(startPathWithoutTaskEnd.contains(entry.getKey())) {
subInteralPaths.put(entry.getKey(), entry.getValue());
} else {
internalPaths.addAll(addToPath(new AnalysisPath(new CommonElement(entry.getKey())), entry.getValue()));
}
}

TaskParallelGroup subTaskGroup = new TaskParallelGroup(from.getElement(),convertToAnalysisPath(subInteralPaths));

result.setInternalPaths(paths);

List<AnalysisPath> nextPaths = findAnalysisPaths(joinTask, flowName, findType, emptyList());
var newInternalPaths = addToPath(new AnalysisPath(subTaskGroup), nextPaths);

internalPaths.addAll(newInternalPaths);
} else {
internalPaths = convertToAnalysisPath(paths);
}

TaskParallelGroup result = new TaskParallelGroup(from.getElement(), internalPaths);
return result;
}

Expand Down Expand Up @@ -613,6 +645,7 @@ private List<AnalysisPath> correctInternalPathByNextSequence(List<AnalysisPath>

return result;
}

private List<AnalysisPath> getAnalysisPathBaseOnNextSequenceFlow(List<AnalysisPath> internalPaths, ProcessElement nextElement) {
if(nextElement == null) {
return internalPaths;
Expand All @@ -631,19 +664,19 @@ private List<AnalysisPath> getAnalysisPathBaseOnNextSequenceFlow(List<AnalysisPa
}

if (processGraph.isTaskSwitchGateway(lastElement)) {
Map<SequenceFlow, List<AnalysisPath>> validInternalPaths = new LinkedHashMap<>();
((TaskParallelGroup) lastProcessElement).getInternalPaths().forEach((key, value) -> {
var validPaths = getAnalysisPathBaseOnNextSequenceFlow(value, nextElement);
//Map<SequenceFlow, List<AnalysisPath>> validInternalPaths = new LinkedHashMap<>();
List<AnalysisPath> validInternalPaths = new ArrayList<>();
((TaskParallelGroup) lastProcessElement).getPaths().forEach(value -> {
var validPaths = getAnalysisPathBaseOnNextSequenceFlow(List.of(value), nextElement);
if (isNotEmpty(validPaths)) {
validInternalPaths.put(key, validPaths);
validInternalPaths.addAll(validPaths);
}
});

int size = path.getElements().size();
List<ProcessElement> newPath = path.getElements().stream().limit(size - 1).collect(Collectors.toList());
if (MapUtils.isNotEmpty(validInternalPaths)) {
TaskParallelGroup taskGroup = new TaskParallelGroup(lastElement);
taskGroup.setInternalPaths(validInternalPaths);
if (isNotEmpty(validInternalPaths)) {
TaskParallelGroup taskGroup = new TaskParallelGroup(lastElement, validInternalPaths);
newPath.add(taskGroup);
}
result.add(new AnalysisPath(newPath));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ public TaskConfig getStartTaskConfig(SequenceFlow sequenceFlow) {
return taskConfig;
}

public boolean isSystemTask(TaskConfig task) {
if(task instanceof TaskConfig) {
String roleName = ((TaskConfig) task).getActivator().getName();
return Role.SYSTEM.name().equals(roleName);
}

return false;
}

public boolean isSystemTask(BaseElement task) {
if (task instanceof TaskAndCaseModifier) {
return ((TaskAndCaseModifier) task).getAllTaskConfigs().stream()
Expand Down
Loading

0 comments on commit b0c40ce

Please sign in to comment.