Merge pull request #11507 from kwoyke/JAVA-8362
JAVA-8362: Split or move spring-batch module
This commit is contained in:
commit
0edbe4c8fb
|
@ -1,3 +1,5 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Spring Boot With Spring Batch](https://www.baeldung.com/spring-boot-spring-batch)
|
||||
- [How to Trigger and Stop a Scheduled Spring Batch Job](https://www.baeldung.com/spring-batch-start-stop-job)
|
||||
- More articles [[<-- prev]](/spring-batch)
|
||||
|
|
|
@ -22,10 +22,8 @@
|
|||
<artifactId>spring-boot-starter-batch</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>${hsqldb.version}</version>
|
||||
<scope>runtime</scope>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -44,11 +42,17 @@
|
|||
<version>${spring.batch.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<version>${awaitility.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<spring.batch.version>4.3.0</spring.batch.version>
|
||||
<hsqldb.version>2.5.1</hsqldb.version>
|
||||
<awaitility.version>3.1.1</awaitility.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -11,26 +11,20 @@ import org.springframework.batch.core.configuration.annotation.EnableBatchProces
|
|||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.file.FlatFileItemReader;
|
||||
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
|
||||
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.scheduling.support.ScheduledMethodRunnable;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Date;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
@ -58,13 +52,16 @@ public class SpringBatchScheduler {
|
|||
@Autowired
|
||||
private StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private JobLauncher jobLauncher;
|
||||
|
||||
@Scheduled(fixedRate = 2000)
|
||||
public void launchJob() throws Exception {
|
||||
Date date = new Date();
|
||||
logger.debug("scheduler starts at " + date);
|
||||
if (enabled.get()) {
|
||||
JobExecution jobExecution = jobLauncher().run(job(), new JobParametersBuilder().addDate("launchDate", date)
|
||||
.toJobParameters());
|
||||
JobExecution jobExecution = jobLauncher.run(job(), new JobParametersBuilder().addDate("launchDate", date)
|
||||
.toJobParameters());
|
||||
batchRunCounter.incrementAndGet();
|
||||
logger.debug("Batch job ends with status as " + jobExecution.getStatus());
|
||||
}
|
||||
|
@ -110,56 +107,33 @@ public class SpringBatchScheduler {
|
|||
|
||||
@Bean
|
||||
public Job job() {
|
||||
return jobBuilderFactory.get("job")
|
||||
.start(readBooks())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobLauncher jobLauncher() throws Exception {
|
||||
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
||||
jobLauncher.setJobRepository(jobRepository());
|
||||
jobLauncher.afterPropertiesSet();
|
||||
return jobLauncher;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobRepository jobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(new ResourcelessTransactionManager());
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName("org.sqlite.JDBC");
|
||||
dataSource.setUrl("jdbc:sqlite:repository.sqlite");
|
||||
return dataSource;
|
||||
return jobBuilderFactory
|
||||
.get("job")
|
||||
.start(readBooks())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Step readBooks() {
|
||||
return stepBuilderFactory.get("readBooks")
|
||||
.<Book, Book> chunk(2)
|
||||
.reader(reader())
|
||||
.writer(writer())
|
||||
.build();
|
||||
.<Book, Book> chunk(2)
|
||||
.reader(reader())
|
||||
.writer(writer())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FlatFileItemReader<Book> reader() {
|
||||
return new FlatFileItemReaderBuilder<Book>().name("bookItemReader")
|
||||
.resource(new ClassPathResource("books.csv"))
|
||||
.delimited()
|
||||
.names(new String[] { "id", "name" })
|
||||
.fieldSetMapper(new BeanWrapperFieldSetMapper<Book>() {
|
||||
{
|
||||
setTargetType(Book.class);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
.resource(new ClassPathResource("books.csv"))
|
||||
.delimited()
|
||||
.names(new String[] { "id", "name" })
|
||||
.fieldSetMapper(new BeanWrapperFieldSetMapper<Book>() {
|
||||
{
|
||||
setTargetType(Book.class);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.batchscheduler;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBatchSchedulerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBatchSchedulerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@ package com.baeldung.batchscheduler.model;
|
|||
public class Book {
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
|
||||
public Book() {}
|
||||
|
||||
public Book(int id, String name) {
|
||||
|
@ -27,7 +27,7 @@ public class Book {
|
|||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "Book [id=" + id + ", name=" + name + "]";
|
||||
}
|
|
@ -4,32 +4,40 @@ import com.baeldung.batchscheduler.SpringBatchScheduler;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static java.util.concurrent.TimeUnit.*;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = SpringBatchScheduler.class)
|
||||
@SpringBatchTest
|
||||
@SpringBootTest
|
||||
@DirtiesContext
|
||||
@PropertySource("classpath:application.properties")
|
||||
@RunWith(SpringRunner.class)
|
||||
public class SpringBatchSchedulerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void stopJobsWhenSchedulerDisabled() throws Exception {
|
||||
public void stopJobsWhenSchedulerDisabled() {
|
||||
SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class);
|
||||
await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get()));
|
||||
.get()));
|
||||
schedulerBean.stop();
|
||||
await().atLeast(3, SECONDS);
|
||||
|
||||
Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get());
|
||||
.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -37,24 +45,24 @@ public class SpringBatchSchedulerIntegrationTest {
|
|||
ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class);
|
||||
SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class);
|
||||
await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get()));
|
||||
.get()));
|
||||
bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler");
|
||||
await().atLeast(3, SECONDS);
|
||||
|
||||
Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get());
|
||||
.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception {
|
||||
SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class);
|
||||
await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get()));
|
||||
.get()));
|
||||
schedulerBean.cancelFutureSchedulerTasks();
|
||||
await().atLeast(3, SECONDS);
|
||||
|
||||
Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get());
|
||||
.get());
|
||||
}
|
||||
|
||||
|
|
@ -7,8 +7,8 @@ This module contains articles about Spring Batch
|
|||
- [Introduction to Spring Batch](https://www.baeldung.com/introduction-to-spring-batch)
|
||||
- [Spring Batch using Partitioner](https://www.baeldung.com/spring-batch-partitioner)
|
||||
- [Spring Batch – Tasklets vs Chunks](https://www.baeldung.com/spring-batch-tasklet-chunk)
|
||||
- [How to Trigger and Stop a Scheduled Spring Batch Job](https://www.baeldung.com/spring-batch-start-stop-job)
|
||||
- [Configuring Skip Logic in Spring Batch](https://www.baeldung.com/spring-batch-skip-logic)
|
||||
- [Testing a Spring Batch Job](https://www.baeldung.com/spring-batch-testing-job)
|
||||
- [Configuring Retry Logic in Spring Batch](https://www.baeldung.com/spring-batch-retry-logic)
|
||||
- [Conditional Flow in Spring Batch](https://www.baeldung.com/spring-batch-conditional-flow)
|
||||
- More articles [[next -->]](/spring-batch-2)
|
||||
|
|
|
@ -82,12 +82,6 @@
|
|||
<artifactId>hsqldb</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<version>${awaitility.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
@ -97,7 +91,6 @@
|
|||
<opencsv.version>4.1</opencsv.version>
|
||||
<jaxb.version>2.3.1</jaxb.version>
|
||||
<jackson-datatype.version>2.12.3</jackson-datatype.version>
|
||||
<awaitility.version>3.1.1</awaitility.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
Binary file not shown.
Loading…
Reference in New Issue