I have some independent camunda engines that propagate their userTasks to a central taskList (via TaskCreateListener). This creates “proxyTasks” that, when completed, also complete the “remoteTask”.
I am able to recognise if the remoteTask is completed directly (OnTaskComplete) or the process instance is cancelled (OnTaskDelete), in these cases I notify the central tasklist that the proxyTask is no longer needed.
But what if the remoteTask is ended by a boundaryEvent (Timer, Message, …)? Neither the complete nor the delete listeners are called. How can I avoid leaving the proxyTask open in this case? Anything in the engine/spec? Or would this require a 5th taskListener-event “onInterrupt”?
Hi Jan,
The delete
event should cover this case as well and we also have a test for this case (see https://github.com/camunda/camunda-bpm-platform/blob/7.10.0-alpha4/engine/src/test/java/org/camunda/bpm/engine/test/bpmn/tasklistener/TaskListenerTest.java#L125).
Can you please provide a test case with a model where the delete
event is not triggered?
Cheers,
Thorben
Hm, seems you are right, false alarm … I took a step away from the code and created a minimal example, and it works. Must have been a lack of coffee.
public class TaskListenerOnBoundaryEventTest {
private final static String TASK_DEFINITION_KEY = "test-task";
private final static String END_SUCCESS = "success";
private final static String END_INTERRUPT = "interrupted";
private final static String MSG_INTERRUPT = "INTERRUPT";
private static final String PROCESS_KEY = "test";
// -- register two listeners --
private final FluentTaskListenerMock onDelete = registerTaskListenerMock("onDelete");
private final FluentTaskListenerMock onComplete = registerTaskListenerMock("onComplete");
private ProcessInstance processInstance;
private Task task;
@Rule
public final ProcessEngineRule camunda = new ProcessEngineRule(new StandaloneInMemProcessEngineConfiguration() {{
jobExecutorActivate = false;
expressionManager = new MockExpressionManager();
databaseSchemaUpdate = DB_SCHEMA_UPDATE_DROP_CREATE;
isDbMetricsReporterActivate = false;
historyLevel = HistoryLevel.HISTORY_LEVEL_FULL;
}}.buildProcessEngine());
@Before
public void generateAndDeployProcess() {
camunda.manageDeployment(camunda.getRepositoryService().createDeployment()
.addModelInstance(PROCESS_KEY + ".bpmn", Bpmn.createExecutableProcess(PROCESS_KEY)
.startEvent()
.userTask(TASK_DEFINITION_KEY)
.camundaTaskListenerDelegateExpression(TaskListener.EVENTNAME_DELETE, "${onDelete}")
.camundaTaskListenerDelegateExpression(TaskListener.EVENTNAME_COMPLETE, "${onComplete}")
.boundaryEvent().message(MSG_INTERRUPT).endEvent(END_INTERRUPT)
.moveToNode(TASK_DEFINITION_KEY)
.endEvent(END_SUCCESS)
.done())
.deploy());
}
@Test
public void onDelete_when_process_cancelled() {
startProcess();
camunda.getRuntimeService().deleteProcessInstance(processInstance.getProcessInstanceId(), "test");
verifyTaskListenerMock(onComplete).executedNever();
verifyTaskListenerMock(onDelete).executed();
}
@Test
public void onComplete_when_task_completed() {
startProcess();
camunda.getTaskService().complete(task.getId());
assertThat(processInstanceEndedWith()).isEqualTo(END_SUCCESS);
verifyTaskListenerMock(onComplete).executed();
verifyTaskListenerMock(onDelete).executedNever();
}
@Test
public void onDelete_when_boundary() {
startProcess();
camunda.getRuntimeService().correlateMessage(MSG_INTERRUPT);
assertThat(processInstanceEndedWith()).isEqualTo(END_INTERRUPT);
verifyTaskListenerMock(onComplete).executedNever();
verifyTaskListenerMock(onDelete).executed();
}
private void startProcess() {
processInstance = camunda.getRuntimeService().startProcessInstanceByKey(PROCESS_KEY);
task = camunda.getTaskService().createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
assertThat(processInstanceEndedWith()).isNull();
assertThat(task).isNotNull();
// so far nothing happened
verifyTaskListenerMock(onComplete).executedNever();
verifyTaskListenerMock(onDelete).executedNever();
}
private String processInstanceEndedWith() {
return camunda.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(processInstance.getProcessInstanceId())
.singleResult()
.getEndActivityId();
}
}
see https://github.com/holunda-io/holunda-spike/tree/master/forum/task-delete-9302
1 Like