TSK-909 - Claim task in camunda if task is claimed in TASKANA
-Added a new CallbackState which is needed when a task was claimed by TASKANA -Added ruleset logic to determine if the public API is allowed to set the desired CallbackState -Added test for the ruleset logic
This commit is contained in:
parent
b49a18048e
commit
536e09911a
|
@ -4,5 +4,5 @@ package pro.taskana;
|
|||
* This enum contains all status of synchronization between a taskana task and a task in a remote system.
|
||||
*/
|
||||
public enum CallbackState {
|
||||
NONE, CALLBACK_PROCESSING_REQUIRED, CALLBACK_PROCESSING_COMPLETED
|
||||
NONE, CALLBACK_PROCESSING_REQUIRED, CLAIMED, CALLBACK_PROCESSING_COMPLETED
|
||||
}
|
||||
|
|
|
@ -459,7 +459,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
|
||||
Iterator<String> taskIdIterator = externalIds.iterator();
|
||||
while (taskIdIterator.hasNext()) {
|
||||
removeSingleTaskForCallbackStateByExternalId(bulkLog, taskSummaries, taskIdIterator);
|
||||
removeSingleTaskForCallbackStateByExternalId(bulkLog, taskSummaries, taskIdIterator, state);
|
||||
}
|
||||
if (!externalIds.isEmpty()) {
|
||||
taskMapper.setCallbackStateMultiple(externalIds, state);
|
||||
|
@ -505,7 +505,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
|
||||
private void removeSingleTaskForCallbackStateByExternalId(BulkOperationResults<String,
|
||||
TaskanaException> bulkLog,
|
||||
List<MinimalTaskSummary> taskSummaries, Iterator<String> externalIdIterator) {
|
||||
List<MinimalTaskSummary> taskSummaries, Iterator<String> externalIdIterator, CallbackState desiredCallbackState) {
|
||||
LOGGER.debug("entry to removeSingleTask()");
|
||||
String currentExternalId = externalIdIterator.next();
|
||||
if (currentExternalId == null || currentExternalId.equals("")) {
|
||||
|
@ -521,14 +521,50 @@ public class TaskServiceImpl implements TaskService {
|
|||
bulkLog.addError(currentExternalId, new TaskNotFoundException(currentExternalId,
|
||||
TASK_WITH_ID + currentExternalId + WAS_NOT_FOUND2));
|
||||
externalIdIterator.remove();
|
||||
} else if (!TaskState.COMPLETED.equals(foundSummary.getTaskState())) {
|
||||
} else if (!desiredCallbackStateCanBeSetForFoundSummary(foundSummary, desiredCallbackState)) {
|
||||
bulkLog.addError(currentExternalId, new InvalidStateException(currentExternalId));
|
||||
externalIdIterator.remove();
|
||||
}
|
||||
|
||||
}
|
||||
LOGGER.debug("exit from removeSingleTask()");
|
||||
}
|
||||
|
||||
private boolean desiredCallbackStateCanBeSetForFoundSummary(MinimalTaskSummary foundSummary, CallbackState desiredCallbackState) {
|
||||
|
||||
CallbackState currentTaskCallbackState = foundSummary.getCallbackState();
|
||||
TaskState currentTaskState = foundSummary.getTaskState();
|
||||
|
||||
switch (desiredCallbackState) {
|
||||
|
||||
case CALLBACK_PROCESSING_COMPLETED:
|
||||
if (!(currentTaskState.equals(TaskState.COMPLETED))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case CLAIMED:
|
||||
if (!currentTaskState.equals(TaskState.CLAIMED)) {
|
||||
return false;
|
||||
} else if (!currentTaskCallbackState.equals(CallbackState.CALLBACK_PROCESSING_REQUIRED)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case CALLBACK_PROCESSING_REQUIRED:
|
||||
if (currentTaskCallbackState.equals(CallbackState.CALLBACK_PROCESSING_COMPLETED)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case NONE:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> updateTasks(ObjectReference selectionCriteria,
|
||||
Map<String, String> customFieldsToUpdate) throws InvalidArgumentException {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package acceptance.task;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -44,7 +43,6 @@ import pro.taskana.security.WithAccessId;
|
|||
@ExtendWith(JAASExtension.class)
|
||||
class CallbackStateAccTest extends AbstractAccTest {
|
||||
|
||||
|
||||
@WithAccessId(
|
||||
userName = "user_1_1",
|
||||
groupNames = {"group_1"})
|
||||
|
@ -65,6 +63,11 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
createdTask = createTask(taskService, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
createdTask = (TaskImpl) taskService.getTask(createdTask.getId());
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_COMPLETED, createdTask.getCallbackState());
|
||||
|
||||
createdTask = createTask(taskService, CallbackState.CLAIMED);
|
||||
createdTask = (TaskImpl) taskService.getTask(createdTask.getId());
|
||||
assertEquals(CallbackState.CLAIMED, createdTask.getCallbackState());
|
||||
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
|
@ -73,16 +76,17 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
@Test
|
||||
void testDeletionOfTaskWithWrongCallbackStateIsBlocked()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException, InvalidOwnerException {
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException,
|
||||
InvalidOwnerException {
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
final TaskImpl createdTask = createTask(taskanaEngine.getTaskService(), CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
final TaskImpl createdTask = createTask(taskanaEngine.getTaskService(),
|
||||
CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_REQUIRED, createdTask.getCallbackState());
|
||||
|
||||
assertEquals(TaskState.READY, createdTask.getState());
|
||||
String endOfMessage = " cannot be deleted because its callback is not yet processed";
|
||||
|
||||
|
||||
Throwable t = Assertions.assertThrows(InvalidStateException.class, () -> {
|
||||
taskService.forceDeleteTask(createdTask.getId());
|
||||
});
|
||||
|
@ -111,7 +115,8 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
@Test
|
||||
void testUpdateOfCallbackState()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException, InvalidOwnerException {
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException,
|
||||
InvalidOwnerException {
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
TaskImpl createdTask1 = createTask(taskanaEngine.getTaskService(), CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
|
@ -131,8 +136,10 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
assertEquals(TaskState.COMPLETED, createdTask2.getState());
|
||||
assertEquals(TaskState.COMPLETED, createdTask3.getState());
|
||||
|
||||
List<String> taskIds = new ArrayList<>(Arrays.asList(createdTask1.getId(), createdTask2.getId(), createdTask3.getId()));
|
||||
List<String> externalIds = new ArrayList<>(Arrays.asList(createdTask1.getExternalId(), createdTask2.getExternalId(), createdTask3.getExternalId()));
|
||||
List<String> taskIds = new ArrayList<>(
|
||||
Arrays.asList(createdTask1.getId(), createdTask2.getId(), createdTask3.getId()));
|
||||
List<String> externalIds = new ArrayList<>(
|
||||
Arrays.asList(createdTask1.getExternalId(), createdTask2.getExternalId(), createdTask3.getExternalId()));
|
||||
// delete should fail because callback_state = CALLBACK_PROCESSING_REQUIRED
|
||||
BulkOperationResults<String, TaskanaException> bulkResult1 = taskService.deleteTasks(taskIds);
|
||||
|
||||
|
@ -146,7 +153,8 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
}
|
||||
|
||||
// now enable deletion by setting callback state to CALLBACK_PROCESSING_COMPLETED
|
||||
BulkOperationResults<String, TaskanaException> bulkResult2 = taskService.setCallbackStateForTasks(externalIds, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
BulkOperationResults<String, TaskanaException> bulkResult2 = taskService.setCallbackStateForTasks(externalIds,
|
||||
CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertFalse(bulkResult2.containsErrors());
|
||||
|
||||
taskIds = new ArrayList<>(Arrays.asList(createdTask1.getId(), createdTask2.getId(), createdTask3.getId()));
|
||||
|
@ -155,13 +163,155 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
assertFalse(bulkResult3.containsErrors());
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
userName = "admin",
|
||||
groupNames = {"group_1"})
|
||||
@Test
|
||||
void testInvalidUpdateOfCallbackStateToNone()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException {
|
||||
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
TaskImpl createdTask1 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_REQUIRED, createdTask1.getCallbackState());
|
||||
|
||||
TaskImpl createdTask2 = createTask(taskService, CallbackState.CLAIMED);
|
||||
assertEquals(CallbackState.CLAIMED, createdTask2.getCallbackState());
|
||||
|
||||
TaskImpl createdTask3 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_COMPLETED, createdTask3.getCallbackState());
|
||||
|
||||
List<String> externalIds = new ArrayList<>(
|
||||
Arrays.asList(createdTask1.getExternalId(), createdTask2.getExternalId(), createdTask3.getExternalId()));
|
||||
|
||||
//try to set CallbackState to NONE
|
||||
BulkOperationResults<String, TaskanaException> bulkResult = taskService.setCallbackStateForTasks(externalIds,
|
||||
CallbackState.NONE);
|
||||
|
||||
//It's never allowed to set CallbackState to NONE over public API
|
||||
assertTrue(bulkResult.containsErrors());
|
||||
List<String> failedTaskIds = bulkResult.getFailedIds();
|
||||
assertTrue(failedTaskIds.size() == 3);
|
||||
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
userName = "admin",
|
||||
groupNames = {"group_1"})
|
||||
@Test
|
||||
void testInvalidUpdateOfCallbackStateToComplete()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException, InvalidOwnerException, InvalidStateException,
|
||||
TaskNotFoundException {
|
||||
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
TaskImpl createdTask1 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_REQUIRED, createdTask1.getCallbackState());
|
||||
|
||||
TaskImpl createdTask2 = createTask(taskService, CallbackState.CLAIMED);
|
||||
assertEquals(CallbackState.CLAIMED, createdTask2.getCallbackState());
|
||||
|
||||
TaskImpl createdTask3 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_COMPLETED, createdTask3.getCallbackState());
|
||||
|
||||
List<String> externalIds = new ArrayList<>(
|
||||
Arrays.asList(createdTask1.getExternalId(), createdTask2.getExternalId(), createdTask3.getExternalId()));
|
||||
|
||||
|
||||
//complete a task
|
||||
createdTask3 = (TaskImpl) taskService.forceCompleteTask(createdTask3.getId());
|
||||
|
||||
//It's only allowed to set CallbackState to COMPLETE, if TaskState equals COMPLETE, therefore 2 tasks should not get updated
|
||||
BulkOperationResults<String, TaskanaException> bulkResult = taskService.setCallbackStateForTasks(externalIds,
|
||||
CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertTrue(bulkResult.containsErrors());
|
||||
List<String> failedTaskIds = bulkResult.getFailedIds();
|
||||
assertTrue(failedTaskIds.size() == 2 && !failedTaskIds.contains(createdTask3.getExternalId()));
|
||||
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
userName = "admin",
|
||||
groupNames = {"group_1"})
|
||||
@Test
|
||||
void testInvalidUpdateOfCallbackStateToClaimed()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException,
|
||||
InvalidOwnerException {
|
||||
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
TaskImpl createdTask1 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_REQUIRED, createdTask1.getCallbackState());
|
||||
|
||||
TaskImpl createdTask2 = createTask(taskService, CallbackState.CLAIMED);
|
||||
assertEquals(CallbackState.CLAIMED, createdTask2.getCallbackState());
|
||||
|
||||
TaskImpl createdTask3 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_COMPLETED, createdTask3.getCallbackState());
|
||||
|
||||
List<String> externalIds = new ArrayList<>(
|
||||
Arrays.asList(createdTask1.getExternalId(), createdTask2.getExternalId(), createdTask3.getExternalId()));
|
||||
|
||||
|
||||
//claim two tasks
|
||||
createdTask1 = (TaskImpl) taskService.forceClaim(createdTask1.getId());
|
||||
createdTask2 = (TaskImpl) taskService.forceClaim(createdTask2.getId());
|
||||
|
||||
//It's only allowed to claim a task if the TaskState equals CLAIMED and the CallbackState equals REQUIRED
|
||||
//Therefore 2 tasks should not get updated
|
||||
BulkOperationResults<String, TaskanaException> bulkResult = taskService.setCallbackStateForTasks(externalIds,
|
||||
CallbackState.CLAIMED);
|
||||
assertTrue(bulkResult.containsErrors());
|
||||
List<String> failedTaskIds = bulkResult.getFailedIds();
|
||||
assertTrue(failedTaskIds.size() == 2 && !failedTaskIds.contains(createdTask1.getExternalId()));
|
||||
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
userName = "admin",
|
||||
groupNames = {"group_1"})
|
||||
@Test
|
||||
void testInvalidUpdateOfCallbackStateToRequired()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException {
|
||||
|
||||
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
TaskImpl createdTask1 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_REQUIRED, createdTask1.getCallbackState());
|
||||
|
||||
TaskImpl createdTask2 = createTask(taskService, CallbackState.CLAIMED);
|
||||
assertEquals(CallbackState.CLAIMED, createdTask2.getCallbackState());
|
||||
|
||||
TaskImpl createdTask3 = createTask(taskService, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertEquals(CallbackState.CALLBACK_PROCESSING_COMPLETED, createdTask3.getCallbackState());
|
||||
|
||||
List<String> externalIds = new ArrayList<>(
|
||||
Arrays.asList(createdTask1.getExternalId(), createdTask2.getExternalId(), createdTask3.getExternalId()));
|
||||
|
||||
|
||||
//It's only allowed to set the CallbackState to REQUIRED if the TaskState doesn't equal COMPLETE
|
||||
//Therefore 1 task should not get updated
|
||||
BulkOperationResults<String, TaskanaException> bulkResult = taskService.setCallbackStateForTasks(externalIds,
|
||||
CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertTrue(bulkResult.containsErrors());
|
||||
List<String> failedTaskIds = bulkResult.getFailedIds();
|
||||
assertTrue(failedTaskIds.size() == 1 && failedTaskIds.contains(createdTask3.getExternalId()));
|
||||
|
||||
}
|
||||
|
||||
@WithAccessId(
|
||||
userName = "admin",
|
||||
groupNames = {"group_1"})
|
||||
@Test
|
||||
void testQueriesWithCallbackState()
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException, InvalidOwnerException, SQLException, IOException {
|
||||
TaskAlreadyExistException, InvalidArgumentException, TaskNotFoundException, InvalidStateException,
|
||||
InvalidOwnerException, SQLException, IOException {
|
||||
resetDb(false);
|
||||
TaskService taskService = taskanaEngine.getTaskService();
|
||||
|
||||
|
@ -180,7 +330,8 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
.list();
|
||||
long numberOfCompletedTasksAtStartOfTest = completedTasks.size();
|
||||
List<String> externalIds = completedTasks.stream().map(TaskSummary::getExternalId).collect(Collectors.toList());
|
||||
BulkOperationResults<String, TaskanaException> bulkResultCompleted = taskService.setCallbackStateForTasks(externalIds, CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
BulkOperationResults<String, TaskanaException> bulkResultCompleted = taskService.setCallbackStateForTasks(
|
||||
externalIds, CallbackState.CALLBACK_PROCESSING_REQUIRED);
|
||||
assertFalse(bulkResultCompleted.containsErrors());
|
||||
|
||||
// now complete some additional tasks
|
||||
|
@ -196,7 +347,8 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
assertTrue(tasksToBeActedUpon.size() == numberOfCompletedTasksAtStartOfTest);
|
||||
// now we set callback state to callback_processing_completed
|
||||
externalIds = tasksToBeActedUpon.stream().map(TaskSummary::getExternalId).collect(Collectors.toList());
|
||||
BulkOperationResults<String, TaskanaException> bulkResult = taskService.setCallbackStateForTasks(externalIds, CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
BulkOperationResults<String, TaskanaException> bulkResult = taskService.setCallbackStateForTasks(externalIds,
|
||||
CallbackState.CALLBACK_PROCESSING_COMPLETED);
|
||||
assertFalse(bulkResult.containsErrors());
|
||||
|
||||
long numOfTasksRemaining = taskService.createTaskQuery()
|
||||
|
@ -207,7 +359,9 @@ class CallbackStateAccTest extends AbstractAccTest {
|
|||
|
||||
}
|
||||
|
||||
private TaskImpl createTask(TaskService taskService, CallbackState callbackState) throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, TaskAlreadyExistException, InvalidArgumentException {
|
||||
private TaskImpl createTask(TaskService taskService, CallbackState callbackState)
|
||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||
TaskAlreadyExistException, InvalidArgumentException {
|
||||
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
|
||||
newTask.setClassificationKey("L12010");
|
||||
newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||
|
|
Loading…
Reference in New Issue