@Override public void applyTo(ProcessInstanceModificationBuilder builder, ProcessEngine engine, ObjectMapper mapper) { validateParameters(); if (activityId != null) { builder.cancelAllForActivity(activityId); } else if (activityInstanceId != null) { builder.cancelActivityInstance(activityInstanceId); } else if (transitionInstanceId != null) { builder.cancelTransitionInstance(transitionInstanceId); } }
@Override public void applyTo(ProcessInstanceModificationBuilder builder, ProcessEngine engine, ObjectMapper mapper) { validateParameters(); if (activityId != null) { builder.cancelAllForActivity(activityId); } else if (activityInstanceId != null) { builder.cancelActivityInstance(activityInstanceId); } else if (transitionInstanceId != null) { builder.cancelTransitionInstance(transitionInstanceId); } }
@Deployment(resources = PARALLEL_GATEWAY_PROCESS) public void testCancellationThatEndsProcessInstance() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("parallelGateway"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(getInstanceIdForActivity(tree, "task1")) .cancelActivityInstance(getInstanceIdForActivity(tree, "task2")) .execute(); assertProcessEnded(processInstance.getId()); }
@Deployment(resources = PARALLEL_GATEWAY_PROCESS) public void testCancellationThatEndsProcessInstance() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("parallelGateway"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); Batch modificationBatch = runtimeService.createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(getInstanceIdForActivity(tree, "task1")) .cancelActivityInstance(getInstanceIdForActivity(tree, "task2")) .executeAsync(); assertNotNull(modificationBatch); executeSeedAndBatchJobs(modificationBatch); assertProcessEnded(processInstance.getId()); }
@Deployment(resources = PARALLEL_GATEWAY_PROCESS) public void testCancellationWithWrongProcessInstanceId() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("parallelGateway"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); try { runtimeService.createProcessInstanceModification("foo") .cancelActivityInstance(getInstanceIdForActivity(tree, "task1")) .cancelActivityInstance(getInstanceIdForActivity(tree, "task2")) .execute(); assertProcessEnded(processInstance.getId()); } catch (ProcessEngineException e) { assertThat(e.getMessage(), startsWith("ENGINE-13036")); assertThat(e.getMessage(), containsString("Process instance '" + "foo" + "' cannot be modified")); } }
@Deployment(resources = EXCLUSIVE_GATEWAY_PROCESS) public void testCancelNonExistingActivityInstance() { // given ProcessInstance instance = runtimeService.startProcessInstanceByKey("exclusiveGateway"); // when - then throw exception try { runtimeService.createProcessInstanceModification(instance.getId()).cancelActivityInstance("nonExistingActivityInstance").execute(); fail("should not succeed"); } catch (NotValidException e) { assertTextPresent("Cannot perform instruction: Cancel activity instance 'nonExistingActivityInstance'; " + "Activity instance 'nonExistingActivityInstance' does not exist", e.getMessage()); } }
@Deployment(resources = PARALLEL_GATEWAY_PROCESS) public void testCancellationWithWrongProcessInstanceId() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("parallelGateway"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); try { Batch modificationBatch = runtimeService.createProcessInstanceModification("foo") .cancelActivityInstance(getInstanceIdForActivity(tree, "task1")) .cancelActivityInstance(getInstanceIdForActivity(tree, "task2")) .executeAsync(); assertNotNull(modificationBatch); executeSeedAndBatchJobs(modificationBatch); assertProcessEnded(processInstance.getId()); } catch (ProcessEngineException e) { assertThat(e.getMessage(), startsWith("ENGINE-13036")); assertThat(e.getMessage(), containsString("Process instance '" + "foo" + "' cannot be modified")); } }
@Deployment(resources = ONE_TASK_PROCESS) public void testCancellationInOneTaskProcess() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); String processInstanceId = processInstance.getId(); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService .createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(getInstanceIdForActivity(tree, "theTask")) .execute(); assertProcessEnded(processInstanceId); }
@Deployment(resources = ONE_SCOPE_TASK_PROCESS) public void testCancellationInOneScopeTaskProcess() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); String processInstanceId = processInstance.getId(); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService .createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(getInstanceIdForActivity(tree, "theTask")) .execute(); assertProcessEnded(processInstanceId); }
@Deployment(resources = TRANSACTION_WITH_COMPENSATION_PROCESS) public void testCancelCompensatingTask() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess"); completeTasksInOrder("userTask"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "undoTask")).execute(); assertProcessEnded(processInstance.getId()); }
@Deployment(resources = SEQUENTIAL_MULTI_INSTANCE_TASK_PROCESS) public void testCancelInnerActivitySequentialTasks() { // given ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("miSequentialUserTasks"); completeTasksInOrder("beforeTask"); // when ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService .createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(tree.getActivityInstances("miTasks")[0].getId()) .execute(); // then assertProcessEnded(processInstance.getId()); }
@Deployment(resources = NESTED_ASYNC_BEFORE_TASK_PROCESS) public void testCancelAsyncActivityInstanceFails() { // given a process instance with an async task in a subprocess ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("nestedOneTaskProcess"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); // the the async task is not an activity instance so it cannot be cancelled as follows try { runtimeService.createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(getChildTransitionInstanceForTargetActivity(tree, "innerTask").getId()) .execute(); fail("should not succeed"); } catch (ProcessEngineException e) { assertTextPresent("activityInstance is null", e.getMessage()); } }
@Deployment(resources = SEQUENTIAL_MULTI_INSTANCE_SUBPROCESS_PROCESS) public void testCancelInnerActivitySequentialSubprocess() { // given ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("miSequentialSubprocess"); completeTasksInOrder("beforeTask"); // when ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService .createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(tree.getActivityInstances("miSubProcess")[0].getId()) .execute(); // then assertProcessEnded(processInstance.getId()); }
@Deployment(resources = ONE_TASK_PROCESS) public void testProcessInstanceVariablesPreservedOnIntermediateCancellation() { ProcessInstance processInstance = runtimeService .startProcessInstanceByKey("oneTaskProcess", Variables.createVariables().putValue("var", "value")); // when I execute cancellation and then start, such that the intermediate state of the process instance // has no activities ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()) .cancelActivityInstance(getInstanceIdForActivity(tree, "theTask")) .startBeforeActivity("theTask") .execute(); // then the process instance variables remain Object variable = runtimeService.getVariable(processInstance.getId(), "var"); assertNotNull(variable); assertEquals("value", variable); }
@Deployment(resources = TRANSACTION_WITH_COMPENSATION_PROCESS) public void testCancelCompensatingTaskAndStartActivity() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess"); completeTasksInOrder("userTask"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "undoTask")) .startBeforeActivity("userTask").execute(); tree = runtimeService.getActivityInstance(processInstance.getId()); assertThat(tree).hasStructure(describeActivityInstanceTree(processInstance.getProcessDefinitionId()).beginScope("tx").activity("userTask").done()); completeTasksInOrder("userTask", "undoTask", "afterCancel"); assertProcessEnded(processInstance.getId()); }
@Deployment(resources = TRANSACTION_WITH_COMPENSATION_PROCESS) public void testCancelCompensatingTaskAndStartActivityWithAncestor() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess"); completeTasksInOrder("userTask"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "undoTask")) .startBeforeActivity("userTask", processInstance.getId()).execute(); tree = runtimeService.getActivityInstance(processInstance.getId()); assertThat(tree).hasStructure(describeActivityInstanceTree(processInstance.getProcessDefinitionId()).beginScope("tx").activity("userTask").done()); completeTasksInOrder("userTask", "undoTask", "afterCancel"); assertProcessEnded(processInstance.getId()); }
@Deployment public void testNoCompensationCreatedOnCancellation() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("compensationProcess"); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); // one on outerTask, one on innerTask assertEquals(2, taskService.createTaskQuery().count()); // when inner task is cancelled runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "innerTask")).execute(); // then no compensation event subscription exists assertEquals(0, runtimeService.createEventSubscriptionQuery().count()); // and the compensation throw event does not trigger compensation handlers Task task = taskService.createTaskQuery().singleResult(); assertNotNull(task); assertEquals("outerTask", task.getTaskDefinitionKey()); taskService.complete(task.getId()); assertProcessEnded(processInstance.getId()); }
@Deployment public void testCompensationRemovalOnCancellation() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("compensationProcess"); Execution taskExecution = runtimeService.createExecutionQuery().activityId("innerTask").singleResult(); Task task = taskService.createTaskQuery().executionId(taskExecution.getId()).singleResult(); assertNotNull(task); taskService.complete(task.getId()); // there should be a compensation event subscription for innerTask now assertEquals(1, runtimeService.createEventSubscriptionQuery().count()); // when innerTask2 is cancelled ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "innerTask2")).execute(); // then the innerTask compensation should be removed assertEquals(0, runtimeService.createEventSubscriptionQuery().count()); }
@Deployment(resources = PARALLEL_GATEWAY_PROCESS) public void testCancellation() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("parallelGateway"); String processInstanceId = processInstance.getId(); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "task1")).execute(); ActivityInstance updatedTree = runtimeService.getActivityInstance(processInstanceId); assertNotNull(updatedTree); assertEquals(processInstanceId, updatedTree.getProcessInstanceId()); assertThat(updatedTree).hasStructure(describeActivityInstanceTree(processInstance.getProcessDefinitionId()).activity("task2").done()); ExecutionTree executionTree = ExecutionTree.forExecution(processInstanceId, processEngine); assertThat(executionTree).matches(describeExecutionTree("task2").scope().done()); // complete the process completeTasksInOrder("task2"); assertProcessEnded(processInstanceId); }
@Deployment(resources = EXCLUSIVE_GATEWAY_PROCESS) public void testCancellationAndStartBefore() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exclusiveGateway"); String processInstanceId = processInstance.getId(); ActivityInstance tree = runtimeService.getActivityInstance(processInstance.getId()); runtimeService.createProcessInstanceModification(processInstance.getId()).cancelActivityInstance(getInstanceIdForActivity(tree, "task1")) .startBeforeActivity("task2").execute(); ActivityInstance activityInstanceTree = runtimeService.getActivityInstance(processInstanceId); assertNotNull(activityInstanceTree); assertEquals(processInstanceId, activityInstanceTree.getProcessInstanceId()); assertThat(activityInstanceTree).hasStructure(describeActivityInstanceTree(processInstance.getProcessDefinitionId()).activity("task2").done()); ExecutionTree executionTree = ExecutionTree.forExecution(processInstanceId, processEngine); assertThat(executionTree).matches(describeExecutionTree("task2").scope().done()); completeTasksInOrder("task2"); assertProcessEnded(processInstanceId); }