In this tutorials, I ‘ll show you how can we conditionally transition steps from one condition to another condition.
In this example, when Step1() completed successfully, we’re calling step2() and on step2() success we’re calling step3()
StepTransitionConfiguration.java
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class StepTransitionConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.tasklet((contribution, chunkContext) -> {
System.out.println(">> This is step-1");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step step2() {
return stepBuilderFactory.get("step2")
.tasklet((contribution, chunkContext) -> {
System.out.println(">> This is step-2");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step step3() {
return stepBuilderFactory.get("step3")
.tasklet((contribution, chunkContext) -> {
System.out.println(">> This is step-3");
return RepeatStatus.FINISHED;
}).build();
}
// This also works, an alternative shown below
/*@Bean
public Job transitionJobSimpleNext() {
return jobBuilderFactory.get("transitionJobSimpleNext")
.start(step1())
.next(step2())
.next(step3())
.build();
}*/
@Bean
public Job transitionJobSimpleNext() {
return jobBuilderFactory.get("transitionJobSimpleNext")
.start(step1())
.on("COMPLETED").to(step2())
.from(step2()).on("COMPLETED").to(step3())
.from(step3()).end()
.build();
}
/*@Bean
public Job transitionJobSimpleNext() {
return jobBuilderFactory.get("transitionJobSimpleNext")
.start(step1())
.on("COMPLETED").to(step2())
.from(step2()).on("COMPLETED").stopAndRestart(step3())
.from(step3()).end()
.build();
}*/
}
- ****************************************************
In this example, we’ll read the JobParameters and also see how to move from one step to another based on condition.
JobConfiguration.java
@SpringBootApplication
@EnableBatchProcessing
public class JobParamsApplication {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public Step storePackageStep() {
return this.stepBuilderFactory.get("storePackageStep").tasklet((contribution, chunkContext) -> {
System.out.println("Storing the package while the customer address is located.");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step givePackageToCustomerStep() {
return this.stepBuilderFactory.get("givePackageToCustomer").tasklet((contribution, chunkContext) -> {
System.out.println("#### Given the package to the customer.");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step driveToAddressStep() {
boolean GOT_LOST = true;
return this.stepBuilderFactory.get("driveToAddressStep").tasklet((contribution, chunkContext) -> {
System.out.println("#### Successfully arrived at the address.");
if(GOT_LOST) {
throw new RuntimeException("Got lost driving to the address");
}
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step packageItemStep() {
return this.stepBuilderFactory.get("packageItemStep").tasklet((contribution, chunkContext) -> {
String item = chunkContext.getStepContext().getJobParameters().get("item").toString();
String date = chunkContext.getStepContext().getJobParameters().get("run.date").toString();
System.out.println(String.format("#### The %s has been packaged on %s.", item, date));
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Job deliverPackageJob() {
return this.jobBuilderFactory.get("deliverPackageJob")
.incrementer(new RunIdIncrementer())
.start(packageItemStep())
.next(driveToAddressStep())
.on("FAILED").to(storePackageStep())
.from(driveToAddressStep())
.on("*").to(givePackageToCustomerStep())
.end()
.build();
}
public static void main(String[] args) {
SpringApplication.run(JobParamsApplication.class, args);
}
}
Please make sure to change the value of boolean GOT_LOST = true to either true or false.
application.properties
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.platform=mysql
spring.batch.initialize-schema=always