From 3fe3b7fc5d0719ef3a83a74a71aa1e3c85c0712e Mon Sep 17 00:00:00 2001 From: Kim Seon Woo Date: Thu, 3 Aug 2023 23:37:31 +0900 Subject: [PATCH] Add ability to start a job flow with a decider Resolves #4411 --- .../batch/core/job/builder/FlowJobBuilder.java | 13 ++++++++++++- .../batch/core/job/builder/JobBuilder.java | 14 ++++++++++++-- .../core/job/builder/FlowJobBuilderTests.java | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowJobBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowJobBuilder.java index 883f35c1a8..86fb466609 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowJobBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowJobBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2011 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.job.flow.Flow; import org.springframework.batch.core.job.flow.FlowJob; +import org.springframework.batch.core.job.flow.JobExecutionDecider; import org.springframework.batch.core.step.builder.StepBuilderException; /** @@ -61,6 +62,16 @@ public JobFlowBuilder start(Step step) { return new JobFlowBuilder(this, step); } + /** + * Start a job with this decider, but expect to transition from there to other flows + * or steps. + * @param decider the decider to start with + * @return a builder to enable fluent chaining + */ + public JobFlowBuilder start(JobExecutionDecider decider) { + return new JobFlowBuilder(this, decider); + } + /** * Provide a single flow to execute as the job. * @param flow the flow to execute diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java index 1e8b8ceec7..7b9b8499bc 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilder.java @@ -17,6 +17,7 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.job.flow.Flow; +import org.springframework.batch.core.job.flow.JobExecutionDecider; import org.springframework.batch.core.repository.JobRepository; /** @@ -61,16 +62,25 @@ public SimpleJobBuilder start(Step step) { /** * Create a new job builder that will execute a flow. * @param flow a flow to execute - * @return a {@link SimpleJobBuilder} + * @return a {@link JobFlowBuilder} */ public JobFlowBuilder start(Flow flow) { return new FlowJobBuilder(this).start(flow); } + /** + * Create a new job builder that will start with a decider. + * @param decider a decider to start with + * @return a {@link JobFlowBuilder} + */ + public JobFlowBuilder start(JobExecutionDecider decider) { + return new FlowJobBuilder(this).start(decider); + } + /** * Create a new job builder that will execute a step or sequence of steps. * @param step a step to execute - * @return a {@link SimpleJobBuilder} + * @return a {@link JobFlowBuilder} */ public JobFlowBuilder flow(Step step) { return new FlowJobBuilder(this).start(step); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java index 6e34807efd..6cdf87deaf 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java @@ -235,6 +235,24 @@ public FlowExecutionStatus decide(JobExecution jobExecution, @Nullable StepExecu assertEquals(2, execution.getStepExecutions().size()); } + @Test + void testBuildWithDeciderAtStart() { + JobExecutionDecider decider = new JobExecutionDecider() { + private int count = 0; + + @Override + public FlowExecutionStatus decide(JobExecution jobExecution, @Nullable StepExecution stepExecution) { + count++; + return count < 2 ? new FlowExecutionStatus("ONGOING") : FlowExecutionStatus.COMPLETED; + } + }; + JobFlowBuilder builder = new JobBuilder("flow", jobRepository).start(decider); + builder.on("COMPLETED").end().from(decider).on("*").to(step1).end(); + builder.build().preventRestart().build().execute(execution); + assertEquals(BatchStatus.COMPLETED, execution.getStatus()); + assertEquals(1, execution.getStepExecutions().size()); + } + @Test void testBuildWithIntermediateSimpleJob() { SimpleJobBuilder builder = new JobBuilder("flow", jobRepository).start(step1);