I am trying to expose a Rest API and use it to receive a file name parameter and launch a Spring Batch job with it.
I want each request to launch the job and want my ItemReader to look for that file name.
I've read some other questions regarding how to launch a job via Rest API, and how the ItemReader can access jobParameters, but could not find a way to receive the parameters from the API request. Below is my code:
@Configuration
public class BatchConfig {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
private static final String WILL_BE_INJECTED = null;
@Bean
public Job processJob() {
return jobBuilderFactory.get("myJobName")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<Foo, Foo> chunk(1)
.reader(excelReader(WILL_BE_INJECTED))
.processor(new Processor()).faultTolerant().skipPolicy(skip())
.writer(new Writer())
.build();
}
@Bean
@StepScope
ItemReader<Foo> excelReader(@Value("#{jobParameters['fileName']}") String fileName) {
PoiItemReader<Foo> reader = new PoiItemReader<>();
reader.setLinesToSkip(3);
reader.setResource(new ClassPathResource("data/" + fileName));
reader.setRowMapper(excelRowMapper());
return reader;
}
private RowMapper<Foo> excelRowMapper() {
return new FooExcelRowMapper();
}
@Bean
public SkipPolicy skip() {
return new SkipPolicies();
}
}
And my Controller:
@RestController
public class BatchResource {
private final JobLauncher jobLauncher;
private final Job job;
public BatchResource(JobLauncher jobLauncher, Job job) {
this.jobLauncher = jobLauncher;
this.job = job;
}
@PostMapping
public void launchJob(@RequestParam(value = "file_name", required = true) final String fileName) throws Exception {
final JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
jobParametersBuilder.addString("fileName", fileName);
final JobParameters jobParameters = jobParametersBuilder.toJobParameters();
jobLauncher.run(job, jobParameters);
}
}
Unfortunately, it doesn't look like the ItemReader is understanding the fileName to be read. The job runs "successfully" but does not actually read my input file.
Edit: I started a new project with the same intention and noticed that as soon as I use the @StepScope annotation, it stops working and does not work again, even if I remove the @StepScope annotation. Now I'm trying to figure out how to overcome this
Resourceimplementation accordingly (ClassPathResourceorFileSystemResource). - Mahmoud Ben Hassine@StepScopeannotation, it stops working and does not work again, even if I remove the@StepScopeannotation. Now I'm trying to figure out how to overcome this. - elxapinhon