Spring RetryTemplate выполняет повторную попытку только для определенного типа ответа (не для исключения)

Справочная информация. Я вызываю REST API для загрузки текстового файла из весеннего загрузочного приложения. Проблема в том, что серверу требуется время, чтобы сгенерировать файл, а затем подготовить его для загрузки.

Итак, я использую RetryTemplate для ожидания 1 минуты и 60 попыток (60 попыток за 1 час). Когда файл загрузки не готов, ответ сервера будет пустым, но когда файл загрузки будет готов, сервер ответит URL-адресом файла.

Проблема: Теперь проблема в том, как я настроил RetryTemplate, он будет продолжать вызывать API, даже если на сервере есть исключение.

Желаемое поведение: RetryTemplate должен повторить попытку вызова API, только если ответ сервера ПУСТОЙ, и НЕ должен повторять попытку, если ответ сервера содержит URL-адрес загружаемого файла или исключение на стороне сервера.

Конфигурация компонента RetryTemplate:

          @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;
    } 

Метод класса обслуживания, где он используется:

      @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();
    }

Ответ сервера, когда загружаемый файл готов к загрузке, выглядит следующим образом:

      {
    fileUrl:"www.download.com/fileId"
}

Пустой ответ сервера, если загружаемый файл не готов к загрузке:

      {
}

Заранее спасибо за помощь!

1 ответ

spring-retryполностью основан на исключениях. Вам нужно проверить результат в лямбде и выдать исключение...

      retryTemplate.execute(downloadFile -> {
    DownloadResult result = dataAccess.getFile(id));
    if (resultIsEmpty(result)) {
         throw new SomeException();
    }
    return result;
}
Другие вопросы по тегам