Skip to content

Commit 32694a5

Browse files
mminellafmbenhassine
authored andcommitted
Added comparitor for state transitions when using java config
Spring Batch orders the transitions as it goes from state to state based on specificity. The XML configuration has always had this functionality. However, when creating the JSR-352 implementation, the mechanism for which this occured was refactored. That occured at about the same time as the java builders were introduced. Because of this crossing of paths, the java configuration option for defining jobs has never correctly sorted the transitions. This PR applys the sorting algorithm to the java configuration, making XML and java configuration behave the same. Resolves #3638 (cherry picked from commit 8e8f9c8)
1 parent 277963b commit 32694a5

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowBuilder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2013 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
3131
import org.springframework.batch.core.job.flow.JobExecutionDecider;
3232
import org.springframework.batch.core.job.flow.State;
33+
import org.springframework.batch.core.job.flow.support.DefaultStateTransitionComparator;
3334
import org.springframework.batch.core.job.flow.support.SimpleFlow;
3435
import org.springframework.batch.core.job.flow.support.StateTransition;
3536
import org.springframework.batch.core.job.flow.support.state.DecisionState;
@@ -44,6 +45,7 @@
4445
* conditional transitions that depend on the exit status of the previous step.
4546
*
4647
* @author Dave Syer
48+
* @author Michael Minella
4749
*
4850
* @since 2.2
4951
*
@@ -244,6 +246,7 @@ protected Flow flow() {
244246
}
245247
addDanglingEndStates();
246248
flow.setStateTransitions(transitions);
249+
flow.setStateTransitionComparator(new DefaultStateTransitionComparator());
247250
dirty = false;
248251
return flow;
249252
}

spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowBuilderTests.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2013 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,21 +15,29 @@
1515
*/
1616
package org.springframework.batch.core.job.builder;
1717

18+
import java.util.Iterator;
19+
1820
import org.junit.Test;
21+
22+
import org.springframework.batch.core.ExitStatus;
1923
import org.springframework.batch.core.JobExecution;
2024
import org.springframework.batch.core.JobInterruptedException;
2125
import org.springframework.batch.core.JobParameters;
2226
import org.springframework.batch.core.StepExecution;
2327
import org.springframework.batch.core.UnexpectedJobExecutionException;
2428
import org.springframework.batch.core.job.SimpleStepHandler;
2529
import org.springframework.batch.core.job.flow.Flow;
30+
import org.springframework.batch.core.job.flow.FlowExecution;
2631
import org.springframework.batch.core.job.flow.JobFlowExecutor;
2732
import org.springframework.batch.core.repository.JobRepository;
2833
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
2934
import org.springframework.batch.core.step.StepSupport;
3035

36+
import static org.junit.Assert.assertEquals;
37+
3138
/**
3239
* @author Dave Syer
40+
* @author Michael Minella
3341
*
3442
*/
3543
public class FlowBuilderTests {
@@ -47,4 +55,43 @@ public void execute(StepExecution stepExecution) throws JobInterruptedException,
4755
}).end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution));
4856
}
4957

58+
@Test
59+
public void testTransitionOrdering() throws Exception {
60+
FlowBuilder<Flow> builder = new FlowBuilder<>("transitionsFlow");
61+
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
62+
JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters());
63+
64+
StepSupport stepA = new StepSupport("stepA") {
65+
@Override
66+
public void execute(StepExecution stepExecution) throws JobInterruptedException,
67+
UnexpectedJobExecutionException {
68+
stepExecution.setExitStatus(new ExitStatus("FAILED"));
69+
}
70+
};
71+
72+
StepSupport stepB = new StepSupport("stepB") {
73+
@Override
74+
public void execute(StepExecution stepExecution) throws JobInterruptedException,
75+
UnexpectedJobExecutionException {
76+
}
77+
};
78+
79+
StepSupport stepC = new StepSupport("stepC") {
80+
@Override
81+
public void execute(StepExecution stepExecution) throws JobInterruptedException,
82+
UnexpectedJobExecutionException {
83+
}
84+
};
85+
86+
FlowExecution flowExecution = builder.start(stepA)
87+
.on("*").to(stepB)
88+
.from(stepA).on("FAILED").to(stepC)
89+
.end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution));
90+
91+
Iterator<StepExecution> stepExecutions = execution.getStepExecutions().iterator();
92+
StepExecution stepExecutionA = stepExecutions.next();
93+
assertEquals(stepExecutionA.getStepName(), "stepA");
94+
StepExecution stepExecutionC = stepExecutions.next();
95+
assertEquals(stepExecutionC.getStepName(), "stepC");
96+
}
5097
}

0 commit comments

Comments
 (0)