From 3d27f54e0f1f7d3751f8c78e7645b2f3603de9b4 Mon Sep 17 00:00:00 2001 From: Joerg Heffner <56156750+gitgoodjhe@users.noreply.github.com> Date: Fri, 7 May 2021 14:06:56 +0200 Subject: [PATCH] TSK-1635: Make forceCancelClaim of a task available in the REST-API --- .../src/docs/asciidoc/rest-api.adoc | 1 + .../taskana/common/rest/RestEndpoints.java | 1 + .../pro/taskana/task/rest/TaskController.java | 30 +++++++++++++++++++ .../task/rest/TaskControllerIntTest.java | 29 ++++++++++++++++++ .../task/rest/TaskControllerRestDocTest.java | 11 +++++++ 5 files changed, 72 insertions(+) diff --git a/rest/taskana-rest-spring/src/docs/asciidoc/rest-api.adoc b/rest/taskana-rest-spring/src/docs/asciidoc/rest-api.adoc index 8be8a5915..7aaa8f593 100644 --- a/rest/taskana-rest-spring/src/docs/asciidoc/rest-api.adoc +++ b/rest/taskana-rest-spring/src/docs/asciidoc/rest-api.adoc @@ -22,6 +22,7 @@ include::{snippets}/TaskControllerRestDocTest/updateTaskDocTest/auto-section.ado include::{snippets}/TaskControllerRestDocTest/claimTaskDocTest/auto-section.adoc[] include::{snippets}/TaskControllerRestDocTest/selectAndClaimTaskDocTest/auto-section.adoc[] include::{snippets}/TaskControllerRestDocTest/cancelClaimTaskDocTest/auto-section.adoc[] +include::{snippets}/TaskControllerRestDocTest/forceCancelClaimTaskDocTest/auto-section.adoc[] include::{snippets}/TaskControllerRestDocTest/completeTaskDocTest/auto-section.adoc[] include::{snippets}/TaskControllerRestDocTest/cancelTaskDocTest/auto-section.adoc[] include::{snippets}/TaskControllerRestDocTest/transferTaskDocTest/auto-section.adoc[] diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/RestEndpoints.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/RestEndpoints.java index 0af0eef5b..368b046f1 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/RestEndpoints.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/RestEndpoints.java @@ -42,6 +42,7 @@ public final class RestEndpoints { public static final String URL_TASKS = API_V1 + "tasks"; public static final String URL_TASKS_ID = API_V1 + "tasks/{taskId}"; public static final String URL_TASKS_ID_CLAIM = API_V1 + "tasks/{taskId}/claim"; + public static final String URL_TASKS_ID_CLAIM_FORCE = API_V1 + "tasks/{taskId}/claim/force"; public static final String URL_TASKS_ID_SELECT_AND_CLAIM = API_V1 + "tasks/select-and-claim"; public static final String URL_TASKS_ID_COMPLETE = API_V1 + "tasks/{taskId}/complete"; public static final String URL_TASKS_ID_CANCEL = API_V1 + "tasks/{taskId}/cancel"; diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java index c8497194c..1a1e7ff71 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/task/rest/TaskController.java @@ -275,6 +275,36 @@ public class TaskController { return result; } + /** + * This endpoint force cancels the claim of an existing Task. + * + * @param taskId the Id of the requested Task. + * @return the unclaimed Task. + * @throws TaskNotFoundException if the requested Task does not exist. + * @throws InvalidStateException if the Task is already in an end state. + * @throws InvalidOwnerException if the Task is claimed by a different user. + * @throws NotAuthorizedException if the current user has no read permission for the Workbasket + * the Task is in + * @title Force cancel a claimed Task + */ + @DeleteMapping(path = RestEndpoints.URL_TASKS_ID_CLAIM_FORCE) + @Transactional(rollbackFor = Exception.class) + public ResponseEntity forceCancelClaimTask(@PathVariable String taskId) + throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, + NotAuthorizedException { + + LOGGER.debug("Entry to forceCancelClaimTask(taskId= {}", taskId); + + Task updatedTask = taskService.forceCancelClaim(taskId); + + ResponseEntity result = + ResponseEntity.ok(taskRepresentationModelAssembler.toModel(updatedTask)); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Exit from forceCancelClaimTask(), returning {}", result); + } + return result; + } + /** * This endpoint completes a Task. * diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java index 37985c02a..123524b3c 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerIntTest.java @@ -730,6 +730,35 @@ class TaskControllerIntTest { assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY); } + @Test + void should_ForceCancelClaim_When_TaskIsClaimedByDifferentOwner() { + String url = + restHelper.toUrl(RestEndpoints.URL_TASKS_ID, "TKI:000000000000000000000000000000000027"); + HttpEntity auth = new HttpEntity<>(restHelper.getHeadersUser_1_1()); + + // retrieve task from Rest Api + ResponseEntity getTaskResponse = + TEMPLATE.exchange(url, HttpMethod.GET, auth, TASK_MODEL_TYPE); + assertThat(getTaskResponse.getBody()).isNotNull(); + TaskRepresentationModel claimedTaskRepresentationModel = getTaskResponse.getBody(); + assertThat(claimedTaskRepresentationModel.getState()).isEqualTo(TaskState.CLAIMED); + assertThat(claimedTaskRepresentationModel.getOwner()).isEqualTo("user-1-2"); + + // force cancel claim + String url2 = + restHelper.toUrl( + RestEndpoints.URL_TASKS_ID_CLAIM_FORCE, "TKI:000000000000000000000000000000000027"); + ResponseEntity cancelClaimResponse = + TEMPLATE.exchange(url2, HttpMethod.DELETE, auth, TASK_MODEL_TYPE); + + assertThat(cancelClaimResponse.getBody()).isNotNull(); + assertThat(cancelClaimResponse.getStatusCode().is2xxSuccessful()).isTrue(); + TaskRepresentationModel cancelClaimedtaskRepresentationModel = cancelClaimResponse.getBody(); + assertThat(cancelClaimedtaskRepresentationModel.getOwner()).isNull(); + assertThat(cancelClaimedtaskRepresentationModel.getClaimed()).isNull(); + assertThat(cancelClaimedtaskRepresentationModel.getState()).isEqualTo(TaskState.READY); + } + @Test void testCancelClaimOfClaimedTaskByAnotherUserShouldThrowException() { String url = diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerRestDocTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerRestDocTest.java index e277a9558..53fbfc8f6 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerRestDocTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/task/rest/TaskControllerRestDocTest.java @@ -68,6 +68,17 @@ class TaskControllerRestDocTest extends BaseRestDocTest { .andExpect(MockMvcResultMatchers.status().isOk()); } + @Test + void forceCancelClaimTaskDocTest() throws Exception { + mockMvc + .perform( + delete( + RestEndpoints.URL_TASKS_ID_CLAIM_FORCE, + "TKI:000000000000000000000000000000000035") + .headers(restHelper.getHeadersUser_1_2())) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + @Test void selectAndClaimTaskDocTest() throws Exception { mockMvc