2016-04-03 4 views
1

Ich habe dieses Tasklet, das eine Datei auf Amazon S3 hochlädt. Nun möchte ich die Tasklet-Ausführung wiederholen, wenn ein AmazonClientException geworfen wird. Ich dachte, mit @Retryable Annotation wird die Arbeit machen.Spring Batch: Wiederholen eines Tasklet mit @Retryable und @EnableRetry Annotation

Tasklet:

@Component 
@StepScope 
@Retryable(value=AmazonClientException.class, stateful=true, [email protected](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-Konfiguration:

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

Allerdings ist es nicht tun, was es tun soll. Der Batch-Job versucht das Tasklet immer noch nicht, wenn die Ausnahme ausgelöst wird.

Irgendwelche Gedanken?

Hier ist die Config

@Configuration 
public class ReportConfiguration { 
    ... 

    @Autowired 
    private S3UploadTasklet s3UploadTasklet; 

    ... 

    @Bean 
    public Step upload() { 
     return stepBuilderFactory.get("upload") 
       .tasklet(s3UploadTasklet) 
       .build(); 
    } 
} 
+0

Wenn Sie sagen, dass es nicht erneut versucht, was passiert, wenn die Ausnahme ausgelöst wird? –

+0

@MichaelPralow Ich sehe, dass die Ausnahme geworfen wird, aber dann geht es einfach weiter zum nächsten Schritt. – makalshrek

+0

Ich glaube nicht, dass die Wiederholungsanmerkung auf dem Tasklet selbst liegen sollte. Eher würde ich den Aufruf nach Amazon in seine eigene Methode setzen und dort retryable verwenden. – IcedDante

Antwort

0

auch die @Retryable (Wert = AmazonClientException.class, Stateful = true, = Backoff @ Backoff (2000)) Anmerkung auf die Methode, die Sie wiederholen möchten sein sollte, nicht die Klasse.

+0

[Retryable] (http://docs.spring.io/spring-retry/docs/1.1.2.RELEASE/apidocs/org/springframework/retry/annotation/Retryable.html) Annotation haben '@Target (Wert = {METHOD, TYPE}) ', so kann es auf einer Methode/Klasse/Schnittstelle sein. Das Annotieren einer Klasse mit @ Retryable ist dasselbe wie das Kommentieren aller Methoden in der Klasse. Wenn Sie eine gemeinsame Wiederholungskonfiguration für alle Methoden in Ihrer Klasse haben, notieren Sie die Klasse/Schnittstelle. Die Methode gilt auch für öffentliche Methoden, da "Retryable" mit Spring AOP implementiert wird. –

Verwandte Themen