0

In the spring-boot application, I am calling a rest endpoint which results in 200 success status code and the response object is something like this:

{
   "id" : "some-uuid",
   "status" : "success"
}

Possbile values for the status object are creating, queued, running, failed, skipped, killed, success

I want to retry the rest-endpoint request when the status object is either queued or creating or running. For all other e.g. success, failed, skipped I want the retry to stop and get the result.

I am implementing it with spring-retry.

The api call:

private String makeApiCall(String jobId) {
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders httpHeaders = new HttpHeaders();
    List<MediaType> acceptType = new ArrayList<>();
    acceptType.add(MediaType.APPLICATION_JSON);
    httpHeaders.setAccept(acceptType);
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    ResponseEntity<String> response = restTemplate.exchange(apiEndpoint, HttpMethod.GET, requestEntity, String.class, params);
    ObjectMapper objectMapper = new ObjectMapper();
    JobStatus jobStatus = null;
    try {
      jobStatus = objectMapper.readValue(response.getBody(), JobStatus.class);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
    return jobStatus.getStatus();
}

The RetryTemp

 public ResponseEntity<String> jobStatusCheck(String jobId) throws JsonProcessingException {
    RetryTemplate retry = new RetryTemplate();
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(10000);
    retry.setRetryPolicy(new JobStatusRetryPolicy());
    retry.setBackOffPolicy(backOffPolicy);
    try {
      String result = (String) retry.execute(context -> {
        // No Idea on how to handle such conditions.
        String s = makeApiCall(jobId);
        if (s.equalsIgnoreCase("success")) {
          return s;
        }
        return null;
      });
      return ResponseEntity.ok().body(result);
    } catch (Exception e) {
      throw new RuntimeException("Error occurred during retry", e);
    }
}

The retry policy :

public class JobStatusRetryPolicy extends ExceptionClassifierRetryPolicy {
  public JobStatusRetryPolicy() {
    final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
    simpleRetryPolicy.setMaxAttempts(3);

    this.setExceptionClassifier( new Classifier<Throwable, RetryPolicy>()
    {
      @Override
      public RetryPolicy classify( Throwable classifiable )
      {
        // Retry only when FailureJobStatusException was thrown
        if ( classifiable instanceof FailureJobStatusException)
        {
          return simpleRetryPolicy;
        }

        // Do not retry for other exceptions
        return new NeverRetryPolicy();
      }
    } );
  }
}

The exception:

public class FailureJobStatusException extends Throwable {
}
Pranaya Behera
  • 545
  • 1
  • 9
  • 24

1 Answers1

0

Please check this https://shankulk.com/auto-retries-in-rest-api-clients-using-spring-retry-c78cacb0cc29

Here you can specify your customized statuses

Your main focus should be on below function and implement it accordingly (Here it is based on http status - But you can make it based on you rown status which is part of response JSON)

private RetryPolicy getRetryPolicyForStatus(HttpStatus httpStatus) {
    switch (httpStatus) {
        case BAD_GATEWAY:
        case SERVICE_UNAVAILABLE:
        case INTERNAL_SERVER_ERROR:
        case GATEWAY_TIMEOUT:
            return simpleRetryPolicy;
        default:
            return neverRetryPolicy;
    }

Hope you find this helpful .

Codified
  • 135
  • 9
  • I went through that tutorial, however I am not sure how do I handle the exception part. In the ```configureStatusCodeBasedRetryPolicy()``` method of ```RetryConfig``` class, it is for the HttpStatus code, what would be a exception for my case ? – Pranaya Behera May 07 '23 at 09:14
  • So the class ExceptionClassifierRetryPolicy which is being extended in the JobStatusRetryPolicy is not from the library/framework it user a defined class (Defined by you or someone from your co-workers)? – Codified May 08 '23 at 14:06