diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryServiceTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryServiceTest.java index 508eb95757..2d44c498e7 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryServiceTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryServiceTest.java @@ -13,10 +13,13 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; import uk.gov.hmcts.reform.wataskmanagementapi.clients.CamundaServiceApi; +import uk.gov.hmcts.reform.wataskmanagementapi.domain.camunda.AddLocalVariableRequest; +import uk.gov.hmcts.reform.wataskmanagementapi.domain.camunda.CamundaValue; import uk.gov.hmcts.reform.wataskmanagementapi.domain.camunda.CompleteTaskVariables; import java.nio.charset.StandardCharsets; import java.util.Collections; +import java.util.Map; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -88,6 +91,97 @@ void should_regenerate_token_when_retry() { verify(authTokenGenerator, times(3)).generate(); } + @Test + void should_retry_add_local_variables_when_feign_exception_occurred() { + String taskId = "task-789"; + AddLocalVariableRequest request = new AddLocalVariableRequest( + Map.of("taskState", CamundaValue.stringValue("completed")) + ); + + when(authTokenGenerator.generate()).thenReturn("S2S_TOKEN_1", "S2S_TOKEN_2", "S2S_TOKEN_3"); + + doThrow(feignException(500)) + .doThrow(feignException(500)) + .doNothing() + .when(camundaServiceApi).addLocalVariablesToTask(anyString(), eq(taskId), eq(request)); + + camundaRetryService.addLocalVariablesToTaskWithRetry(taskId, request); + + verify(camundaServiceApi, times(3)).addLocalVariablesToTask(anyString(), eq(taskId), eq(request)); + verify(authTokenGenerator, times(3)).generate(); + } + + @Test + void should_retry_claim_task_when_feign_exception_occurred() { + String taskId = "task-987"; + Map body = Map.of("userId", "user-123"); + + when(authTokenGenerator.generate()).thenReturn("S2S_TOKEN_1", "S2S_TOKEN_2", "S2S_TOKEN_3"); + + doThrow(feignException(500)) + .doThrow(feignException(500)) + .doNothing() + .when(camundaServiceApi).claimTask(anyString(), eq(taskId), eq(body)); + + camundaRetryService.claimTaskWithRetry(taskId, body); + + verify(camundaServiceApi, times(3)).claimTask(anyString(), eq(taskId), eq(body)); + verify(authTokenGenerator, times(3)).generate(); + } + + @Test + void should_retry_unclaim_task_when_feign_exception_occurred() { + String taskId = "task-654"; + + when(authTokenGenerator.generate()).thenReturn("S2S_TOKEN_1", "S2S_TOKEN_2", "S2S_TOKEN_3"); + + doThrow(feignException(500)) + .doThrow(feignException(500)) + .doNothing() + .when(camundaServiceApi).unclaimTask(anyString(), eq(taskId)); + + camundaRetryService.unclaimTaskWithRetry(taskId); + + verify(camundaServiceApi, times(3)).unclaimTask(anyString(), eq(taskId)); + verify(authTokenGenerator, times(3)).generate(); + } + + @Test + void should_retry_assign_task_when_feign_exception_occurred() { + String taskId = "task-321"; + Map body = Map.of("userId", "user-456"); + + when(authTokenGenerator.generate()).thenReturn("S2S_TOKEN_1", "S2S_TOKEN_2", "S2S_TOKEN_3"); + + doThrow(feignException(500)) + .doThrow(feignException(500)) + .doNothing() + .when(camundaServiceApi).assignTask(anyString(), eq(taskId), eq(body)); + + camundaRetryService.assignTaskWithRetry(taskId, body); + + verify(camundaServiceApi, times(3)).assignTask(anyString(), eq(taskId), eq(body)); + verify(authTokenGenerator, times(3)).generate(); + } + + @Test + void should_retry_bpmn_escalation_when_feign_exception_occurred() { + String taskId = "task-111"; + Map body = Map.of("escalationCode", "wa-esc-cancellation"); + + when(authTokenGenerator.generate()).thenReturn("S2S_TOKEN_1", "S2S_TOKEN_2", "S2S_TOKEN_3"); + + doThrow(feignException(500)) + .doThrow(feignException(500)) + .doNothing() + .when(camundaServiceApi).bpmnEscalation(anyString(), eq(taskId), eq(body)); + + camundaRetryService.bpmnEscalationWithRetry(taskId, body); + + verify(camundaServiceApi, times(3)).bpmnEscalation(anyString(), eq(taskId), eq(body)); + verify(authTokenGenerator, times(3)).generate(); + } + private static FeignException feignException(int status) { Request request = Request.create( Request.HttpMethod.POST, diff --git a/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryService.java b/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryService.java index a2b400cccb..8ef65fbbab 100644 --- a/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryService.java +++ b/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaRetryService.java @@ -6,8 +6,11 @@ import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; import uk.gov.hmcts.reform.wataskmanagementapi.clients.CamundaServiceApi; +import uk.gov.hmcts.reform.wataskmanagementapi.domain.camunda.AddLocalVariableRequest; import uk.gov.hmcts.reform.wataskmanagementapi.domain.camunda.CompleteTaskVariables; +import java.util.Map; + @Service public class CamundaRetryService { @@ -19,9 +22,33 @@ public CamundaRetryService(CamundaServiceApi camundaServiceApi, AuthTokenGenerat this.authTokenGenerator = authTokenGenerator; } - - @Retryable(retryFor = FeignException.class, backoff = @Backoff(delay = 100)) + @Retryable(retryFor = FeignException.class, maxAttempts = 3, backoff = @Backoff(delay = 100)) public void completeTaskWithRetry(String taskId) { camundaServiceApi.completeTask(authTokenGenerator.generate(), taskId, new CompleteTaskVariables()); } + + @Retryable(retryFor = FeignException.class, maxAttempts = 3, backoff = @Backoff(delay = 100)) + public void claimTaskWithRetry(String taskId, Map body) { + camundaServiceApi.claimTask(authTokenGenerator.generate(), taskId, body); + } + + @Retryable(retryFor = FeignException.class, maxAttempts = 3, backoff = @Backoff(delay = 100)) + public void unclaimTaskWithRetry(String taskId) { + camundaServiceApi.unclaimTask(authTokenGenerator.generate(), taskId); + } + + @Retryable(retryFor = FeignException.class, maxAttempts = 3, backoff = @Backoff(delay = 100)) + public void assignTaskWithRetry(String taskId, Map body) { + camundaServiceApi.assignTask(authTokenGenerator.generate(), taskId, body); + } + + @Retryable(retryFor = FeignException.class, maxAttempts = 3, backoff = @Backoff(delay = 100)) + public void addLocalVariablesToTaskWithRetry(String taskId, AddLocalVariableRequest addLocalVariableRequest) { + camundaServiceApi.addLocalVariablesToTask(authTokenGenerator.generate(), taskId, addLocalVariableRequest); + } + + @Retryable(retryFor = FeignException.class, maxAttempts = 3, backoff = @Backoff(delay = 100)) + public void bpmnEscalationWithRetry(String taskId, Map body) { + camundaServiceApi.bpmnEscalation(authTokenGenerator.generate(), taskId, body); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaService.java b/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaService.java index 4a62216ec0..152d21734e 100644 --- a/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaService.java +++ b/src/main/java/uk/gov/hmcts/reform/wataskmanagementapi/services/CamundaService.java @@ -451,7 +451,7 @@ private void performAssignTaskAction(String taskId, String userId, boolean taskS } try { - camundaServiceApi.assignTask(authTokenGenerator.generate(), taskId, body); + camundaRetryService.assignTaskWithRetry(taskId, body); log.info("Task id '{}' assigned to user id: '{}'", taskId, userId); } catch (FeignException ex) { throw new CamundaTaskAssignException(ex); @@ -467,7 +467,7 @@ private void performAssignTaskAction(String taskId, String userId, boolean taskS private void performClaimTaskAction(String taskId, Map body) { updateTaskStateTo(taskId, TaskState.ASSIGNED); try { - camundaServiceApi.claimTask(authTokenGenerator.generate(), taskId, body); + camundaRetryService.claimTaskWithRetry(taskId, body); log.info("Task id '{}' successfully claimed", taskId); } catch (FeignException ex) { CamundaExceptionMessage camundaException = @@ -523,7 +523,7 @@ private void performUnclaimTaskAction(String taskId, boolean taskHasUnassigned) updateTaskStateTo(taskId, TaskState.UNASSIGNED); } try { - camundaServiceApi.unclaimTask(authTokenGenerator.generate(), taskId); + camundaRetryService.unclaimTaskWithRetry(taskId); log.info("Task id '{}' unclaimed", taskId); } catch (FeignException ex) { log.error("There was a problem while claiming task id '{}'", taskId); @@ -546,7 +546,7 @@ private void updateCftTaskStateTo(String taskId, TaskState newState) { AddLocalVariableRequest camundaLocalVariables = new AddLocalVariableRequest(variable); try { - camundaServiceApi.addLocalVariablesToTask(authTokenGenerator.generate(), taskId, camundaLocalVariables); + camundaRetryService.addLocalVariablesToTaskWithRetry(taskId, camundaLocalVariables); } catch (FeignException ex) { log.error( "There was a problem updating task '{}', cft task state could not be updated to '{}'", @@ -570,7 +570,7 @@ private void updateTaskStateTo(String taskId, TaskState newState) { AddLocalVariableRequest camundaLocalVariables = new AddLocalVariableRequest(variable); try { - camundaServiceApi.addLocalVariablesToTask(authTokenGenerator.generate(), taskId, camundaLocalVariables); + camundaRetryService.addLocalVariablesToTaskWithRetry(taskId, camundaLocalVariables); } catch (FeignException ex) { log.error( "There was a problem updating task '{}', task state could not be updated to '{}'", @@ -591,7 +591,7 @@ private void performCancelTaskAction(String taskId) { Map body = new ConcurrentHashMap<>(); body.put("escalationCode", ESCALATION_CODE); try { - camundaServiceApi.bpmnEscalation(authTokenGenerator.generate(), taskId, body); + camundaRetryService.bpmnEscalationWithRetry(taskId, body); log.info("Task id '{}' cancelled", taskId); } catch (FeignException ex) { log.error("Task id '{}' could not be cancelled", taskId);