BATCH-1923: add stop() methods to FlowBuilder
This commit is contained in:
@@ -66,10 +66,14 @@ public class FlowBuilder<Q> {
|
||||
|
||||
private EndState completedState;
|
||||
|
||||
private EndState stoppedState;
|
||||
|
||||
private int decisionCounter = 0;
|
||||
|
||||
private int splitCounter = 0;
|
||||
|
||||
private int endCounter = 0;
|
||||
|
||||
private Map<Object, State> states = new HashMap<Object, State>();
|
||||
|
||||
private SimpleFlow flow;
|
||||
@@ -81,6 +85,7 @@ public class FlowBuilder<Q> {
|
||||
this.prefix = name + ".";
|
||||
this.failedState = new EndState(FlowExecutionStatus.FAILED, prefix + "FAILED");
|
||||
this.completedState = new EndState(FlowExecutionStatus.COMPLETED, prefix + "COMPLETED");
|
||||
this.stoppedState = new EndState(FlowExecutionStatus.STOPPED, prefix + "STOPPED");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,10 +330,8 @@ public class FlowBuilder<Q> {
|
||||
for (String to : copy.keySet()) {
|
||||
if (!froms.contains(to)) {
|
||||
currentState = copy.get(to);
|
||||
if (currentState != completedState) {
|
||||
if (!currentState.isEndState()) {
|
||||
addTransition("COMPLETED", completedState);
|
||||
}
|
||||
if (currentState != failedState) {
|
||||
addTransition("*", failedState);
|
||||
}
|
||||
}
|
||||
@@ -337,12 +340,10 @@ public class FlowBuilder<Q> {
|
||||
// Then find the states that do not have a default transition
|
||||
for (String from : copy.keySet()) {
|
||||
currentState = copy.get(from);
|
||||
if (currentState != failedState) {
|
||||
if (!currentState.isEndState()) {
|
||||
if (!hasFail(from)) {
|
||||
addTransition("*", failedState);
|
||||
}
|
||||
}
|
||||
if (currentState != completedState) {
|
||||
if (!hasCompleted(from)) {
|
||||
addTransition("*", completedState);
|
||||
}
|
||||
@@ -373,14 +374,33 @@ public class FlowBuilder<Q> {
|
||||
if (transitions.size() == 1) {
|
||||
transitions.add(StateTransition.createEndStateTransition(failedState));
|
||||
transitions.add(StateTransition.createEndStateTransition(completedState));
|
||||
transitions.add(StateTransition.createEndStateTransition(stoppedState));
|
||||
}
|
||||
if (next.isEndState()) {
|
||||
transitions.add(StateTransition.createEndStateTransition(next));
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
private void stop(String pattern) {
|
||||
addTransition(pattern, stoppedState);
|
||||
}
|
||||
|
||||
private void stop(String pattern, State restart) {
|
||||
EndState next = new EndState(FlowExecutionStatus.STOPPED, "STOPPED", prefix + "stop" + (endCounter++), true);
|
||||
addTransition(pattern, next);
|
||||
currentState = next;
|
||||
addTransition("*", restart);
|
||||
}
|
||||
|
||||
private void end(String pattern) {
|
||||
addTransition(pattern, completedState);
|
||||
}
|
||||
|
||||
private void end(String pattern, String code) {
|
||||
addTransition(pattern, new EndState(FlowExecutionStatus.COMPLETED, code, prefix + "end" + (endCounter++)));
|
||||
}
|
||||
|
||||
private void fail(String pattern) {
|
||||
addTransition(pattern, failedState);
|
||||
}
|
||||
@@ -471,6 +491,52 @@ public class FlowBuilder<Q> {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the successful end of the flow.
|
||||
*
|
||||
* @return a FlowBuilder
|
||||
*/
|
||||
public FlowBuilder<Q> stop() {
|
||||
parent.stop(pattern);
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the flow and provide a flow to start with if the flow is restarted.
|
||||
*
|
||||
* @param flow the flow to restart with
|
||||
* @return a FlowBuilder
|
||||
*/
|
||||
public FlowBuilder<Q> stopAndRestart(Flow flow) {
|
||||
State next = parent.createState(flow);
|
||||
parent.stop(pattern, next);
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the flow and provide a decider to start with if the flow is restarted.
|
||||
*
|
||||
* @param restart a decider to restart with
|
||||
* @return a FlowBuilder
|
||||
*/
|
||||
public FlowBuilder<Q> stopAndRestart(JobExecutionDecider decider) {
|
||||
State next = parent.createState(decider);
|
||||
parent.stop(pattern, next);
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the flow and provide a step to start with if the flow is restarted.
|
||||
*
|
||||
* @param restart the step to restart with
|
||||
* @return a FlowBuilder
|
||||
*/
|
||||
public FlowBuilder<Q> stopAndRestart(Step restart) {
|
||||
State next = parent.createState(restart);
|
||||
parent.stop(pattern, next);
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the successful end of the flow.
|
||||
*
|
||||
@@ -481,6 +547,16 @@ public class FlowBuilder<Q> {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the end of the flow with the status provided.
|
||||
*
|
||||
* @return a FlowBuilder
|
||||
*/
|
||||
public FlowBuilder<Q> end(String status) {
|
||||
parent.end(pattern, status);
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the end of the flow with an error condition.
|
||||
*
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
@@ -54,6 +55,16 @@ public class FlowJobBuilderTests {
|
||||
}
|
||||
};
|
||||
|
||||
private StepSupport fails = new StepSupport("fails") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
stepExecution.upgradeStatus(BatchStatus.FAILED);
|
||||
stepExecution.setExitStatus(ExitStatus.FAILED);
|
||||
jobRepository.update(stepExecution);
|
||||
}
|
||||
};
|
||||
|
||||
private StepSupport step2 = new StepSupport("step2") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
@@ -164,4 +175,41 @@ public class FlowJobBuilderTests {
|
||||
assertEquals(2, execution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildWithCustomEndState() throws Exception {
|
||||
SimpleJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(step1);
|
||||
builder.on("COMPLETED").end("FOO");
|
||||
builder.preventRestart();
|
||||
builder.build().execute(execution);
|
||||
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("FOO", execution.getExitStatus().getExitCode());
|
||||
assertEquals(1, execution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildWithStop() throws Exception {
|
||||
SimpleJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(step1);
|
||||
builder.on("COMPLETED").stop();
|
||||
builder.preventRestart();
|
||||
builder.build().execute(execution);
|
||||
assertEquals(BatchStatus.STOPPED, execution.getStatus());
|
||||
assertEquals("STOPPED", execution.getExitStatus().getExitCode());
|
||||
assertEquals(1, execution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildWithStopAndRestart() throws Exception {
|
||||
SimpleJobBuilder builder = new JobBuilder("flow").repository(jobRepository).start(fails);
|
||||
builder.on("FAILED").stopAndRestart(step2);
|
||||
Job job = builder.build();
|
||||
job.execute(execution);
|
||||
assertEquals(BatchStatus.STOPPED, execution.getStatus());
|
||||
assertEquals(1, execution.getStepExecutions().size());
|
||||
execution = jobRepository.createJobExecution("flow", new JobParameters());
|
||||
job.execute(execution);
|
||||
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals(1, execution.getStepExecutions().size());
|
||||
assertEquals("step2", execution.getStepExecutions().iterator().next().getStepName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user