2

I have this tasklet which uploads a file to Amazon S3. Now, I want to retry the tasklet execution whenever an AmazonClientException is thrown. I figured using @Retryable annotation will do the job.

Tasklet:

@Component
@StepScope
@Retryable(value=AmazonClientException.class, stateful=true, backoff=@Backoff(2000))
public class S3UploadTasklet extends ArgsSupport implements Tasklet {

    @Autowired
    private S3Client s3Client;

    @Autowired
    private S3Properties s3Properties;

    private static final Logger LOGGER = LoggerFactory.getLogger(S3UploadTasklet.class);

    private static final String FILE_EXTENSION = ".gpg";

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        try {
            String localFilename = getTempOutputFilename() + FILE_EXTENSION;
            String s3Filename = s3Properties.getReportPath() + getS3OutputFilename() + FILE_EXTENSION;
            File f = new File(localFilename);
            if(f.exists()) {
                LOGGER.info("Uploading " + localFilename + " to s3...");
                s3Client.upload(localFilename, s3Filename, s3Properties.getBucketName());
                LOGGER.info("Uploading done!");
            } else {
                throw new RuntimeException("Encrypted file not found! Encryption process might have failed.");
            }
        } catch(AmazonClientException e) {
            LOGGER.error("Problems uploading to S3. " + e.getMessage(), e);
            throw e;
        } catch(RuntimeException e) {
            LOGGER.error("Runtime error occured. " + e.getMessage(), e);
            throw e;
        }

        return RepeatStatus.FINISHED;
    }
}

Job configuration:

@Configuration
@EnableBatchProcessing
@EnableRetry
public class BatchConfiguration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private Step generateReport;

    @Autowired
    private Step encrypt;

    @Autowired
    private Step upload;

    @Autowired
    private Step cleanUp;

    @Bean
    @Transactional(value="appTransactionManager", isolation=Isolation.READ_COMMITTED)
    public Job generateReconJob() {
        return jobBuilderFactory.get("reconJob")
                .incrementer(new RunIdIncrementer())
                .start(generateReport)
                    .on("COMPLETED").to(encrypt)
                .from(generateReport)
                    .on("NOOP").end()
                .from(generateReport)
                    .on("FAILED").to(cleanUp)
                .from(encrypt)
                    .on("COMPLETED").to(upload)
                .from(encrypt)
                    .on("FAILED").to(cleanUp)
                .from(upload)
                    .on("*").to(cleanUp)
                .from(cleanUp)
                    .on("*").end()
                .end()
                .build();
    }
}

However, it doesn't do what it is supposed to do. The batch job still doesn't retry the tasklet when the exception is thrown.

Any thoughts?

Here's the config also

@Configuration
public class ReportConfiguration {
   ...

   @Autowired
   private S3UploadTasklet s3UploadTasklet;

   ...

    @Bean
    public Step upload() {
        return stepBuilderFactory.get("upload")
                .tasklet(s3UploadTasklet)
                .build();
    }
}
makalshrek
  • 853
  • 3
  • 14
  • 29

1 Answers1

0

The @Retryable(value=AmazonClientException.class, stateful=true, backoff=@Backoff(2000)) annotation should be on the method you want to retry, not the class.

ufdeveloper
  • 387
  • 6
  • 19
  • [Retryable](http://docs.spring.io/spring-retry/docs/1.1.2.RELEASE/apidocs/org/springframework/retry/annotation/Retryable.html) annotation have `@Target(value={METHOD,TYPE})`, so it can be on a method/class/interface. Annotating a class with `@Retryable` is same as annotating all methods in the class. So if you have a common retry configuration for all methods in your class, annotate the class/interface. And method here applies to public methods, as `Retryable` is implemented using Spring AOP. – Chacko Mar 14 '17 at 11:06