I followed the tutorial https://spring.io/guides/gs/batch-processing/ which basically reads a spreadsheet and insert the data in database once the application is started. I want to execute the reading process every time a rest service is evoked, so I added a controller in this application. To call the job I followed the suggestion in How to trigger a job using a rest web service? and now it rises my issue: whenever I called the rest service it runs only the afterJob method. I read how to select which spring batch job to run based on application argument - spring boot java config (which has certain similiarity with my issue) and the excellent blog post pointed in it but I am still stuck. I want to call "public ItemReader reader()" after the rest service and I expect the same flow to be followed as it is done when the application started via main(). I mean, the same flow as when it is deployed by springboot. I guess my confusion lies in @EnableBatchProcessing or JobExecutionListenerSupport but I am really stuck on it. Below are the most important snippet.
Controller
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
@RequestMapping("/runit")
public void handle() throws Exception{
JobParameters jobParameters =
new JobParametersBuilder()
.addLong("time",System.currentTimeMillis()).toJobParameters();
jobLauncher.run(job, jobParameters);
}
Listener
@Component
public class JobCompletionNotificationListener extends
JobExecutionListenerSupport {
@Override
public void afterJob(JobExecution jobExecution) {
if(jobExecution.getStatus() == BatchStatus.COMPLETED) {
Batch Configuration
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
// tag::readerwriterprocessor[]
@Bean
public ItemReader<Person> reader() {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "firstName", "lastName" });
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});
return reader;
}
@Bean
public ItemProcessor<Person, Person> processor() {
return new PersonItemProcessor();
}
@Bean
public ItemWriter<Person> writer(DataSource dataSource) {
JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());
writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
writer.setDataSource(dataSource);
return writer;
}
@Bean
public Job importUserJob(JobBuilderFactory jobs, Step s1, JobExecutionListener listener) {
return jobs.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(s1)
.end()
.build();
}
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<Person> reader,
ItemWriter<Person> writer, ItemProcessor<Person, Person> processor) {
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
application.properties
application.properties
# SPRING BATCH (BatchDatabaseInitializer)
spring.batch.job.enabled=false
spring.batch.initializer.enabled=false