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