Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, String> 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<String, String> 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<String, String> 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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<String, String> 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<String, String> 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<String, String> body) {
camundaServiceApi.bpmnEscalation(authTokenGenerator.generate(), taskId, body);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -467,7 +467,7 @@ private void performAssignTaskAction(String taskId, String userId, boolean taskS
private void performClaimTaskAction(String taskId, Map<String, String> 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 =
Expand Down Expand Up @@ -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);
Expand All @@ -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 '{}'",
Expand All @@ -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 '{}'",
Expand All @@ -591,7 +591,7 @@ private void performCancelTaskAction(String taskId) {
Map<String, String> 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);
Expand Down