diff --git a/Chapter04/pom.xml b/Chapter04/pom.xml index 254359c..68658d6 100644 --- a/Chapter04/pom.xml +++ b/Chapter04/pom.xml @@ -33,6 +33,11 @@ mysql-connector-java runtime + + com.h2database + h2 + runtime + org.springframework.boot spring-boot-starter-test diff --git a/Chapter04/src/main/java/com/example/Chapter04/jobs/ChunkJob.java b/Chapter04/src/main/java/com/example/Chapter04/jobs/ChunkJob.java index 397d3bc..e31cf8b 100644 --- a/Chapter04/src/main/java/com/example/Chapter04/jobs/ChunkJob.java +++ b/Chapter04/src/main/java/com/example/Chapter04/jobs/ChunkJob.java @@ -15,8 +15,32 @@ */ package com.example.Chapter04.jobs; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +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.item.ItemWriter; +import org.springframework.batch.item.support.ListItemReader; +import org.springframework.batch.repeat.CompletionPolicy; +import org.springframework.batch.repeat.policy.CompositeCompletionPolicy; +import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; +import org.springframework.batch.repeat.policy.TimeoutTerminationPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import com.example.Chapter04.batch.LoggingStepStartStopListener; +import com.example.Chapter04.batch.RandomChunkSizePolicy; /** * @author Michael Minella @@ -24,70 +48,80 @@ @EnableBatchProcessing @SpringBootApplication public class ChunkJob { -// -// @Autowired -// private JobBuilderFactory jobBuilderFactory; -// -// @Autowired -// private StepBuilderFactory stepBuilderFactory; -// -// @Bean -// public Job chunkBasedJob() { -// return this.jobBuilderFactory.get("chunkBasedJob") -// .start(chunkStep()) -// .build(); -// } -// -// @Bean -// public Step chunkStep() { -// return this.stepBuilderFactory.get("chunkStep") -//// .chunk(1000) -// .chunk(randomCompletionPolicy()) -// .reader(itemReader()) -// .writer(itemWriter()) -// .listener(new LoggingStepStartStopListener()) -// .build(); -// } -// -// @Bean -// public ListItemReader itemReader() { -// List items = new ArrayList<>(100000); -// -// for (int i = 0; i < 100000; i++) { -// items.add(UUID.randomUUID().toString()); -// } -// -// return new ListItemReader<>(items); -// } -// -// @Bean -// public ItemWriter itemWriter() { -// return items -> { -// for (String item : items) { -// System.out.println(">> current item = " + item); -// } -// }; -// } -// -// @Bean -// public CompletionPolicy completionPolicy() { -// CompositeCompletionPolicy policy = -// new CompositeCompletionPolicy(); -// -// policy.setPolicies( -// new CompletionPolicy[] { -// new TimeoutTerminationPolicy(3), -// new SimpleCompletionPolicy(1000)}); -// -// return policy; -// } -// -// @Bean -// public CompletionPolicy randomCompletionPolicy() { -// return new RandomChunkSizePolicy(); -// } -// -// public static void main(String[] args) { -// SpringApplication.run(ChunkJob.class, args); -// } + + @Autowired + private JobBuilderFactory jobBuilderFactory; + + @Autowired + private StepBuilderFactory stepBuilderFactory; + + @Bean + public Job chunkBasedJob() { + return this.jobBuilderFactory.get("chunkBasedJob") + .start(chunkStep()) + .build(); + } + + @Bean + public Step chunkStep() { + return this.stepBuilderFactory.get("chunkStep") +// .chunk(1000) + .chunk(randomCompletionPolicy()) + .reader(itemReader()) + .writer(itemWriter()) + .listener(new LoggingStepStartStopListener()) + .taskExecutor(taskExecutor(0)) + .build(); + } + + @Bean + @StepScope + public TaskExecutor taskExecutor(@Value("#{jobParameters['poolSize']}") int poolSize) { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(poolSize); + executor.setMaxPoolSize(poolSize); + return executor; + } + + @Bean + public ListItemReader itemReader() { + List items = new ArrayList<>(100000); + + for (int i = 0; i < 100000; i++) { + items.add(UUID.randomUUID().toString()); + } + + return new ListItemReader<>(items); + } + + @Bean + public ItemWriter itemWriter() { + return items -> { + for (String item : items) { + System.out.println(">> current item = " + item); + } + }; + } + + @Bean + public CompletionPolicy completionPolicy() { + CompositeCompletionPolicy policy = + new CompositeCompletionPolicy(); + + policy.setPolicies( + new CompletionPolicy[] { + new TimeoutTerminationPolicy(3), + new SimpleCompletionPolicy(1000)}); + + return policy; + } + + @Bean + public CompletionPolicy randomCompletionPolicy() { + return new RandomChunkSizePolicy(); + } + + public static void main(String[] args) { + SpringApplication.run(ChunkJob.class, new String[] { "poolSize=null" }); + } } diff --git a/Chapter04/src/main/java/com/example/Chapter04/jobs/JobJob.java b/Chapter04/src/main/java/com/example/Chapter04/jobs/JobJob.java index 1a02f6d..18d0d67 100644 --- a/Chapter04/src/main/java/com/example/Chapter04/jobs/JobJob.java +++ b/Chapter04/src/main/java/com/example/Chapter04/jobs/JobJob.java @@ -35,98 +35,98 @@ @SpringBootApplication public class JobJob { - @Autowired - private JobBuilderFactory jobBuilderFactory; - - @Autowired - private StepBuilderFactory stepBuilderFactory; - - @Bean - public Tasklet loadStockFile() { - return (contribution, chunkContext) -> { - System.out.println("The stock file has been loaded"); - return RepeatStatus.FINISHED; - }; - } - - @Bean - public Tasklet loadCustomerFile() { - return (contribution, chunkContext) -> { - System.out.println("The customer file has been loaded"); - return RepeatStatus.FINISHED; - }; - } - - @Bean - public Tasklet updateStart() { - return (contribution, chunkContext) -> { - System.out.println("The start has been updated"); - return RepeatStatus.FINISHED; - }; - } - - @Bean - public Tasklet runBatchTasklet() { - return (contribution, chunkContext) -> { - System.out.println("The batch has been run"); - return RepeatStatus.FINISHED; - }; - } - - @Bean - public Job preProcessingJob() { - return this.jobBuilderFactory.get("preProcessingJob") - .start(loadFileStep()) - .next(loadCustomerStep()) - .next(updateStartStep()) - .build(); - } - - @Bean - public Job conditionalStepLogicJob() { - return this.jobBuilderFactory.get("conditionalStepLogicJob") - .start(intializeBatch()) - .next(runBatch()) - .build(); - } - - @Bean - public Step intializeBatch() { - return this.stepBuilderFactory.get("initalizeBatch") - .job(preProcessingJob()) - .parametersExtractor(new DefaultJobParametersExtractor()) - .build(); - } - - @Bean - public Step loadFileStep() { - return this.stepBuilderFactory.get("loadFileStep") - .tasklet(loadStockFile()) - .build(); - } - - @Bean - public Step loadCustomerStep() { - return this.stepBuilderFactory.get("loadCustomerStep") - .tasklet(loadCustomerFile()) - .build(); - } - - @Bean - public Step updateStartStep() { - return this.stepBuilderFactory.get("updateStartStep") - .tasklet(updateStart()) - .build(); - } - - @Bean - public Step runBatch() { - return this.stepBuilderFactory.get("runBatch") - .tasklet(runBatchTasklet()) - .build(); - } - - public static void main(String[] args) { - SpringApplication.run(HelloWorldJob.class, args); - } +// @Autowired +// private JobBuilderFactory jobBuilderFactory; +// +// @Autowired +// private StepBuilderFactory stepBuilderFactory; +// +// @Bean +// public Tasklet loadStockFile() { +// return (contribution, chunkContext) -> { +// System.out.println("The stock file has been loaded"); +// return RepeatStatus.FINISHED; +// }; +// } +// +// @Bean +// public Tasklet loadCustomerFile() { +// return (contribution, chunkContext) -> { +// System.out.println("The customer file has been loaded"); +// return RepeatStatus.FINISHED; +// }; +// } +// +// @Bean +// public Tasklet updateStart() { +// return (contribution, chunkContext) -> { +// System.out.println("The start has been updated"); +// return RepeatStatus.FINISHED; +// }; +// } +// +// @Bean +// public Tasklet runBatchTasklet() { +// return (contribution, chunkContext) -> { +// System.out.println("The batch has been run"); +// return RepeatStatus.FINISHED; +// }; +// } +// +// @Bean +// public Job preProcessingJob() { +// return this.jobBuilderFactory.get("preProcessingJob") +// .start(loadFileStep()) +// .next(loadCustomerStep()) +// .next(updateStartStep()) +// .build(); +// } +// +// @Bean +// public Job conditionalStepLogicJob() { +// return this.jobBuilderFactory.get("conditionalStepLogicJob") +// .start(intializeBatch()) +// .next(runBatch()) +// .build(); +// } +// +// @Bean +// public Step intializeBatch() { +// return this.stepBuilderFactory.get("initalizeBatch") +// .job(preProcessingJob()) +// .parametersExtractor(new DefaultJobParametersExtractor()) +// .build(); +// } +// +// @Bean +// public Step loadFileStep() { +// return this.stepBuilderFactory.get("loadFileStep") +// .tasklet(loadStockFile()) +// .build(); +// } +// +// @Bean +// public Step loadCustomerStep() { +// return this.stepBuilderFactory.get("loadCustomerStep") +// .tasklet(loadCustomerFile()) +// .build(); +// } +// +// @Bean +// public Step updateStartStep() { +// return this.stepBuilderFactory.get("updateStartStep") +// .tasklet(updateStart()) +// .build(); +// } +// +// @Bean +// public Step runBatch() { +// return this.stepBuilderFactory.get("runBatch") +// .tasklet(runBatchTasklet()) +// .build(); +// } +// +// public static void main(String[] args) { +// SpringApplication.run(HelloWorldJob.class, args); +// } } diff --git a/Chapter04/src/main/resources/application.properties b/Chapter04/src/main/resources/application.properties index d382b4d..3546f83 100644 --- a/Chapter04/src/main/resources/application.properties +++ b/Chapter04/src/main/resources/application.properties @@ -1,8 +1,8 @@ -spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver -spring.datasource.url=jdbc:mysql://localhost:3306/spring_batch -spring.datasource.username=root -spring.datasource.password=p@ssw0rd +#spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver +#spring.datasource.url=jdbc:mysql://localhost:3306/spring_batch +#spring.datasource.username=root +#spring.datasource.password=p@ssw0rd #spring.datasource.schema=schema-mysql.sql #spring.datasource.initialization-mode=always -spring.batch.initialize-schema=always -spring.batch.job.names=conditionalStepLogicJob +#spring.batch.initialize-schema=always +#spring.batch.job.names=conditionalStepLogicJob diff --git a/Chapter04/src/main/resources/application.yml b/Chapter04/src/main/resources/application.yml index fa0c7a2..8ef250b 100644 --- a/Chapter04/src/main/resources/application.yml +++ b/Chapter04/src/main/resources/application.yml @@ -1,9 +1,10 @@ -spring: - datasource: - driverClassName: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/spring_batch - username: root - password: p@ssw0rd - batch: - initialize-schema: always -spring.batch.job.names=conditionalStepLogicJob +#debug: true +#spring: +# datasource: +# driverClassName: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://localhost:3306/spring_batch +# username: root +# password: p@ssw0rd +# batch: +# initialize-schema: always +#spring.batch.job.names=conditionalStepLogicJob