JAVA-18609 GitHub Issue: Spring Batch - JobBuilderFactory and StepBui… (#13618)
* JAVA-18609 GitHub Issue: Spring Batch - JobBuilderFactory and StepBuilderFactory are deprecated --------- Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
parent
d0d58509e2
commit
d1249befd1
5
pom.xml
5
pom.xml
|
@ -759,6 +759,7 @@
|
|||
|
||||
<module>javafx</module>
|
||||
<module>spring-batch</module>
|
||||
<module>spring-batch-2</module>
|
||||
<module>spring-boot-rest</module>
|
||||
<module>spring-drools</module>
|
||||
<module>spring-exceptions</module>
|
||||
|
@ -781,7 +782,6 @@
|
|||
<module>server-modules</module>
|
||||
<module>apache-cxf-modules</module>
|
||||
|
||||
|
||||
<module>spring-aop</module>
|
||||
<module>jmeter</module>
|
||||
<module>spring-aop-2</module>
|
||||
|
@ -928,7 +928,6 @@
|
|||
<module>spring-5-webflux</module>
|
||||
<module>spring-5-webflux-2</module>
|
||||
<module>spring-activiti</module>
|
||||
<module>spring-batch-2</module>
|
||||
<module>spring-core-2</module>
|
||||
<module>spring-core-3</module>
|
||||
<module>spring-core-5</module>
|
||||
|
@ -1012,6 +1011,7 @@
|
|||
|
||||
<module>javafx</module>
|
||||
<module>spring-batch</module>
|
||||
<module>spring-batch-2</module>
|
||||
<module>spring-boot-rest</module>
|
||||
<module>spring-drools</module>
|
||||
<module>spring-exceptions</module>
|
||||
|
@ -1180,7 +1180,6 @@
|
|||
<module>spring-5-webflux</module>
|
||||
<module>spring-5-webflux-2</module>
|
||||
<module>spring-activiti</module>
|
||||
<module>spring-batch-2</module>
|
||||
<module>spring-core-2</module>
|
||||
<module>spring-core-3</module>
|
||||
<module>spring-core-5</module>
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
<relativePath>../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -51,8 +51,9 @@
|
|||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<spring.batch.version>4.3.0</spring.batch.version>
|
||||
<awaitility.version>3.1.1</awaitility.version>
|
||||
<spring.batch.version>5.0.0</spring.batch.version>
|
||||
<awaitility.version>4.2.0</awaitility.version>
|
||||
<start-class>com.baeldung.batch.SpringBootBatchProcessingApplication</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -4,31 +4,24 @@ import javax.sql.DataSource;
|
|||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
|
||||
import org.springframework.batch.item.database.JdbcBatchItemWriter;
|
||||
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
|
||||
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.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class BatchConfiguration {
|
||||
|
||||
@Autowired
|
||||
public JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
public StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Value("${file.input}")
|
||||
private String fileInput;
|
||||
|
@ -59,8 +52,8 @@ public class BatchConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
|
||||
return jobBuilderFactory.get("importUserJob")
|
||||
public Job importUserJob(JobRepository jobRepository, JobCompletionNotificationListener listener, Step step1) {
|
||||
return new JobBuilder("importUserJob", jobRepository)
|
||||
.incrementer(new RunIdIncrementer())
|
||||
.listener(listener)
|
||||
.flow(step1)
|
||||
|
@ -69,9 +62,9 @@ public class BatchConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public Step step1(JdbcBatchItemWriter<Coffee> writer) {
|
||||
return stepBuilderFactory.get("step1")
|
||||
.<Coffee, Coffee> chunk(10)
|
||||
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, JdbcBatchItemWriter<Coffee> writer) {
|
||||
return new StepBuilder("step1", jobRepository)
|
||||
.<Coffee, Coffee> chunk(10, transactionManager)
|
||||
.reader(reader())
|
||||
.processor(processor())
|
||||
.writer(writer)
|
||||
|
|
|
@ -10,7 +10,7 @@ public class CoffeeItemProcessor implements ItemProcessor<Coffee, Coffee> {
|
|||
private static final Logger LOGGER = LoggerFactory.getLogger(CoffeeItemProcessor.class);
|
||||
|
||||
@Override
|
||||
public Coffee process(final Coffee coffee) throws Exception {
|
||||
public Coffee process(final Coffee coffee) {
|
||||
String brand = coffee.getBrand().toUpperCase();
|
||||
String origin = coffee.getOrigin().toUpperCase();
|
||||
String chracteristics = coffee.getCharacteristics().toUpperCase();
|
||||
|
|
|
@ -4,13 +4,13 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
|
||||
import org.springframework.batch.core.JobExecutionListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {
|
||||
public class JobCompletionNotificationListener implements JobExecutionListener {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JobCompletionNotificationListener.class);
|
||||
|
||||
|
|
|
@ -7,15 +7,16 @@ import org.springframework.batch.core.Job;
|
|||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
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.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
@ -24,17 +25,16 @@ 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 org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
@EnableScheduling
|
||||
public class SpringBatchScheduler {
|
||||
|
||||
|
@ -46,21 +46,21 @@ public class SpringBatchScheduler {
|
|||
|
||||
private final Map<Object, ScheduledFuture<?>> scheduledTasks = new IdentityHashMap<>();
|
||||
|
||||
@Autowired
|
||||
private JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private JobLauncher jobLauncher;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
@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)
|
||||
JobExecution jobExecution = jobLauncher.run(job(jobRepository, transactionManager), new JobParametersBuilder().addDate("launchDate", date)
|
||||
.toJobParameters());
|
||||
batchRunCounter.incrementAndGet();
|
||||
logger.debug("Batch job ends with status as " + jobExecution.getStatus());
|
||||
|
@ -106,17 +106,16 @@ public class SpringBatchScheduler {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public Job job() {
|
||||
return jobBuilderFactory
|
||||
.get("job")
|
||||
.start(readBooks())
|
||||
public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new JobBuilder("job", jobRepository)
|
||||
.start(readBooks(jobRepository, transactionManager))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Step readBooks() {
|
||||
return stepBuilderFactory.get("readBooks")
|
||||
.<Book, Book> chunk(2)
|
||||
protected Step readBooks(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("readBooks", jobRepository)
|
||||
.<Book, Book> chunk(2, transactionManager)
|
||||
.reader(reader())
|
||||
.writer(writer())
|
||||
.build();
|
||||
|
@ -128,7 +127,7 @@ public class SpringBatchScheduler {
|
|||
.resource(new ClassPathResource("books.csv"))
|
||||
.delimited()
|
||||
.names(new String[] { "id", "name" })
|
||||
.fieldSetMapper(new BeanWrapperFieldSetMapper<Book>() {
|
||||
.fieldSetMapper(new BeanWrapperFieldSetMapper<>() {
|
||||
{
|
||||
setTargetType(Book.class);
|
||||
}
|
||||
|
@ -138,15 +137,10 @@ public class SpringBatchScheduler {
|
|||
|
||||
@Bean
|
||||
public ItemWriter<Book> writer() {
|
||||
return new ItemWriter<Book>() {
|
||||
|
||||
@Override
|
||||
public void write(List<? extends Book> items) throws Exception {
|
||||
logger.debug("writer..." + items.size());
|
||||
for (Book item : items) {
|
||||
logger.debug(item.toString());
|
||||
}
|
||||
|
||||
return items -> {
|
||||
logger.debug("writer..." + items.size());
|
||||
for (Book item : items) {
|
||||
logger.debug(item.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package com.baeldung.batch;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
|
@ -13,16 +12,17 @@ import org.springframework.batch.test.JobLauncherTestUtils;
|
|||
import org.springframework.batch.test.JobRepositoryTestUtils;
|
||||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
@SpringBatchTest
|
||||
@SpringBootTest
|
||||
@DirtiesContext
|
||||
@SpringJUnitConfig(BatchConfiguration.class)
|
||||
@PropertySource("classpath:application.properties")
|
||||
@RunWith(SpringRunner.class)
|
||||
@EnableAutoConfiguration
|
||||
public class SpringBootBatchIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
|
@ -31,7 +31,10 @@ public class SpringBootBatchIntegrationTest {
|
|||
@Autowired
|
||||
private JobRepositoryTestUtils jobRepositoryTestUtils;
|
||||
|
||||
@After
|
||||
@MockBean
|
||||
private JobCompletionNotificationListener jobCompletionNotificationListener;
|
||||
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
jobRepositoryTestUtils.removeJobExecutions();
|
||||
}
|
||||
|
@ -42,8 +45,8 @@ public class SpringBootBatchIntegrationTest {
|
|||
JobInstance jobInstance = jobExecution.getJobInstance();
|
||||
ExitStatus jobExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
assertThat(jobInstance.getJobName(), is("importUserJob"));
|
||||
assertThat(jobExitStatus.getExitCode(), is("COMPLETED"));
|
||||
assertEquals("importUserJob", jobInstance.getJobName());
|
||||
assertEquals("COMPLETED", jobExitStatus.getExitCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,28 +1,20 @@
|
|||
package com.baeldung.batchscheduler;
|
||||
|
||||
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.junit.jupiter.api.Test;
|
||||
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.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@SpringBatchTest
|
||||
@SpringBootTest
|
||||
@DirtiesContext
|
||||
@PropertySource("classpath:application.properties")
|
||||
@RunWith(SpringRunner.class)
|
||||
public class SpringBatchSchedulerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
|
@ -31,37 +23,36 @@ public class SpringBatchSchedulerIntegrationTest {
|
|||
@Test
|
||||
public void stopJobsWhenSchedulerDisabled() {
|
||||
SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class);
|
||||
await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
await().untilAsserted(() -> assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get()));
|
||||
schedulerBean.stop();
|
||||
await().atLeast(3, SECONDS);
|
||||
|
||||
Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get());
|
||||
assertEquals(2, schedulerBean.getBatchRunCounter().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception {
|
||||
public void stopJobSchedulerWhenSchedulerDestroyed() {
|
||||
ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class);
|
||||
SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class);
|
||||
await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
await().untilAsserted(() -> assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get()));
|
||||
bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler");
|
||||
await().atLeast(3, SECONDS);
|
||||
|
||||
Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception {
|
||||
public void stopJobSchedulerWhenFutureTasksCancelled() {
|
||||
SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class);
|
||||
await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
await().untilAsserted(() -> assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get()));
|
||||
schedulerBean.cancelFutureSchedulerTasks();
|
||||
await().atLeast(3, SECONDS);
|
||||
|
||||
Assert.assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
assertEquals(2, schedulerBean.getBatchRunCounter()
|
||||
.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
<relativePath>../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -22,25 +22,15 @@
|
|||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson-datatype.version}</version>
|
||||
</dependency>
|
||||
<!-- JAXB APIs & runtime no longer provided in JDK 11 -->
|
||||
<!-- see http://openjdk.java.net/jeps/320 -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>${jaxb.version}</version>
|
||||
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>${jaxb.version}</version>
|
||||
|
||||
</dependency>
|
||||
<!-- SQLite database driver -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>${sqlite.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
@ -53,20 +43,9 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.batch</groupId>
|
||||
<artifactId>spring-batch-core</artifactId>
|
||||
<version>${spring.batch.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.batch</groupId>
|
||||
<artifactId>spring-batch-test</artifactId>
|
||||
<version>${spring.batch.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
|
@ -78,19 +57,29 @@
|
|||
<artifactId>spring-boot-starter-batch</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${http-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jettison</groupId>
|
||||
<artifactId>jettison</artifactId>
|
||||
<version>${jettison.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<spring.version>5.3.0</spring.version>
|
||||
<spring.batch.version>4.3.0</spring.batch.version>
|
||||
<sqlite.version>3.15.1</sqlite.version>
|
||||
<opencsv.version>4.1</opencsv.version>
|
||||
<jaxb.version>2.3.1</jaxb.version>
|
||||
<jackson-datatype.version>2.12.3</jackson-datatype.version>
|
||||
<spring.version>6.0.6</spring.version>
|
||||
<opencsv.version>5.7.1</opencsv.version>
|
||||
<jaxb.version>4.0.2</jaxb.version>
|
||||
<jackson-datatype.version>2.14.2</jackson-datatype.version>
|
||||
<http-client.version>4.5.14</http-client.version>
|
||||
<jettison.version>1.5.3</jettison.version>
|
||||
<start-class>com.baeldung.batchtesting.SpringBatchApplication</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
Binary file not shown.
|
@ -18,20 +18,19 @@ public class App {
|
|||
public static void main(final String[] args) {
|
||||
// Spring Java config
|
||||
final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(SpringConfig.class);
|
||||
context.getEnvironment().addActiveProfile("spring");
|
||||
context.register(SpringBatchConfig.class);
|
||||
context.register(SpringBatchRetryConfig.class);
|
||||
|
||||
context.refresh();
|
||||
|
||||
// Spring xml config
|
||||
// ApplicationContext context = new ClassPathXmlApplicationContext("spring-batch.xml");
|
||||
// ApplicationContext context = new ClassPathXmlApplicationContext("spring-batch-intro.xml");
|
||||
|
||||
runJob(context, "firstBatchJob");
|
||||
runJob(context, "skippingBatchJob");
|
||||
runJob(context, "skipPolicyBatchJob");
|
||||
runJob(context, "retryBatchJob");
|
||||
|
||||
}
|
||||
|
||||
private static void runJob(AnnotationConfigApplicationContext context, String batchJobName) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.baeldung.batch;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.baeldung.batch.model.Transaction;
|
||||
import com.baeldung.batch.service.CustomItemProcessor;
|
||||
import com.baeldung.batch.service.CustomSkipPolicy;
|
||||
|
@ -7,10 +9,15 @@ import com.baeldung.batch.service.MissingUsernameException;
|
|||
import com.baeldung.batch.service.NegativeAmountException;
|
||||
import com.baeldung.batch.service.RecordFieldSetMapper;
|
||||
import com.baeldung.batch.service.SkippingItemProcessor;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
@ -19,24 +26,23 @@ import org.springframework.batch.item.file.FlatFileItemReader;
|
|||
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
|
||||
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
|
||||
import org.springframework.batch.item.xml.StaxEventItemWriter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.WritableResource;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
@Configuration
|
||||
@Profile("spring")
|
||||
public class SpringBatchConfig {
|
||||
@Autowired
|
||||
private JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Value("input/record.csv")
|
||||
private Resource inputCsv;
|
||||
|
@ -45,9 +51,9 @@ public class SpringBatchConfig {
|
|||
private Resource invalidInputCsv;
|
||||
|
||||
@Value("file:xml/output.xml")
|
||||
private Resource outputXml;
|
||||
private WritableResource outputXml;
|
||||
|
||||
public ItemReader<Transaction> itemReader(Resource inputData) throws UnexpectedInputException, ParseException {
|
||||
public ItemReader<Transaction> itemReader(Resource inputData) throws UnexpectedInputException {
|
||||
FlatFileItemReader<Transaction> reader = new FlatFileItemReader<>();
|
||||
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
|
||||
String[] tokens = {"username", "userid", "transactiondate", "amount"};
|
||||
|
@ -88,10 +94,10 @@ public class SpringBatchConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
protected Step step1(@Qualifier("itemProcessor") ItemProcessor<Transaction, Transaction> processor, ItemWriter<Transaction> writer) throws ParseException {
|
||||
return stepBuilderFactory
|
||||
.get("step1")
|
||||
.<Transaction, Transaction> chunk(10)
|
||||
protected Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("itemProcessor") ItemProcessor<Transaction,
|
||||
Transaction> processor, ItemWriter<Transaction> writer) {
|
||||
return new StepBuilder("step1", jobRepository)
|
||||
.<Transaction, Transaction> chunk(10, transactionManager)
|
||||
.reader(itemReader(inputCsv))
|
||||
.processor(processor)
|
||||
.writer(writer)
|
||||
|
@ -99,16 +105,15 @@ public class SpringBatchConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "firstBatchJob")
|
||||
public Job job(@Qualifier("step1") Step step1) {
|
||||
return jobBuilderFactory.get("firstBatchJob").start(step1).build();
|
||||
public Job job(JobRepository jobRepository, @Qualifier("step1") Step step1) {
|
||||
return new JobBuilder("firstBatchJob", jobRepository).preventRestart().start(step1).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step skippingStep(@Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> writer) throws ParseException {
|
||||
return stepBuilderFactory
|
||||
.get("skippingStep")
|
||||
.<Transaction, Transaction>chunk(10)
|
||||
public Step skippingStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor<Transaction,
|
||||
Transaction> processor, ItemWriter<Transaction> writer) {
|
||||
return new StepBuilder("skippingStep", jobRepository)
|
||||
.<Transaction, Transaction>chunk(10, transactionManager)
|
||||
.reader(itemReader(invalidInputCsv))
|
||||
.processor(processor)
|
||||
.writer(writer)
|
||||
|
@ -120,19 +125,18 @@ public class SpringBatchConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "skippingBatchJob")
|
||||
public Job skippingJob(@Qualifier("skippingStep") Step skippingStep) {
|
||||
return jobBuilderFactory
|
||||
.get("skippingBatchJob")
|
||||
public Job skippingJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingStep") Step skippingStep) {
|
||||
return new JobBuilder("skippingBatchJob", jobRepository)
|
||||
.start(skippingStep)
|
||||
.preventRestart()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step skipPolicyStep(@Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> writer) throws ParseException {
|
||||
return stepBuilderFactory
|
||||
.get("skipPolicyStep")
|
||||
.<Transaction, Transaction>chunk(10)
|
||||
public Step skipPolicyStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> writer) {
|
||||
return new StepBuilder("skipPolicyStep", jobRepository)
|
||||
.<Transaction, Transaction>chunk(10, transactionManager)
|
||||
.reader(itemReader(invalidInputCsv))
|
||||
.processor(processor)
|
||||
.writer(writer)
|
||||
|
@ -142,11 +146,44 @@ public class SpringBatchConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "skipPolicyBatchJob")
|
||||
public Job skipPolicyBatchJob(@Qualifier("skipPolicyStep") Step skipPolicyStep) {
|
||||
return jobBuilderFactory
|
||||
.get("skipPolicyBatchJob")
|
||||
public Job skipPolicyBatchJob(JobRepository jobRepository, @Qualifier("skipPolicyStep") Step skipPolicyStep) {
|
||||
return new JobBuilder("skipPolicyBatchJob", jobRepository)
|
||||
.start(skipPolicyStep)
|
||||
.preventRestart()
|
||||
.build();
|
||||
}
|
||||
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
return builder.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql")
|
||||
.addScript("classpath:org/springframework/batch/core/schema-h2.sql")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(name = "transactionManager")
|
||||
public PlatformTransactionManager getTransactionManager() {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
@Bean(name = "jobRepository")
|
||||
public JobRepository getJobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(getTransactionManager());
|
||||
// JobRepositoryFactoryBean's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
factory.afterPropertiesSet();
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean(name = "jobLauncher")
|
||||
public JobLauncher getJobLauncher() throws Exception {
|
||||
TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
|
||||
// TaskExecutorJobLauncher's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
jobLauncher.setJobRepository(getJobRepository());
|
||||
jobLauncher.afterPropertiesSet();
|
||||
return jobLauncher;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package com.baeldung.batch;
|
||||
|
||||
import com.baeldung.batch.model.Transaction;
|
||||
import com.baeldung.batch.service.RecordFieldSetMapper;
|
||||
import com.baeldung.batch.service.RetryItemProcessor;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import com.baeldung.batch.model.Transaction;
|
||||
import com.baeldung.batch.service.RecordFieldSetMapper;
|
||||
import com.baeldung.batch.service.RetryItemProcessor;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
@ -19,38 +20,30 @@ import org.springframework.batch.item.file.FlatFileItemReader;
|
|||
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
|
||||
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
|
||||
import org.springframework.batch.item.xml.StaxEventItemWriter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.WritableResource;
|
||||
import org.springframework.dao.DeadlockLoserDataAccessException;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
|
||||
import java.text.ParseException;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class SpringBatchRetryConfig {
|
||||
|
||||
|
||||
private static final String[] tokens = { "username", "userid", "transactiondate", "amount" };
|
||||
private static final int TWO_SECONDS = 2000;
|
||||
|
||||
@Autowired
|
||||
private JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Value("input/recordRetry.csv")
|
||||
private Resource inputCsv;
|
||||
|
||||
@Value("file:xml/retryOutput.xml")
|
||||
private Resource outputXml;
|
||||
private WritableResource outputXml;
|
||||
|
||||
public ItemReader<Transaction> itemReader(Resource inputData) throws ParseException {
|
||||
public ItemReader<Transaction> itemReader(Resource inputData) {
|
||||
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
|
||||
tokenizer.setNames(tokens);
|
||||
DefaultLineMapper<Transaction> lineMapper = new DefaultLineMapper<>();
|
||||
|
@ -93,10 +86,11 @@ public class SpringBatchRetryConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public Step retryStep(@Qualifier("retryItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> writer) throws ParseException {
|
||||
return stepBuilderFactory.get("retryStep")
|
||||
.<Transaction, Transaction>chunk(10)
|
||||
public Step retryStep(
|
||||
JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("retryItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> writer) {
|
||||
return new StepBuilder("retryStep", jobRepository)
|
||||
.<Transaction, Transaction>chunk(10, transactionManager)
|
||||
.reader(itemReader(inputCsv))
|
||||
.processor(processor)
|
||||
.writer(writer)
|
||||
|
@ -108,9 +102,8 @@ public class SpringBatchRetryConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "retryBatchJob")
|
||||
public Job retryJob(@Qualifier("retryStep") Step retryStep) {
|
||||
return jobBuilderFactory
|
||||
.get("retryBatchJob")
|
||||
public Job retryJob(JobRepository jobRepository, @Qualifier("retryStep") Step retryStep) {
|
||||
return new JobBuilder("retryBatchJob", jobRepository)
|
||||
.start(retryStep)
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
package com.baeldung.batch;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
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.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
@Profile("spring")
|
||||
public class SpringConfig {
|
||||
|
||||
@Value("org/springframework/batch/core/schema-drop-sqlite.sql")
|
||||
private Resource dropReopsitoryTables;
|
||||
|
||||
@Value("org/springframework/batch/core/schema-sqlite.sql")
|
||||
private Resource dataReopsitorySchema;
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName("org.sqlite.JDBC");
|
||||
dataSource.setUrl("jdbc:sqlite:repository.sqlite");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSourceInitializer dataSourceInitializer(DataSource dataSource) throws MalformedURLException {
|
||||
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
|
||||
|
||||
databasePopulator.addScript(dropReopsitoryTables);
|
||||
databasePopulator.addScript(dataReopsitorySchema);
|
||||
databasePopulator.setIgnoreFailedDrops(true);
|
||||
|
||||
DataSourceInitializer initializer = new DataSourceInitializer();
|
||||
initializer.setDataSource(dataSource);
|
||||
initializer.setDatabasePopulator(databasePopulator);
|
||||
|
||||
return initializer;
|
||||
}
|
||||
|
||||
private JobRepository getJobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(getTransactionManager());
|
||||
// JobRepositoryFactoryBean's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
factory.afterPropertiesSet();
|
||||
return (JobRepository) factory.getObject();
|
||||
}
|
||||
|
||||
private PlatformTransactionManager getTransactionManager() {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
public JobLauncher getJobLauncher() throws Exception {
|
||||
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
||||
// SimpleJobLauncher's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
jobLauncher.setJobRepository(getJobRepository());
|
||||
jobLauncher.afterPropertiesSet();
|
||||
return jobLauncher;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package com.baeldung.batch.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baeldung.batch.service.adapter.LocalDateTimeAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.time.LocalDateTime;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@XmlRootElement(name = "transactionRecord")
|
||||
|
|
|
@ -60,7 +60,7 @@ public class CustomMultiResourcePartitioner implements Partitioner {
|
|||
*/
|
||||
@Override
|
||||
public Map<String, ExecutionContext> partition(int gridSize) {
|
||||
Map<String, ExecutionContext> map = new HashMap<String, ExecutionContext>(gridSize);
|
||||
Map<String, ExecutionContext> map = new HashMap<>(gridSize);
|
||||
int i = 0, k = 1;
|
||||
for (Resource resource : resources) {
|
||||
ExecutionContext context = new ExecutionContext();
|
||||
|
|
|
@ -5,13 +5,13 @@ import com.baeldung.batch.service.RecordFieldSetMapper;
|
|||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepScope;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
|
||||
import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.UnexpectedInputException;
|
||||
import org.springframework.batch.item.file.FlatFileItemReader;
|
||||
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
|
||||
|
@ -36,42 +36,35 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.text.ParseException;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class SpringbatchPartitionConfig {
|
||||
public class SpringBatchPartitionConfig {
|
||||
|
||||
@Autowired
|
||||
ResourcePatternResolver resoursePatternResolver;
|
||||
|
||||
@Autowired
|
||||
private JobBuilderFactory jobs;
|
||||
|
||||
@Autowired
|
||||
private StepBuilderFactory steps;
|
||||
private ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
@Bean(name = "partitionerJob")
|
||||
public Job partitionerJob() throws UnexpectedInputException, MalformedURLException, ParseException {
|
||||
return jobs.get("partitionerJob")
|
||||
.start(partitionStep())
|
||||
public Job partitionerJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws UnexpectedInputException, ParseException {
|
||||
return new JobBuilder("partitionerJob", jobRepository)
|
||||
.start(partitionStep(jobRepository, transactionManager))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step partitionStep() throws UnexpectedInputException, MalformedURLException, ParseException {
|
||||
return steps.get("partitionStep")
|
||||
public Step partitionStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws UnexpectedInputException, ParseException {
|
||||
return new StepBuilder("partitionStep", jobRepository)
|
||||
.partitioner("slaveStep", partitioner())
|
||||
.step(slaveStep())
|
||||
.step(slaveStep(jobRepository, transactionManager))
|
||||
.taskExecutor(taskExecutor())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step slaveStep() throws UnexpectedInputException, MalformedURLException, ParseException {
|
||||
return steps.get("slaveStep")
|
||||
.<Transaction, Transaction>chunk(1)
|
||||
public Step slaveStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws UnexpectedInputException, ParseException {
|
||||
return new StepBuilder("slaveStep", jobRepository)
|
||||
.<Transaction, Transaction>chunk(1, transactionManager)
|
||||
.reader(itemReader(null))
|
||||
.writer(itemWriter(marshaller(), null))
|
||||
.build();
|
||||
|
@ -82,7 +75,7 @@ public class SpringbatchPartitionConfig {
|
|||
CustomMultiResourcePartitioner partitioner = new CustomMultiResourcePartitioner();
|
||||
Resource[] resources;
|
||||
try {
|
||||
resources = resoursePatternResolver.getResources("file:src/main/resources/input/partitioner/*.csv");
|
||||
resources = resourcePatternResolver.getResources("file:src/main/resources/input/partitioner/*.csv");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("I/O problems when resolving the input file pattern.", e);
|
||||
}
|
||||
|
@ -108,7 +101,7 @@ public class SpringbatchPartitionConfig {
|
|||
|
||||
@Bean(destroyMethod = "")
|
||||
@StepScope
|
||||
public StaxEventItemWriter<Transaction> itemWriter(Marshaller marshaller, @Value("#{stepExecutionContext[opFileName]}") String filename) throws MalformedURLException {
|
||||
public StaxEventItemWriter<Transaction> itemWriter(Marshaller marshaller, @Value("#{stepExecutionContext[opFileName]}") String filename) {
|
||||
StaxEventItemWriter<Transaction> itemWriter = new StaxEventItemWriter<>();
|
||||
itemWriter.setMarshaller(marshaller);
|
||||
itemWriter.setRootTagName("transactionRecord");
|
||||
|
@ -133,7 +126,8 @@ public class SpringbatchPartitionConfig {
|
|||
return taskExecutor;
|
||||
}
|
||||
|
||||
private JobRepository getJobRepository() throws Exception {
|
||||
@Bean(name = "jobRepository")
|
||||
public JobRepository getJobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(getTransactionManager());
|
||||
|
@ -143,20 +137,23 @@ public class SpringbatchPartitionConfig {
|
|||
return factory.getObject();
|
||||
}
|
||||
|
||||
private DataSource dataSource() {
|
||||
@Bean(name = "dataSource")
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
return builder.setType(EmbeddedDatabaseType.HSQL)
|
||||
return builder.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql")
|
||||
.addScript("classpath:org/springframework/batch/core/schema-h2.sql")
|
||||
.build();
|
||||
}
|
||||
|
||||
private PlatformTransactionManager getTransactionManager() {
|
||||
@Bean(name = "transactionManager")
|
||||
public PlatformTransactionManager getTransactionManager() {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
@Bean(name = "jobLauncher")
|
||||
public JobLauncher getJobLauncher() throws Exception {
|
||||
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
||||
TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
|
||||
// SimpleJobLauncher's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
jobLauncher.setJobRepository(getJobRepository());
|
|
@ -8,14 +8,14 @@ import org.springframework.batch.core.JobParameters;
|
|||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
public class SpringbatchPartitionerApp {
|
||||
public class SpringBatchPartitionerApp {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SpringbatchPartitionerApp.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SpringBatchPartitionerApp.class);
|
||||
|
||||
public static void main(final String[] args) {
|
||||
// Spring Java config
|
||||
final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(SpringbatchPartitionConfig.class);
|
||||
context.register(SpringBatchPartitionConfig.class);
|
||||
context.refresh();
|
||||
|
||||
final JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
|
|
@ -9,19 +9,13 @@ public class CustomSkipPolicy implements SkipPolicy {
|
|||
private static final int INVALID_TX_AMOUNT_LIMIT = -1000;
|
||||
|
||||
@Override
|
||||
public boolean shouldSkip(Throwable throwable, int skipCount) throws SkipLimitExceededException {
|
||||
|
||||
public boolean shouldSkip(Throwable throwable, long skipCount) throws SkipLimitExceededException {
|
||||
if (throwable instanceof MissingUsernameException && skipCount < MAX_SKIP_COUNT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (throwable instanceof NegativeAmountException && skipCount < MAX_SKIP_COUNT ) {
|
||||
NegativeAmountException ex = (NegativeAmountException) throwable;
|
||||
if(ex.getAmount() < INVALID_TX_AMOUNT_LIMIT){
|
||||
return false;
|
||||
} else{
|
||||
return true;
|
||||
}
|
||||
if (throwable instanceof NegativeAmountException ex && skipCount < MAX_SKIP_COUNT ) {
|
||||
return ex.getAmount() >= INVALID_TX_AMOUNT_LIMIT;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.time.format.DateTimeFormatter;
|
|||
|
||||
public class RecordFieldSetMapper implements FieldSetMapper<Transaction> {
|
||||
|
||||
public Transaction mapFieldSet(FieldSet fieldSet) throws BindException {
|
||||
public Transaction mapFieldSet(FieldSet fieldSet) {
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyy");
|
||||
|
||||
|
|
|
@ -5,15 +5,13 @@ import org.apache.http.client.methods.HttpGet;
|
|||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import com.baeldung.batch.model.Transaction;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class RetryItemProcessor implements ItemProcessor<Transaction, Transaction> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RetryItemProcessor.class);
|
||||
|
@ -22,7 +20,7 @@ public class RetryItemProcessor implements ItemProcessor<Transaction, Transactio
|
|||
private CloseableHttpClient closeableHttpClient;
|
||||
|
||||
@Override
|
||||
public Transaction process(Transaction transaction) throws IOException, JSONException {
|
||||
public Transaction process(Transaction transaction) throws Exception {
|
||||
LOGGER.info("Attempting to process user with id={}", transaction.getUserId());
|
||||
HttpResponse response = fetchMoreUserDetails(transaction.getUserId());
|
||||
|
||||
|
@ -35,7 +33,7 @@ public class RetryItemProcessor implements ItemProcessor<Transaction, Transactio
|
|||
return transaction;
|
||||
}
|
||||
|
||||
private HttpResponse fetchMoreUserDetails(int id) throws IOException {
|
||||
private HttpResponse fetchMoreUserDetails(int id) throws Exception {
|
||||
final HttpGet request = new HttpGet("http://www.baeldung.com:81/user/" + id);
|
||||
return closeableHttpClient.execute(request);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.baeldung.batch.service.adapter;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {
|
||||
|
||||
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
|
|
@ -5,8 +5,9 @@ import com.baeldung.batch.service.*;
|
|||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
@ -15,27 +16,21 @@ import org.springframework.batch.item.file.FlatFileItemReader;
|
|||
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
|
||||
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
|
||||
import org.springframework.batch.item.xml.StaxEventItemWriter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.WritableResource;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
|
||||
import java.text.ParseException;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
@Profile("spring-boot")
|
||||
public class SpringBootBatchConfig {
|
||||
@Autowired
|
||||
private JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Value("input/record.csv")
|
||||
private Resource inputCsv;
|
||||
|
@ -44,9 +39,9 @@ public class SpringBootBatchConfig {
|
|||
private Resource invalidInputCsv;
|
||||
|
||||
@Value("file:xml/output.xml")
|
||||
private Resource outputXml;
|
||||
private WritableResource outputXml;
|
||||
|
||||
public ItemReader<Transaction> itemReader(Resource inputData) throws UnexpectedInputException, ParseException {
|
||||
public ItemReader<Transaction> itemReader(Resource inputData) throws UnexpectedInputException {
|
||||
FlatFileItemReader<Transaction> reader = new FlatFileItemReader<>();
|
||||
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
|
||||
String[] tokens = {"username", "userid", "transactiondate", "amount"};
|
||||
|
@ -86,11 +81,10 @@ public class SpringBootBatchConfig {
|
|||
return marshaller3;
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Step step1(@Qualifier("itemProcessor") ItemProcessor<Transaction, Transaction> processor, ItemWriter<Transaction> itemWriter3) throws ParseException {
|
||||
return stepBuilderFactory
|
||||
.get("step1")
|
||||
.<Transaction, Transaction> chunk(10)
|
||||
@Bean(name = "step1")
|
||||
protected Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("itemProcessor") ItemProcessor<Transaction, Transaction> processor, ItemWriter<Transaction> itemWriter3) {
|
||||
return new StepBuilder("step1", jobRepository)
|
||||
.<Transaction, Transaction> chunk(10, transactionManager)
|
||||
.reader(itemReader(inputCsv))
|
||||
.processor(processor)
|
||||
.writer(itemWriter3)
|
||||
|
@ -98,16 +92,15 @@ public class SpringBootBatchConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "firstBatchJob")
|
||||
public Job job(@Qualifier("step1") Step step1) {
|
||||
return jobBuilderFactory.get("firstBatchJob").start(step1).build();
|
||||
public Job job(@Qualifier("step1") Step step1, JobRepository jobRepository) {
|
||||
return new JobBuilder("firstBatchJob", jobRepository).start(step1).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step skippingStep(@Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> itemWriter3) throws ParseException {
|
||||
return stepBuilderFactory
|
||||
.get("skippingStep")
|
||||
.<Transaction, Transaction>chunk(10)
|
||||
public Step skippingStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> itemWriter3) {
|
||||
return new StepBuilder("skippingStep", jobRepository)
|
||||
.<Transaction, Transaction>chunk(10, transactionManager)
|
||||
.reader(itemReader(invalidInputCsv))
|
||||
.processor(processor)
|
||||
.writer(itemWriter3)
|
||||
|
@ -119,19 +112,17 @@ public class SpringBootBatchConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "skippingBatchJob")
|
||||
public Job skippingJob(@Qualifier("skippingStep") Step skippingStep) {
|
||||
return jobBuilderFactory
|
||||
.get("skippingBatchJob")
|
||||
public Job skippingJob(JobRepository jobRepository, @Qualifier("skippingStep") Step skippingStep) {
|
||||
return new JobBuilder("skippingBatchJob", jobRepository)
|
||||
.start(skippingStep)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step skipPolicyStep(@Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> itemWriter3) throws ParseException {
|
||||
return stepBuilderFactory
|
||||
.get("skipPolicyStep")
|
||||
.<Transaction, Transaction>chunk(10)
|
||||
@Bean(name = "skipPolicyStep")
|
||||
public Step skipPolicyStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("skippingItemProcessor") ItemProcessor<Transaction, Transaction> processor,
|
||||
ItemWriter<Transaction> itemWriter3) {
|
||||
return new StepBuilder("skipPolicyStep", jobRepository)
|
||||
.<Transaction, Transaction>chunk(10, transactionManager)
|
||||
.reader(itemReader(invalidInputCsv))
|
||||
.processor(processor)
|
||||
.writer(itemWriter3)
|
||||
|
@ -141,11 +132,9 @@ public class SpringBootBatchConfig {
|
|||
}
|
||||
|
||||
@Bean(name = "skipPolicyBatchJob")
|
||||
public Job skipPolicyBatchJob(@Qualifier("skipPolicyStep") Step skipPolicyStep) {
|
||||
return jobBuilderFactory
|
||||
.get("skipPolicyBatchJob")
|
||||
public Job skipPolicyBatchJob(JobRepository jobRepository, @Qualifier("skipPolicyStep") Step skipPolicyStep) {
|
||||
return new JobBuilder("skipPolicyBatchJob", jobRepository)
|
||||
.start(skipPolicyStep)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.baeldung.batchtesting;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.batchtesting.model.Book;
|
||||
import com.baeldung.batchtesting.model.BookDetails;
|
||||
import com.baeldung.batchtesting.model.BookRecord;
|
||||
|
@ -12,10 +10,10 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepScope;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.file.FlatFileItemReader;
|
||||
|
@ -25,27 +23,19 @@ import org.springframework.batch.item.json.JacksonJsonObjectMarshaller;
|
|||
import org.springframework.batch.item.json.JsonFileItemWriter;
|
||||
import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder;
|
||||
import org.springframework.batch.item.support.ListItemWriter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class SpringBatchConfiguration {
|
||||
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(SpringBatchConfiguration.class);
|
||||
|
||||
private static final String[] TOKENS = { "bookname", "bookauthor", "bookformat", "isbn", "publishyear" };
|
||||
|
||||
@Autowired
|
||||
private JobBuilderFactory jobBuilderFactory;
|
||||
|
||||
@Autowired
|
||||
private StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
@Bean
|
||||
@StepScope
|
||||
public FlatFileItemReader<BookRecord> csvItemReader(@Value("#{jobParameters['file.input']}") String input) {
|
||||
|
@ -65,7 +55,7 @@ public class SpringBatchConfiguration {
|
|||
|
||||
@Bean
|
||||
@StepScope
|
||||
public JsonFileItemWriter<Book> jsonItemWriter(@Value("#{jobParameters['file.output']}") String output) throws IOException {
|
||||
public JsonFileItemWriter<Book> jsonItemWriter(@Value("#{jobParameters['file.output']}") String output) {
|
||||
JsonFileItemWriterBuilder<Book> builder = new JsonFileItemWriterBuilder<>();
|
||||
JacksonJsonObjectMarshaller<Book> marshaller = new JacksonJsonObjectMarshaller<>();
|
||||
LOGGER.info("Configuring writer to output {}", output);
|
||||
|
@ -81,7 +71,7 @@ public class SpringBatchConfiguration {
|
|||
@Bean
|
||||
@StepScope
|
||||
public ListItemWriter<BookDetails> listItemWriter() {
|
||||
return new ListItemWriter<BookDetails>();
|
||||
return new ListItemWriter<>();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -96,12 +86,11 @@ public class SpringBatchConfiguration {
|
|||
return new BookDetailsItemProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step step1(ItemReader<BookRecord> csvItemReader, ItemWriter<Book> jsonItemWriter) throws IOException {
|
||||
@Bean(name = "step1")
|
||||
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader<BookRecord> csvItemReader, ItemWriter<Book> jsonItemWriter) {
|
||||
// @formatter:off
|
||||
return stepBuilderFactory
|
||||
.get("step1")
|
||||
.<BookRecord, Book> chunk(3)
|
||||
return new StepBuilder("step1", jobRepository)
|
||||
.<BookRecord, Book> chunk(3, transactionManager)
|
||||
.reader(csvItemReader)
|
||||
.processor(bookItemProcessor())
|
||||
.writer(jsonItemWriter)
|
||||
|
@ -109,12 +98,11 @@ public class SpringBatchConfiguration {
|
|||
// @formatter:on
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Step step2(ItemReader<BookRecord> csvItemReader, ItemWriter<BookDetails> listItemWriter) {
|
||||
@Bean(name = "step2")
|
||||
public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader<BookRecord> csvItemReader, ItemWriter<BookDetails> listItemWriter) {
|
||||
// @formatter:off
|
||||
return stepBuilderFactory
|
||||
.get("step2")
|
||||
.<BookRecord, BookDetails> chunk(3)
|
||||
return new StepBuilder("step2", jobRepository)
|
||||
.<BookRecord, BookDetails> chunk(3, transactionManager)
|
||||
.reader(csvItemReader)
|
||||
.processor(bookDetailsItemProcessor())
|
||||
.writer(listItemWriter)
|
||||
|
@ -123,15 +111,13 @@ public class SpringBatchConfiguration {
|
|||
}
|
||||
|
||||
@Bean(name = "transformBooksRecords")
|
||||
public Job transformBookRecords(Step step1, Step step2) throws IOException {
|
||||
public Job transformBookRecords(JobRepository jobRepository, Step step1, Step step2) {
|
||||
// @formatter:off
|
||||
return jobBuilderFactory
|
||||
.get("transformBooksRecords")
|
||||
return new JobBuilder("transformBooksRecords", jobRepository)
|
||||
.flow(step1)
|
||||
.next(step2)
|
||||
.end()
|
||||
.build();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public class BookDetailsItemProcessor implements ItemProcessor<BookRecord, BookD
|
|||
private static Logger LOGGER = LoggerFactory.getLogger(BookDetailsItemProcessor.class);
|
||||
|
||||
@Override
|
||||
public BookDetails process(BookRecord item) throws Exception {
|
||||
public BookDetails process(BookRecord item) {
|
||||
BookDetails bookDetails = new BookDetails();
|
||||
bookDetails.setBookFormat(item.getBookFormat());
|
||||
bookDetails.setBookISBN(item.getBookISBN());
|
||||
|
|
|
@ -11,7 +11,7 @@ public class BookItemProcessor implements ItemProcessor<BookRecord, Book> {
|
|||
private static Logger LOGGER = LoggerFactory.getLogger(BookItemProcessor.class);
|
||||
|
||||
@Override
|
||||
public Book process(BookRecord item) throws Exception {
|
||||
public Book process(BookRecord item) {
|
||||
Book book = new Book();
|
||||
book.setAuthor(item.getBookAuthor());
|
||||
book.setName(item.getBookName());
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.springframework.validation.BindException;
|
|||
public class BookRecordFieldSetMapper implements FieldSetMapper<BookRecord> {
|
||||
|
||||
@Override
|
||||
public BookRecord mapFieldSet(FieldSet fieldSet) throws BindException {
|
||||
public BookRecord mapFieldSet(FieldSet fieldSet) {
|
||||
BookRecord bookRecord = new BookRecord();
|
||||
bookRecord.setBookName(fieldSet.readString("bookname"));
|
||||
bookRecord.setBookAuthor(fieldSet.readString("bookauthor"));
|
||||
|
|
|
@ -21,9 +21,9 @@ public class LineReader implements ItemReader<Line>, StepExecutionListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Line read() throws Exception {
|
||||
public Line read() {
|
||||
Line line = fu.readLine();
|
||||
if (line != null) logger.debug("Read line: " + line.toString());
|
||||
if (line != null) logger.debug("Read line: " + line);
|
||||
return line;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,9 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.StepExecutionListener;
|
||||
import org.springframework.batch.item.Chunk;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LinesWriter implements ItemWriter<Line>, StepExecutionListener {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(LinesWriter.class);
|
||||
|
@ -30,7 +29,7 @@ public class LinesWriter implements ItemWriter<Line>, StepExecutionListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void write(List<? extends Line> lines) throws Exception {
|
||||
public void write(Chunk<? extends Line> lines) {
|
||||
for (Line line : lines) {
|
||||
fu.writeLine(line);
|
||||
logger.debug("Wrote line " + line.toString());
|
||||
|
|
|
@ -6,67 +6,19 @@ import com.baeldung.taskletsvschunks.chunks.LinesWriter;
|
|||
import com.baeldung.taskletsvschunks.model.Line;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
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.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.batch.test.JobLauncherTestUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class ChunksConfig {
|
||||
|
||||
@Autowired private JobBuilderFactory jobs;
|
||||
|
||||
@Autowired private StepBuilderFactory steps;
|
||||
|
||||
@Bean
|
||||
public JobLauncherTestUtils jobLauncherTestUtils() {
|
||||
return new JobLauncherTestUtils();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobRepository jobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(transactionManager());
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName("org.sqlite.JDBC");
|
||||
dataSource.setUrl("jdbc:sqlite:repository.sqlite");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobLauncher jobLauncher() throws Exception {
|
||||
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
||||
jobLauncher.setJobRepository(jobRepository());
|
||||
return jobLauncher;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ItemReader<Line> itemReader() {
|
||||
return new LineReader();
|
||||
|
@ -82,20 +34,19 @@ public class ChunksConfig {
|
|||
return new LinesWriter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Step processLines(ItemReader<Line> reader, ItemProcessor<Line, Line> processor, ItemWriter<Line> writer) {
|
||||
return steps.get("processLines").<Line, Line> chunk(2)
|
||||
@Bean(name = "processLines")
|
||||
protected Step processLines(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader<Line> reader, ItemProcessor<Line, Line> processor, ItemWriter<Line> writer) {
|
||||
return new StepBuilder("processLines", jobRepository).<Line, Line> chunk(2, transactionManager)
|
||||
.reader(reader)
|
||||
.processor(processor)
|
||||
.writer(writer)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Job job() {
|
||||
return jobs
|
||||
.get("chunksJob")
|
||||
.start(processLines(itemReader(), itemProcessor(), itemWriter()))
|
||||
@Bean(name = "chunksJob")
|
||||
public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new JobBuilder("chunksJob", jobRepository)
|
||||
.start(processLines(jobRepository, transactionManager, itemReader(), itemProcessor(), itemWriter()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,64 +5,16 @@ import com.baeldung.taskletsvschunks.tasklets.LinesReader;
|
|||
import com.baeldung.taskletsvschunks.tasklets.LinesWriter;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
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.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.batch.test.JobLauncherTestUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class TaskletsConfig {
|
||||
|
||||
@Autowired private JobBuilderFactory jobs;
|
||||
|
||||
@Autowired private StepBuilderFactory steps;
|
||||
|
||||
@Bean
|
||||
public JobLauncherTestUtils jobLauncherTestUtils() {
|
||||
return new JobLauncherTestUtils();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobRepository jobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(transactionManager());
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName("org.sqlite.JDBC");
|
||||
dataSource.setUrl("jdbc:sqlite:repository.sqlite");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobLauncher jobLauncher() throws Exception {
|
||||
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
||||
jobLauncher.setJobRepository(jobRepository());
|
||||
return jobLauncher;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LinesReader linesReader() {
|
||||
return new LinesReader();
|
||||
|
@ -79,36 +31,32 @@ public class TaskletsConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
protected Step readLines() {
|
||||
return steps
|
||||
.get("readLines")
|
||||
.tasklet(linesReader())
|
||||
protected Step readLines(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("readLines", jobRepository)
|
||||
.tasklet(linesReader(), transactionManager)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Step processLines() {
|
||||
return steps
|
||||
.get("processLines")
|
||||
.tasklet(linesProcessor())
|
||||
protected Step processLines(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("processLines", jobRepository)
|
||||
.tasklet(linesProcessor(), transactionManager)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Step writeLines() {
|
||||
return steps
|
||||
.get("writeLines")
|
||||
.tasklet(linesWriter())
|
||||
protected Step writeLines(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("writeLines", jobRepository)
|
||||
.tasklet(linesWriter(), transactionManager)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Job job() {
|
||||
return jobs
|
||||
.get("taskletsJob")
|
||||
.start(readLines())
|
||||
.next(processLines())
|
||||
.next(writeLines())
|
||||
public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new JobBuilder("taskletsJob", jobRepository)
|
||||
.start(readLines(jobRepository, transactionManager))
|
||||
.next(processLines(jobRepository, transactionManager))
|
||||
.next(writeLines(jobRepository, transactionManager))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public class LinesReader implements Tasklet, StepExecutionListener {
|
|||
|
||||
@Override
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
lines = new ArrayList<Line>();
|
||||
lines = new ArrayList<>();
|
||||
fu = new FileUtils("taskletsvschunks/input/tasklets-vs-chunks.csv");
|
||||
logger.debug("Lines Reader initialized.");
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public class ConditionalFlowApplication implements CommandLineRunner {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
public void run(String... args) {
|
||||
logger.info("Running conditional flow application...");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,39 +6,49 @@ import org.baeldung.conditionalflow.step.*;
|
|||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.batch.core.job.builder.JobBuilder;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.support.TaskExecutorJobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.builder.StepBuilder;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.baeldung.conditionalflow.NumberInfoDecider.NOTIFY;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@EnableBatchProcessing
|
||||
public class NumberInfoConfig {
|
||||
|
||||
@Bean
|
||||
@Qualifier("NotificationStep")
|
||||
public Step notificationStep(StepBuilderFactory sbf) {
|
||||
return sbf.get("Notify step")
|
||||
.tasklet(new NotifierTasklet())
|
||||
public Step notificationStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||
return new StepBuilder("Notify step", jobRepository)
|
||||
.tasklet(new NotifierTasklet(), transactionManager)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Step numberGeneratorStep(StepBuilderFactory sbf, int[] values, String prepend) {
|
||||
return sbf.get("Number generator")
|
||||
.<NumberInfo, Integer> chunk(1)
|
||||
public Step numberGeneratorStep(JobRepository jobRepositories, PlatformTransactionManager transactionManager, int[] values, String prepend) {
|
||||
return new StepBuilder("Number generator", jobRepositories)
|
||||
.<NumberInfo, Integer> chunk(1, transactionManager)
|
||||
.reader(new NumberInfoGenerator(values))
|
||||
.processor(new NumberInfoClassifier())
|
||||
.writer(new PrependingStdoutWriter<>(prepend))
|
||||
.build();
|
||||
}
|
||||
|
||||
public Step numberGeneratorStepDecider(StepBuilderFactory sbf, int[] values, String prepend) {
|
||||
return sbf.get("Number generator decider")
|
||||
.<NumberInfo, Integer> chunk(1)
|
||||
public Step numberGeneratorStepDecider(JobRepository jobRepositories, PlatformTransactionManager transactionManager, int[] values, String prepend) {
|
||||
return new StepBuilder("Number generator decider", jobRepositories)
|
||||
.<NumberInfo, Integer> chunk(1, transactionManager)
|
||||
.reader(new NumberInfoGenerator(values))
|
||||
.processor(new NumberInfoClassifierWithDecider())
|
||||
.writer(new PrependingStdoutWriter<>(prepend))
|
||||
|
@ -47,10 +57,10 @@ public class NumberInfoConfig {
|
|||
|
||||
@Bean
|
||||
@Qualifier("first_job")
|
||||
public Job numberGeneratorNonNotifierJob(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, @Qualifier("NotificationStep") Step notificationStep) {
|
||||
public Job numberGeneratorNonNotifierJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("NotificationStep") Step notificationStep) {
|
||||
int[] nonNotifierData = { -1, -2, -3 };
|
||||
Step step = numberGeneratorStep(stepBuilderFactory, nonNotifierData, "First Dataset Processor");
|
||||
return jobBuilderFactory.get("Number generator - first dataset")
|
||||
Step step = numberGeneratorStep(jobRepository, transactionManager, nonNotifierData, "First Dataset Processor");
|
||||
return new JobBuilder("Number generator - first dataset", jobRepository)
|
||||
.start(step)
|
||||
.on(NOTIFY)
|
||||
.to(notificationStep)
|
||||
|
@ -63,10 +73,10 @@ public class NumberInfoConfig {
|
|||
|
||||
@Bean
|
||||
@Qualifier("second_job")
|
||||
public Job numberGeneratorNotifierJob(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, @Qualifier("NotificationStep") Step notificationStep) {
|
||||
public Job numberGeneratorNotifierJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("NotificationStep") Step notificationStep) {
|
||||
int[] billableData = { 11, -2, -3 };
|
||||
Step dataProviderStep = numberGeneratorStep(stepBuilderFactory, billableData, "Second Dataset Processor");
|
||||
return jobBuilderFactory.get("Number generator - second dataset")
|
||||
Step dataProviderStep = numberGeneratorStep(jobRepository, transactionManager, billableData, "Second Dataset Processor");
|
||||
return new JobBuilder("Number generator - second dataset", jobRepository)
|
||||
.start(dataProviderStep)
|
||||
.on(NOTIFY)
|
||||
.to(notificationStep)
|
||||
|
@ -77,10 +87,10 @@ public class NumberInfoConfig {
|
|||
@Bean
|
||||
@Qualifier("third_job")
|
||||
@Primary
|
||||
public Job numberGeneratorNotifierJobWithDecider(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, @Qualifier("NotificationStep") Step notificationStep) {
|
||||
public Job numberGeneratorNotifierJobWithDecider(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("NotificationStep") Step notificationStep) {
|
||||
int[] billableData = { 11, -2, -3 };
|
||||
Step dataProviderStep = numberGeneratorStepDecider(stepBuilderFactory, billableData, "Third Dataset Processor");
|
||||
return jobBuilderFactory.get("Number generator - third dataset")
|
||||
Step dataProviderStep = numberGeneratorStepDecider(jobRepository, transactionManager, billableData, "Third Dataset Processor");
|
||||
return new JobBuilder("Number generator - third dataset", jobRepository)
|
||||
.start(dataProviderStep)
|
||||
.next(new NumberInfoDecider())
|
||||
.on(NOTIFY)
|
||||
|
@ -88,4 +98,39 @@ public class NumberInfoConfig {
|
|||
.end()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(name = "jobRepository")
|
||||
public JobRepository getJobRepository() throws Exception {
|
||||
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
|
||||
factory.setDataSource(dataSource());
|
||||
factory.setTransactionManager(getTransactionManager());
|
||||
// JobRepositoryFactoryBean's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
factory.afterPropertiesSet();
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean(name = "dataSource")
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
return builder.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("classpath:org/springframework/batch/core/schema-drop-h2.sql")
|
||||
.addScript("classpath:org/springframework/batch/core/schema-h2.sql")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(name = "transactionManager")
|
||||
public PlatformTransactionManager getTransactionManager() {
|
||||
return new ResourcelessTransactionManager();
|
||||
}
|
||||
|
||||
@Bean(name = "jobLauncher")
|
||||
public JobLauncher getJobLauncher() throws Exception {
|
||||
TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher();
|
||||
// SimpleJobLauncher's methods Throws Generic Exception,
|
||||
// it would have been better to have a specific one
|
||||
jobLauncher.setJobRepository(getJobRepository());
|
||||
jobLauncher.afterPropertiesSet();
|
||||
return jobLauncher;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ import org.springframework.batch.repeat.RepeatStatus;
|
|||
|
||||
public class NotifierTasklet implements Tasklet {
|
||||
@Override
|
||||
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
|
||||
System.err.println("[" + chunkContext.getStepContext()
|
||||
.getJobName() + "] contains interesting data!!");
|
||||
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) {
|
||||
System.err.println("[" + chunkContext.getStepContext().getJobName() + "] contains interesting data!!");
|
||||
return RepeatStatus.FINISHED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class NumberInfoClassifier extends ItemListenerSupport<NumberInfo, Intege
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer process(NumberInfo numberInfo) throws Exception {
|
||||
return Integer.valueOf(numberInfo.getNumber());
|
||||
public Integer process(NumberInfo numberInfo) {
|
||||
return numberInfo.getNumber();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.springframework.batch.item.ItemProcessor;
|
|||
public class NumberInfoClassifierWithDecider extends ItemListenerSupport<NumberInfo, Integer> implements ItemProcessor<NumberInfo, Integer> {
|
||||
|
||||
@Override
|
||||
public Integer process(NumberInfo numberInfo) throws Exception {
|
||||
public Integer process(NumberInfo numberInfo) {
|
||||
return Integer.valueOf(numberInfo.getNumber());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.baeldung.conditionalflow.step;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.item.Chunk;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
||||
public class PrependingStdoutWriter<T> implements ItemWriter<T> {
|
||||
|
@ -12,8 +11,8 @@ public class PrependingStdoutWriter<T> implements ItemWriter<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void write(List<? extends T> list) {
|
||||
for (T listItem : list) {
|
||||
public void write(Chunk<? extends T> chunk) {
|
||||
for (T listItem : chunk) {
|
||||
System.out.println(prependText + " " + listItem.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
</transactionRecord>
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
</transactionRecord>
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
</transactionRecord>
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
</transactionRecord>
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>10000.0</amount>
|
||||
<transactionDate>2015-10-31 00:00:00</transactionDate>
|
||||
<userId>1234</userId>
|
||||
<username>devendra</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>12321.0</amount>
|
||||
<transactionDate>2015-12-03 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>john</username>
|
||||
</transactionRecord>
|
||||
<transactionRecord>
|
||||
<amount>23411.0</amount>
|
||||
<transactionDate>2015-02-02 00:00:00</transactionDate>
|
||||
<userId>2134</userId>
|
||||
<username>robin</username>
|
||||
</transactionRecord>
|
||||
</transactionRecord>
|
|
@ -17,7 +17,7 @@
|
|||
<bean
|
||||
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
|
||||
<property name="names"
|
||||
value="username,userid,transaction_date,transaction_amount" />
|
||||
value="username,userid,transactiondate,amount" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="fieldSetMapper">
|
||||
|
@ -33,11 +33,11 @@
|
|||
|
||||
<bean id="itemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
|
||||
<property name="resource" value="file:xml/output.xml" />
|
||||
<property name="marshaller" ref="recordMarshaller" />
|
||||
<property name="marshaller" ref="marshaller" />
|
||||
<property name="rootTagName" value="transactionRecord" />
|
||||
</bean>
|
||||
|
||||
<bean id="recordMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
|
||||
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
|
||||
<property name="classesToBeBound">
|
||||
<list>
|
||||
<value>com.baeldung.batch.model.Transaction</value>
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<!-- connect to SQLite database -->
|
||||
<bean id="dataSource"
|
||||
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.sqlite.JDBC" />
|
||||
<property name="url" value="jdbc:sqlite:repository.sqlite" />
|
||||
<property name="driverClassName" value="org.h2.Driver" />
|
||||
<property name="url" value="jdbc:h2:repository.sqlite" />
|
||||
<property name="username" value="" />
|
||||
<property name="password" value="" />
|
||||
</bean>
|
||||
|
@ -18,8 +18,8 @@
|
|||
<!-- create job-meta tables automatically -->
|
||||
<jdbc:initialize-database data-source="dataSource">
|
||||
<jdbc:script
|
||||
location="org/springframework/batch/core/schema-drop-sqlite.sql" />
|
||||
<jdbc:script location="org/springframework/batch/core/schema-sqlite.sql" />
|
||||
location="org/springframework/batch/core/schema-drop-h2.sql" />
|
||||
<jdbc:script location="org/springframework/batch/core/schema-h2.sql" />
|
||||
</jdbc:initialize-database>
|
||||
|
||||
<!-- stored job-meta in memory -->
|
||||
|
@ -31,7 +31,6 @@
|
|||
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="databaseType" value="sqlite" />
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager"
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
package com.baeldung.batch;
|
||||
|
||||
import com.baeldung.batch.SpringBatchRetryConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.test.AssertFile;
|
||||
import org.springframework.batch.test.JobLauncherTestUtils;
|
||||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -21,15 +18,15 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.batch.test.AssertFile.assertFileEquals;
|
||||
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBatchTest
|
||||
@EnableAutoConfiguration
|
||||
@ContextConfiguration(classes = { SpringBatchRetryConfig.class })
|
||||
|
@ -56,8 +53,8 @@ public class SpringBatchRetryIntegrationTest {
|
|||
JobInstance actualJobInstance = jobExecution.getJobInstance();
|
||||
ExitStatus actualJobExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
assertThat(actualJobInstance.getJobName(), is("retryBatchJob"));
|
||||
assertThat(actualJobExitStatus.getExitCode(), is("FAILED"));
|
||||
assertEquals("retryBatchJob", actualJobInstance.getJobName());
|
||||
assertEquals("FAILED", actualJobExitStatus.getExitCode());
|
||||
assertThat(actualJobExitStatus.getExitDescription(), containsString("org.apache.http.conn.ConnectTimeoutException"));
|
||||
}
|
||||
|
||||
|
@ -78,11 +75,11 @@ public class SpringBatchRetryIntegrationTest {
|
|||
JobInstance actualJobInstance = jobExecution.getJobInstance();
|
||||
ExitStatus actualJobExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
assertThat(actualJobInstance.getJobName(), is("retryBatchJob"));
|
||||
assertThat(actualJobExitStatus.getExitCode(), is("COMPLETED"));
|
||||
AssertFile.assertFileEquals(expectedResult, actualResult);
|
||||
assertEquals("retryBatchJob", actualJobInstance.getJobName());
|
||||
assertEquals("COMPLETED", actualJobExitStatus.getExitCode());
|
||||
assertFileEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
|
||||
private JobParameters defaultJobParameters() {
|
||||
JobParametersBuilder paramsBuilder = new JobParametersBuilder();
|
||||
paramsBuilder.addString("jobID", String.valueOf(System.currentTimeMillis()));
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
package com.baeldung.batchtesting;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.baeldung.batchtesting.SpringBatchConfiguration;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
|
@ -22,20 +19,11 @@ import org.springframework.batch.test.context.SpringBatchTest;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBatchTest
|
||||
@EnableAutoConfiguration
|
||||
@ContextConfiguration(classes = { SpringBatchConfiguration.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
|
||||
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
|
||||
public class SpringBatchIntegrationTest {
|
||||
|
||||
private static final String TEST_OUTPUT = "src/test/resources/output/actual-output.json";
|
||||
|
@ -50,7 +38,7 @@ public class SpringBatchIntegrationTest {
|
|||
@Autowired
|
||||
private JobRepositoryTestUtils jobRepositoryTestUtils;
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
jobRepositoryTestUtils.removeJobExecutions();
|
||||
}
|
||||
|
@ -74,8 +62,8 @@ public class SpringBatchIntegrationTest {
|
|||
ExitStatus actualJobExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
// then
|
||||
assertThat(actualJobInstance.getJobName(), is("transformBooksRecords"));
|
||||
assertThat(actualJobExitStatus.getExitCode(), is("COMPLETED"));
|
||||
assertEquals("transformBooksRecords", actualJobInstance.getJobName());
|
||||
assertEquals("COMPLETED", actualJobExitStatus.getExitCode());
|
||||
AssertFile.assertFileEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
|
@ -92,8 +80,8 @@ public class SpringBatchIntegrationTest {
|
|||
ExitStatus actualJobExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
// then
|
||||
assertThat(actualStepExecutions.size(), is(1));
|
||||
assertThat(actualJobExitStatus.getExitCode(), is("COMPLETED"));
|
||||
assertEquals(1, actualStepExecutions.size());
|
||||
assertEquals("COMPLETED", actualJobExitStatus.getExitCode());
|
||||
AssertFile.assertFileEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
|
@ -106,10 +94,10 @@ public class SpringBatchIntegrationTest {
|
|||
ExitStatus actualExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
// then
|
||||
assertThat(actualStepExecutions.size(), is(1));
|
||||
assertThat(actualExitStatus.getExitCode(), is("COMPLETED"));
|
||||
assertEquals(1, actualStepExecutions.size());
|
||||
assertEquals("COMPLETED", actualExitStatus.getExitCode());
|
||||
actualStepExecutions.forEach(stepExecution -> {
|
||||
assertThat(stepExecution.getWriteCount(), is(8));
|
||||
assertEquals(8L, stepExecution.getWriteCount());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
package com.baeldung.batchtesting;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.springframework.batch.test.AssertFile.assertFileEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.batchtesting.SpringBatchConfiguration;
|
||||
import com.baeldung.batchtesting.model.Book;
|
||||
import com.baeldung.batchtesting.model.BookRecord;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.item.Chunk;
|
||||
import org.springframework.batch.item.file.FlatFileItemReader;
|
||||
import org.springframework.batch.item.json.JsonFileItemWriter;
|
||||
import org.springframework.batch.test.AssertFile;
|
||||
import org.springframework.batch.test.JobRepositoryTestUtils;
|
||||
import org.springframework.batch.test.MetaDataInstanceFactory;
|
||||
import org.springframework.batch.test.StepScopeTestUtils;
|
||||
|
@ -24,21 +23,12 @@ import org.springframework.batch.test.context.SpringBatchTest;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBatchTest
|
||||
@EnableAutoConfiguration
|
||||
@ContextConfiguration(classes = { SpringBatchConfiguration.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
|
||||
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
|
||||
public class SpringBatchStepScopeIntegrationTest {
|
||||
|
||||
private static final String TEST_OUTPUT = "src/test/resources/output/actual-output.json";
|
||||
|
@ -62,7 +52,7 @@ public class SpringBatchStepScopeIntegrationTest {
|
|||
return paramsBuilder.toJobParameters();
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
jobRepositoryTestUtils.removeJobExecutions();
|
||||
}
|
||||
|
@ -80,11 +70,11 @@ public class SpringBatchStepScopeIntegrationTest {
|
|||
while ((bookRecord = itemReader.read()) != null) {
|
||||
|
||||
// then
|
||||
assertThat(bookRecord.getBookName(), is("Foundation"));
|
||||
assertThat(bookRecord.getBookAuthor(), is("Asimov I."));
|
||||
assertThat(bookRecord.getBookISBN(), is("ISBN 12839"));
|
||||
assertThat(bookRecord.getBookFormat(), is("hardcover"));
|
||||
assertThat(bookRecord.getPublishingYear(), is("2018"));
|
||||
assertEquals("Foundation", bookRecord.getBookName());
|
||||
assertEquals("Asimov I.", bookRecord.getBookAuthor());
|
||||
assertEquals("ISBN 12839", bookRecord.getBookISBN());
|
||||
assertEquals("hardcover", bookRecord.getBookFormat());
|
||||
assertEquals("2018", bookRecord.getPublishingYear());
|
||||
}
|
||||
itemReader.close();
|
||||
return null;
|
||||
|
@ -106,12 +96,12 @@ public class SpringBatchStepScopeIntegrationTest {
|
|||
StepScopeTestUtils.doInStepScope(stepExecution, () -> {
|
||||
|
||||
jsonItemWriter.open(stepExecution.getExecutionContext());
|
||||
jsonItemWriter.write(Arrays.asList(demoBook));
|
||||
jsonItemWriter.write(new Chunk<>(List.of(demoBook)));
|
||||
jsonItemWriter.close();
|
||||
return null;
|
||||
});
|
||||
|
||||
// then
|
||||
AssertFile.assertFileEquals(expectedResult, actualResult);
|
||||
assertFileEquals(expectedResult, actualResult);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
package com.baeldung.taskletsvschunks.chunks;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.baeldung.taskletsvschunks.config.ChunksConfig;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.test.JobLauncherTestUtils;
|
||||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = ChunksConfig.class)
|
||||
@SpringBatchTest
|
||||
@EnableAutoConfiguration
|
||||
@ContextConfiguration(classes = ChunksConfig.class)
|
||||
public class ChunksIntegrationTest {
|
||||
|
||||
@Autowired private JobLauncherTestUtils jobLauncherTestUtils;
|
||||
@Autowired
|
||||
private JobLauncherTestUtils jobLauncherTestUtils;
|
||||
|
||||
@Test
|
||||
public void givenChunksJob_WhenJobEnds_ThenStatusCompleted() throws Exception {
|
||||
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
|
||||
Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
|
||||
assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
|
||||
}
|
||||
}
|
|
@ -1,25 +1,29 @@
|
|||
package com.baeldung.taskletsvschunks.tasklets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.baeldung.taskletsvschunks.config.TaskletsConfig;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.test.JobLauncherTestUtils;
|
||||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBatchTest
|
||||
@EnableAutoConfiguration
|
||||
@ContextConfiguration(classes = TaskletsConfig.class)
|
||||
public class TaskletsIntegrationTest {
|
||||
|
||||
@Autowired private JobLauncherTestUtils jobLauncherTestUtils;
|
||||
@Autowired
|
||||
private JobLauncherTestUtils jobLauncherTestUtils;
|
||||
|
||||
@Test
|
||||
public void givenTaskletsJob_WhenJobEnds_ThenStatusCompleted() throws Exception {
|
||||
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
|
||||
Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
|
||||
assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
package org.baeldung.conditionalflow;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.baeldung.conditionalflow.config.NumberInfoConfig;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
|
@ -10,26 +12,16 @@ import org.springframework.batch.test.JobLauncherTestUtils;
|
|||
import org.springframework.batch.test.context.SpringBatchTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBatchTest
|
||||
@EnableAutoConfiguration
|
||||
@ContextConfiguration(classes = { NumberInfoConfig.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
||||
public class DeciderJobIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private JobLauncherTestUtils jobLauncherTestUtils;
|
||||
|
||||
|
@ -39,8 +31,7 @@ public class DeciderJobIntegrationTest {
|
|||
Collection<StepExecution> actualStepExecutions = jobExecution.getStepExecutions();
|
||||
ExitStatus actualJobExitStatus = jobExecution.getExitStatus();
|
||||
|
||||
assertEquals("COMPLETED", actualJobExitStatus.getExitCode()
|
||||
.toString());
|
||||
assertEquals("COMPLETED", actualJobExitStatus.getExitCode());
|
||||
assertEquals(2, actualStepExecutions.size());
|
||||
boolean notifyStepDidRun = false;
|
||||
Iterator<StepExecution> iterator = actualStepExecutions.iterator();
|
||||
|
|
|
@ -5,10 +5,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ExtendWith(SpringExtension.class)
|
||||
class NumberInfoUnitTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
[
|
||||
{"author":"Grisham J.","name":"The Firm"}
|
||||
{"author":"Asimov I.","name":"Foundation"},
|
||||
{"author":"Strugatski A.","name":"Roadside Picnic"},
|
||||
{"author":"Murakami H.","name":"Norwegian Wood"},
|
||||
{"author":"Brown D.","name":"Davinci Code"},
|
||||
{"author":"Dick K. P.","name":"Ubik"},
|
||||
{"author":"King S.","name":"JFK"},
|
||||
{"author":"Sagan C.","name":"Contact"},
|
||||
{"author":"Huxley A.","name":"Brave New World"}
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue