Background: I am calling a REST API to download a text file from a spring boot app. The problem is that the server takes time to generate the file and then make it ready for download.
So, I am using RetryTemplate to wait for 1 minute and attempt 60 times (60 attempts in 1 hour). When the download file is not ready, the server response will be empty, but when the download file is ready, the server will respond with the file URL.
Problem: Now the problem is, the way I've configured RetryTemplate, it'll keep calling the API even if there is an exception from the server.
Desired behavior: RetryTemplate should retry calling the API only when the server response is EMPTY and should NOT retry if the server response contains the download file URL or on a server-side exception.
RetryTemplate bean configuration:
@Bean
public RetryTemplate retryTemplate() {
final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(60);
final FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(60000L);
final RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.setBackOffPolicy(backOffPolicy);
return retryTemplate;
}
Service class method where it's used:
@Override
public DownloadResult getDownloadFile(final int id) {
// retry for 1 hour to download the file. Call to EBL will be made every minute for 60 minutes until the file is ready
final DownloadResult result = retryTemplate.execute(downloadFile -> dataAccess.getFile(id));
final InputStream inputStream = Try.of(result::getFileUrl)
.map(this::download)
.onFailure(throwable -> log.error("MalformedURLException: {}", result.getFileUrl()))
.get();
return result.toBuilder().downloadFileInputStream(inputStream).build();
}
The server response when download file is ready for download looks like this:
{
fileUrl:"www.download.com/fileId"
}
Empty server response if download file is not ready for download:
{
}
Thanks in advance for your help!
spring-retry
is entirely based on exceptions. You need to check the result within the lambda and throw an exception...