0
votes

i want to setup a new Batch Job.

This Job should receive a few Parameters from the Rest Interface (i am Using @EnableBatchProcessing for the automated JobScanning).

I only want the job to be performed once per rest call -> thats why i think a tasklet would be the weapon of choice. But i did not get @StepScope to work with a tasklet only Job (it seems as if there is no StepScope available without chunk but please correct me if i am wrong)...

My other idea was to create an ItemReader that reads the JobParameters and create a single Domain Object (from the Parameters) and then processes the Data and writes to a Dummy ItemWriter.

I tried to setup the ItemReader like this:

@Bean
@StepScope
public ItemReader<BatchPrinterJob> setupParameterItemReader(
        @Value("#{jobParameters}") Map<String, Object> jobParameters) {

    ItemReader<BatchPrinterJob> reader = new ItemReader<BatchPrinterJob>() {

        @Override
        public BatchPrinterJob read()
                throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

            BatchPrinterJob job = new BatchPrinterJob();
            LOG.info(jobParameters.toString());
            return job;
        }
    };
    return reader;
}

i tried to start the job with a POST Request like this: myhost:8080/jobs/thisjobsname?name=testname

But the only thing that gets logged is the run.id.

2

2 Answers

1
votes

i think a tasklet would be the weapon of choice. But i did not get @StepScope to work with a tasklet only Job (it seems as if there is no StepScope available without chunk but please correct me if i am wrong)...

You can use @StepScope on a tasklet, here is an example:

@Bean
@StepScope
public Tasklet tasklet(@Value("#{jobParameters['parameter']}") String parameter) {
    return (contribution, chunkContext) -> {
        // use job parameter here
        return RepeatStatus.FINISHED;
    };
}

Then use the tasklet to create the step:

@Bean
public Step step() {
    return this.stepBuilderFactory.get("step")
            .tasklet(tasklet(null))
            .build();
}
0
votes

Allright, i wrote my own Launcher for this Job based on your example:

@RestController
public class AutoPrintLaunchingController {

@Autowired
private JobLauncher jobLauncher;

@Autowired
private AutoPrint autoprint;

@RequestMapping(value = "/jobs/AutoPrint", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.ACCEPTED)
public void launch(@RequestParam("Drucker") String printer, @RequestParam("Fach") String fach,
        @RequestParam("Dokument") String doc, @RequestParam("DokumentParameter") String param) throws Exception {

    JobParametersBuilder jpb = new JobParametersBuilder();
    jpb.addString("Drucker", printer);
    jpb.addString("Fach", fach);
    jpb.addString("Dokument", doc);
    jpb.addString("DokumentParameter", param);
    jpb.addDate("dateInstant", Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));

    JobParameters jobParameters = jpb.toJobParameters();
    this.jobLauncher.run(autoprint.createAutoPrintJob(), jobParameters);
}

}

This is works as it required !