RESOLVED - issue BATCH-1011: Need distinction between "stop" and "end" transitions?
Push JobExecution status update out of the EndState and back into FlowJob (via FlowExecutor).
This commit is contained in:
@@ -19,8 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.support.SimpleFlow;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
||||
@@ -172,10 +171,10 @@ public class FlowParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
|
||||
if (!transitionElementExists) {
|
||||
list.addAll(createTransition(BatchStatus.FAILED, ExitStatus.FAILED.getExitCode(), null, null, stateDef,
|
||||
parserContext, false));
|
||||
list.addAll(createTransition(FlowExecutionStatus.FAILED, FlowExecutionStatus.FAILED.toString(), null, null, stateDef, parserContext, false));
|
||||
if (!hasNextAttribute) {
|
||||
list.addAll(createTransition(BatchStatus.COMPLETED, null, null, null, stateDef, parserContext, false));
|
||||
list.addAll(createTransition(FlowExecutionStatus.COMPLETED, null, null, null, stateDef, parserContext,
|
||||
false));
|
||||
}
|
||||
}
|
||||
else if (hasNextAttribute) {
|
||||
@@ -213,7 +212,7 @@ public class FlowParser extends AbstractSingleBeanDefinitionParser {
|
||||
private static Collection<BeanDefinition> parseTransitionElement(Element transitionElement, String stateId,
|
||||
BeanDefinition stateDef, ParserContext parserContext) {
|
||||
|
||||
BatchStatus batchStatus = getBatchStatusFromEndTransitionName(transitionElement.getNodeName());
|
||||
FlowExecutionStatus batchStatus = getBatchStatusFromEndTransitionName(transitionElement.getNodeName());
|
||||
String onAttribute = transitionElement.getAttribute("on");
|
||||
String nextAttribute = transitionElement.getAttribute("to");
|
||||
String restartAttribute = transitionElement.getAttribute("restart");
|
||||
@@ -243,24 +242,28 @@ public class FlowParser extends AbstractSingleBeanDefinitionParser {
|
||||
* {@link org.springframework.batch.core.job.flow.support.StateTransition}
|
||||
* references
|
||||
*/
|
||||
private static Collection<BeanDefinition> createTransition(BatchStatus batchStatus, String on, String next,
|
||||
private static Collection<BeanDefinition> createTransition(FlowExecutionStatus batchStatus, String on, String next,
|
||||
String exitCode, BeanDefinition stateDef, ParserContext parserContext, boolean abandon) {
|
||||
|
||||
BeanDefinition endState = null;
|
||||
|
||||
// TODO: revise this for clarity
|
||||
if (batchStatus == BatchStatus.STOPPED || batchStatus == BatchStatus.COMPLETED
|
||||
|| batchStatus == BatchStatus.FAILED) {
|
||||
if (batchStatus == FlowExecutionStatus.STOPPED || batchStatus == FlowExecutionStatus.COMPLETED
|
||||
|| batchStatus == FlowExecutionStatus.FAILED) {
|
||||
|
||||
BeanDefinitionBuilder endBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition("org.springframework.batch.core.job.flow.support.state.EndState");
|
||||
endBuilder.addConstructorArgValue(batchStatus);
|
||||
|
||||
boolean exitCodeExists = StringUtils.hasText(exitCode);
|
||||
endBuilder.addConstructorArgValue(exitCodeExists ? new ExitStatus(exitCode)
|
||||
: convertToExitStatus(batchStatus));
|
||||
// Make sure exit code is consistent with status for aggregation
|
||||
// purposes
|
||||
if (exitCodeExists && !exitCode.startsWith(batchStatus.toString())) {
|
||||
exitCode = batchStatus.toString() + (exitCode.contains(" ") ? " " : "_") + exitCode;
|
||||
}
|
||||
endBuilder.addConstructorArgValue(exitCodeExists ? new FlowExecutionStatus(exitCode) : batchStatus);
|
||||
|
||||
String endName = (batchStatus == BatchStatus.STOPPED ? STOP : batchStatus == BatchStatus.FAILED ? FAIL : END)
|
||||
String endName = (batchStatus == FlowExecutionStatus.STOPPED ? STOP
|
||||
: batchStatus == FlowExecutionStatus.FAILED ? FAIL : END)
|
||||
+ (endCounter++);
|
||||
endBuilder.addConstructorArgValue(endName);
|
||||
|
||||
@@ -288,31 +291,18 @@ public class FlowParser extends AbstractSingleBeanDefinitionParser {
|
||||
* @param elementName An end transition element name
|
||||
* @return the BatchStatus corresponding to the transition name
|
||||
*/
|
||||
private static BatchStatus getBatchStatusFromEndTransitionName(String elementName) {
|
||||
private static FlowExecutionStatus getBatchStatusFromEndTransitionName(String elementName) {
|
||||
if (STOP.equals(elementName)) {
|
||||
return BatchStatus.STOPPED;
|
||||
return FlowExecutionStatus.STOPPED;
|
||||
}
|
||||
else if (END.equals(elementName)) {
|
||||
return BatchStatus.COMPLETED;
|
||||
return FlowExecutionStatus.COMPLETED;
|
||||
}
|
||||
else if (FAIL.equals(elementName)) {
|
||||
return BatchStatus.FAILED;
|
||||
return FlowExecutionStatus.FAILED;
|
||||
}
|
||||
else {
|
||||
return BatchStatus.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param batchStatus A BatchStatus
|
||||
* @return the ExitStatus corresponding to the BatchStatus
|
||||
*/
|
||||
private static ExitStatus convertToExitStatus(BatchStatus batchStatus) {
|
||||
if (batchStatus == BatchStatus.FAILED) {
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
else {
|
||||
return new ExitStatus(batchStatus.toString());
|
||||
return FlowExecutionStatus.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,21 @@ public class FlowExecutionStatus implements Comparable<FlowExecutionStatus> {
|
||||
public FlowExecutionStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the status starts with "STOPPED"
|
||||
*/
|
||||
public boolean isStop() {
|
||||
return status.startsWith(STOPPED.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the status starts with "FAILED"
|
||||
*/
|
||||
public boolean isFail() {
|
||||
return status.startsWith(FAILED.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ordering on {@link FlowExecutionStatus} instances by comparing
|
||||
* their statuses.
|
||||
@@ -107,7 +121,7 @@ public class FlowExecutionStatus implements Comparable<FlowExecutionStatus> {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "FlowExecutionStatus: " + status;
|
||||
return status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
|
||||
@@ -32,15 +32,13 @@ import org.springframework.batch.core.repository.JobRestartException;
|
||||
public interface FlowExecutor {
|
||||
|
||||
/**
|
||||
* @param step
|
||||
* a {@link Step} to execute
|
||||
* @param step a {@link Step} to execute
|
||||
* @return the exit status that drives the surrounding {@link Flow}
|
||||
* @throws StartLimitExceededException
|
||||
* @throws JobRestartException
|
||||
* @throws JobInterruptedException
|
||||
*/
|
||||
String executeStep(Step step) throws JobInterruptedException,
|
||||
JobRestartException, StartLimitExceededException;
|
||||
String executeStep(Step step) throws JobInterruptedException, JobRestartException, StartLimitExceededException;
|
||||
|
||||
/**
|
||||
* @return the current {@link JobExecution}
|
||||
@@ -56,29 +54,19 @@ public interface FlowExecutor {
|
||||
* Chance to clean up resources at the end of a flow (whether it completed
|
||||
* successfully or not).
|
||||
*
|
||||
* @param result
|
||||
* the final {@link FlowExecution}
|
||||
* @param result the final {@link FlowExecution}
|
||||
*/
|
||||
void close(FlowExecution result);
|
||||
|
||||
/**
|
||||
* Handle any status changes that might be needed at the start of a state.
|
||||
*/
|
||||
void updateStepExecutionStatus();
|
||||
void abandonStepExecution();
|
||||
|
||||
/**
|
||||
* Push a token onto a stack to indicate that the context is being nested.
|
||||
* Handle any status changes that might be needed in the
|
||||
* {@link JobExecution}.
|
||||
*/
|
||||
void nest();
|
||||
|
||||
/**
|
||||
* Pop a token off a stack to indicate that the context is being un-nested.
|
||||
*/
|
||||
void unnest();
|
||||
|
||||
/**
|
||||
* @return indicate whether the execution context is nested
|
||||
*/
|
||||
boolean isNested();
|
||||
void updateJobExecutionStatus(FlowExecutionStatus status);
|
||||
|
||||
}
|
||||
|
||||
@@ -80,7 +80,8 @@ public class FlowJob extends AbstractJob {
|
||||
protected void doExecute(final JobExecution execution)
|
||||
throws JobExecutionException {
|
||||
try {
|
||||
flow.start(new JobFlowExecutor(execution));
|
||||
JobFlowExecutor executor = new JobFlowExecutor(execution);
|
||||
executor.updateJobExecutionStatus(flow.start(executor).getStatus());
|
||||
} catch (FlowExecutionException e) {
|
||||
if (e.getCause() instanceof JobExecutionException) {
|
||||
throw (JobExecutionException) e.getCause();
|
||||
@@ -100,8 +101,6 @@ public class FlowJob extends AbstractJob {
|
||||
|
||||
private final JobExecution execution;
|
||||
|
||||
private volatile boolean nested = false;
|
||||
|
||||
/**
|
||||
* @param execution
|
||||
*/
|
||||
@@ -118,7 +117,7 @@ public class FlowJob extends AbstractJob {
|
||||
: stepExecution.getExitStatus().getExitCode();
|
||||
}
|
||||
|
||||
public void updateStepExecutionStatus() {
|
||||
public void abandonStepExecution() {
|
||||
StepExecution lastStepExecution = stepExecutionHolder.get();
|
||||
if (lastStepExecution != null
|
||||
&& lastStepExecution.getStatus().isGreaterThan(
|
||||
@@ -127,6 +126,11 @@ public class FlowJob extends AbstractJob {
|
||||
updateStepExecution(lastStepExecution);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateJobExecutionStatus(FlowExecutionStatus status) {
|
||||
execution.setStatus(findBatchStatus(status));
|
||||
execution.setExitStatus(new ExitStatus(status.getStatus()));
|
||||
}
|
||||
|
||||
public JobExecution getJobExecution() {
|
||||
return execution;
|
||||
@@ -140,16 +144,17 @@ public class FlowJob extends AbstractJob {
|
||||
stepExecutionHolder.set(null);
|
||||
}
|
||||
|
||||
public boolean isNested() {
|
||||
return nested;
|
||||
}
|
||||
|
||||
public void nest() {
|
||||
nested = true;
|
||||
}
|
||||
|
||||
public void unnest() {
|
||||
nested = false;
|
||||
/**
|
||||
* @param status
|
||||
* @return
|
||||
*/
|
||||
private BatchStatus findBatchStatus(FlowExecutionStatus status) {
|
||||
for (BatchStatus batchStatus : BatchStatus.values()) {
|
||||
if (status.getStatus().startsWith(batchStatus.toString())) {
|
||||
return batchStatus;
|
||||
}
|
||||
}
|
||||
return BatchStatus.UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,6 @@ public interface JobExecutionDecider {
|
||||
* @param stepExecution the latest step execution (may be null)
|
||||
* @return the exit status code
|
||||
*/
|
||||
String decide(JobExecution jobExecution, StepExecution stepExecution);
|
||||
FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -46,10 +44,12 @@ public interface State {
|
||||
FlowExecutionStatus handle(FlowExecutor executor) throws Exception;
|
||||
|
||||
/**
|
||||
* Validate that the transition attributes are appropriate for this State.
|
||||
* Inquire as to whether a {@link State} is an end state. Implementations
|
||||
* should return false if processing can continue, even if that would
|
||||
* require a restart.
|
||||
*
|
||||
* @param pattern
|
||||
* @param nextState
|
||||
* @return true if this {@link State} is the end of processing
|
||||
*/
|
||||
void validate(String pattern, String nextState);
|
||||
boolean isEndState();
|
||||
|
||||
}
|
||||
|
||||
@@ -100,7 +100,9 @@ public class StateTransition implements Comparable<StateTransition> {
|
||||
}
|
||||
|
||||
Assert.notNull(state, "A state is required for a StateTransition");
|
||||
state.validate(pattern, next);
|
||||
if (state.isEndState() && StringUtils.hasText(next)) {
|
||||
throw new IllegalStateException("End state cannot have next: "+state);
|
||||
}
|
||||
|
||||
this.next = next;
|
||||
this.state = state;
|
||||
|
||||
@@ -38,16 +38,14 @@ public class DecisionState extends AbstractState {
|
||||
|
||||
@Override
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
return new FlowExecutionStatus(decider.decide(executor.getJobExecution(), executor.getStepExecution()));
|
||||
return decider.decide(executor.getJobExecution(), executor.getStepExecution());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.flow.State#isEndState()
|
||||
*/
|
||||
public boolean isEndState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.flow.State#validate(java.lang.String)
|
||||
*/
|
||||
public void validate(String pattern, String nextState) {
|
||||
if (nextState == null) {
|
||||
throw new IllegalStateException("The transition for " + getClass().getSimpleName() + " [" + getName()
|
||||
+ "] requires a 'next' state.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.batch.core.job.flow.support.state;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
@@ -32,40 +30,33 @@ import org.springframework.batch.core.job.flow.State;
|
||||
*/
|
||||
public class EndState extends AbstractState {
|
||||
|
||||
private final BatchStatus status;
|
||||
|
||||
private final ExitStatus exitStatus;
|
||||
private final FlowExecutionStatus status;
|
||||
|
||||
private final boolean abandon;
|
||||
|
||||
/**
|
||||
* @param status The BatchStatus to end with
|
||||
* @param exitStatus The ExitStatus to end with
|
||||
* @param status The {@link FlowExecutionStatus} to end with
|
||||
* @param name The name of the state
|
||||
*/
|
||||
public EndState(BatchStatus status, ExitStatus exitStatus, String name) {
|
||||
this(status, exitStatus, name, false);
|
||||
public EndState(FlowExecutionStatus status, String name) {
|
||||
this(status, name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param status The BatchStatus to end with
|
||||
* @param exitStatus The ExitStatus to end with
|
||||
* @param status The {@link FlowExecutionStatus} to end with
|
||||
* @param name The name of the state
|
||||
* @param abandon flag to indicate that previous step execution can be
|
||||
* marked as abandoned (if there is one)
|
||||
*
|
||||
*/
|
||||
public EndState(BatchStatus status, ExitStatus exitStatus, String name, boolean abandon) {
|
||||
public EndState(FlowExecutionStatus status, String name, boolean abandon) {
|
||||
super(name);
|
||||
this.status = status;
|
||||
this.exitStatus = exitStatus;
|
||||
this.abandon = abandon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link BatchStatus} and {@link ExitStatus} stored. If the
|
||||
* {@link BatchStatus} is {@link BatchStatus#FAILED}, then mark it on the
|
||||
* {@link JobExecution} so that the job will know to stop.
|
||||
* Return the {@link FlowExecutionStatus} stored.
|
||||
*
|
||||
* @see State#handle(FlowExecutor)
|
||||
*/
|
||||
@@ -73,51 +64,41 @@ public class EndState extends AbstractState {
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
JobExecution jobExecution = executor.getJobExecution();
|
||||
synchronized (jobExecution) {
|
||||
if (!jobExecution.getStepExecutions().isEmpty()) {
|
||||
/*
|
||||
* If there are step executions, then we are not at the
|
||||
* beginning of a restart.
|
||||
*/
|
||||
if (!executor.isNested()) {
|
||||
jobExecution.setStatus(status);
|
||||
jobExecution.setExitStatus(exitStatus);
|
||||
}
|
||||
if (status == BatchStatus.STOPPED) {
|
||||
|
||||
if (status.isStop()) {
|
||||
if (!jobExecution.getStepExecutions().isEmpty()) {
|
||||
/*
|
||||
* If there are step executions, then we are not at the
|
||||
* beginning of a restart.
|
||||
*/
|
||||
if (abandon) {
|
||||
/*
|
||||
* Only if instructed to do so upgrade the status of
|
||||
* Only if instructed to do so, upgrade the status of
|
||||
* last step execution so it is not replayed on a
|
||||
* restart...
|
||||
*/
|
||||
executor.updateStepExecutionStatus();
|
||||
executor.abandonStepExecution();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* If we are in flight (not a restart) and we are supposed
|
||||
* to signal a stop, then make sure that happens
|
||||
* irrespective of the exit status.
|
||||
* If we are a stop state and we got this far then it must
|
||||
* be a restart, so return COMPLETED.
|
||||
*/
|
||||
return FlowExecutionStatus.STOPPED;
|
||||
return FlowExecutionStatus.COMPLETED;
|
||||
}
|
||||
}
|
||||
return new FlowExecutionStatus(exitStatus.getExitCode());
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.batch.core.job.flow.State#validate(java.lang.String)
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.flow.State#isEndState()
|
||||
*/
|
||||
public void validate(String pattern, String nextState) {
|
||||
if (status != BatchStatus.STOPPED && nextState != null) {
|
||||
throw new IllegalStateException("The transition for " + getClass().getSimpleName() + " [" + getName()
|
||||
+ "] may not have a 'next' state.");
|
||||
}
|
||||
if (pattern != null) {
|
||||
throw new IllegalStateException("The transition for " + getClass().getSimpleName() + " [" + getName()
|
||||
+ "] may not have a 'pattern'.");
|
||||
}
|
||||
public boolean isEndState() {
|
||||
return !status.isStop();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -127,6 +108,6 @@ public class EndState extends AbstractState {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " status=[" + status + "] exitcode=[" + exitStatus.getExitCode() + "] ";
|
||||
return super.toString() + " status=[" + status + "]";
|
||||
}
|
||||
}
|
||||
@@ -71,10 +71,6 @@ public class SplitState extends AbstractState {
|
||||
@Override
|
||||
public FlowExecutionStatus handle(final FlowExecutor executor) throws Exception {
|
||||
|
||||
try {
|
||||
|
||||
executor.nest();
|
||||
|
||||
// TODO: collect the last StepExecution from the flows as well, so they
|
||||
// can be abandoned if necessary
|
||||
Collection<Future<FlowExecution>> tasks = new ArrayList<Future<FlowExecution>>();
|
||||
@@ -107,22 +103,14 @@ public class SplitState extends AbstractState {
|
||||
|
||||
return aggregator.aggregate(results);
|
||||
|
||||
} finally {
|
||||
executor.unnest();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.batch.core.job.flow.State#validate(java.lang.String)
|
||||
* @see org.springframework.batch.core.job.flow.State#isEndState()
|
||||
*/
|
||||
public void validate(String pattern, String nextState) {
|
||||
if (nextState == null) {
|
||||
throw new IllegalStateException("The transition for " + getClass().getSimpleName() + " [" + getName()
|
||||
+ "] requires a 'next' state.");
|
||||
}
|
||||
public boolean isEndState() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,11 @@ public class StepState extends AbstractState implements StepHolder {
|
||||
|
||||
@Override
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
executor.updateStepExecutionStatus();
|
||||
/*
|
||||
* On starting a new step, possibly upgrade the last execution to make
|
||||
* sure it is abandoned on restart if it failed.
|
||||
*/
|
||||
executor.abandonStepExecution();
|
||||
return new FlowExecutionStatus(executor.executeStep(step));
|
||||
}
|
||||
|
||||
@@ -62,14 +66,12 @@ public class StepState extends AbstractState implements StepHolder {
|
||||
public Step getStep() {
|
||||
return step;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.flow.State#validate(java.lang.String)
|
||||
* @see org.springframework.batch.core.job.flow.State#isEndState()
|
||||
*/
|
||||
public void validate(String pattern, String nextState) {
|
||||
if (nextState == null) {
|
||||
throw new IllegalStateException("The transition for " + getClass().getSimpleName() + " [" + getName()
|
||||
+ "] requires a 'next' state.");
|
||||
}
|
||||
public boolean isEndState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
@@ -34,22 +35,21 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class DecisionJobParserTests {
|
||||
|
||||
|
||||
@Autowired
|
||||
@Qualifier("job")
|
||||
private Job job;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MapJobRepositoryFactoryBean.clear();
|
||||
@@ -63,10 +63,10 @@ public class DecisionJobParserTests {
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
}
|
||||
|
||||
|
||||
public static class TestDecider implements JobExecutionDecider {
|
||||
public String decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
return "FOO";
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
return new FlowExecutionStatus("FOO");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class EndTransitionJobParserTests extends AbstractJobParserTests {
|
||||
assertTrue(stepNamesList.contains("fail"));
|
||||
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals("EARLY TERMINATION (FAIL)", jobExecution.getExitStatus().getExitCode());
|
||||
assertEquals("COMPLETED EARLY TERMINATION", jobExecution.getExitStatus().getExitCode());
|
||||
|
||||
StepExecution stepExecution1 = getStepExecution(jobExecution, "s1");
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution1.getStatus());
|
||||
|
||||
@@ -48,7 +48,7 @@ public class FailTransitionJobParserTests extends AbstractJobParserTests {
|
||||
assertTrue(stepNamesList.contains("fail"));
|
||||
|
||||
assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
|
||||
assertEquals("EARLY TERMINATION (FAIL)", jobExecution.getExitStatus()
|
||||
assertEquals("FAILED EARLY TERMINATION", jobExecution.getExitStatus()
|
||||
.getExitCode());
|
||||
|
||||
StepExecution stepExecution1 = getStepExecution(jobExecution, "s1");
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -73,8 +74,8 @@ public class StopJobParserTests extends AbstractJobParserTests {
|
||||
}
|
||||
|
||||
public static class TestDecider implements JobExecutionDecider {
|
||||
public String decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
return "FOO";
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
return new FlowExecutionStatus("FOO");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,26 +64,20 @@ public class FlowJobTests {
|
||||
factory.afterPropertiesSet();
|
||||
jobRepository = (JobRepository) factory.getObject();
|
||||
job.setJobRepository(jobRepository);
|
||||
jobExecution = jobRepository.createJobExecution("job",
|
||||
new JobParameters());
|
||||
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoSteps() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -97,18 +91,14 @@ public class FlowJobTests {
|
||||
public void testFailedStep() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StateSupport(
|
||||
"step1", FlowExecutionStatus.FAILED), "step2"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StateSupport("step1", FlowExecutionStatus.FAILED),
|
||||
"step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -123,30 +113,24 @@ public class FlowJobTests {
|
||||
public void testFailedStepRestarted() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
State step2State = new StateSupport("step2") {
|
||||
@Override
|
||||
public FlowExecutionStatus handle(FlowExecutor executor)
|
||||
throws Exception {
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
JobExecution jobExecution = executor.getJobExecution();
|
||||
jobExecution.getStepExecutions().add(
|
||||
new StepExecution(getName(), jobExecution));
|
||||
jobExecution.getStepExecutions().add(new StepExecution(getName(), jobExecution));
|
||||
if (fail) {
|
||||
return FlowExecutionStatus.FAILED;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return FlowExecutionStatus.COMPLETED;
|
||||
}
|
||||
}
|
||||
};
|
||||
transitions.add(StateTransition.createStateTransition(step2State,
|
||||
ExitStatus.COMPLETED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(step2State,
|
||||
ExitStatus.FAILED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(step2State, ExitStatus.COMPLETED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(step2State, ExitStatus.FAILED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -155,8 +139,7 @@ public class FlowJobTests {
|
||||
assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus());
|
||||
assertEquals(2, jobExecution.getStepExecutions().size());
|
||||
jobRepository.update(jobExecution);
|
||||
jobExecution = jobRepository.createJobExecution("job",
|
||||
new JobParameters());
|
||||
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
fail = false;
|
||||
job.execute(jobExecution);
|
||||
assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
|
||||
@@ -167,21 +150,15 @@ public class FlowJobTests {
|
||||
public void testStoppingStep() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
State state2 = new StateSupport("step2", FlowExecutionStatus.FAILED);
|
||||
transitions.add(StateTransition.createStateTransition(state2,
|
||||
ExitStatus.FAILED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(state2,
|
||||
ExitStatus.COMPLETED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createStateTransition(new EndState(
|
||||
BatchStatus.STOPPED, ExitStatus.STOPPED, "end0"), "step3"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step3")), "end2"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end2")));
|
||||
transitions.add(StateTransition.createStateTransition(state2, ExitStatus.FAILED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(state2, ExitStatus.COMPLETED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end0"),
|
||||
"step3"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")), "end2"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end2")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -194,20 +171,15 @@ public class FlowJobTests {
|
||||
public void testEndStateStopped() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "end"));
|
||||
transitions.add(StateTransition.createStateTransition(new EndState(
|
||||
BatchStatus.STOPPED, ExitStatus.STOPPED, "end"), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end1")));
|
||||
.createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end"), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -219,20 +191,15 @@ public class FlowJobTests {
|
||||
public void testEndStateFailed() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "end"));
|
||||
transitions.add(StateTransition.createStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end"), "step2"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
|
||||
transitions
|
||||
.add(StateTransition.createStateTransition(new EndState(FlowExecutionStatus.FAILED, "end"), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -245,20 +212,15 @@ public class FlowJobTests {
|
||||
public void testEndStateStoppedWithRestart() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "end"));
|
||||
transitions.add(StateTransition.createStateTransition(new EndState(
|
||||
BatchStatus.STOPPED, ExitStatus.STOPPED, "end"), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end1")));
|
||||
.createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end"), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -268,8 +230,7 @@ public class FlowJobTests {
|
||||
assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
|
||||
jobExecution = jobRepository.createJobExecution("job",
|
||||
new JobParameters());
|
||||
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
|
||||
job.execute(jobExecution);
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
@@ -280,30 +241,21 @@ public class FlowJobTests {
|
||||
public void testBranching() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "COMPLETED", "step3"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end0"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end1")));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step3")),
|
||||
ExitStatus.FAILED.getExitCode(), "end2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step3")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end3"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end2")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end3")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "COMPLETED",
|
||||
"step3"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")), ExitStatus.FAILED
|
||||
.getExitCode(), "end2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end3"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.afterPropertiesSet();
|
||||
@@ -317,10 +269,8 @@ public class FlowJobTests {
|
||||
public void testBasicFlow() throws Throwable {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
flow.setStateTransitions(transitions);
|
||||
job.setFlow(flow);
|
||||
job.execute(jobExecution);
|
||||
@@ -335,40 +285,29 @@ public class FlowJobTests {
|
||||
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
JobExecutionDecider decider = new JobExecutionDecider() {
|
||||
public String decide(JobExecution jobExecution,
|
||||
StepExecution stepExecution) {
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
assertNotNull(stepExecution);
|
||||
return "SWITCH";
|
||||
return new FlowExecutionStatus("SWITCH");
|
||||
}
|
||||
};
|
||||
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "decision"));
|
||||
transitions.add(StateTransition.createStateTransition(
|
||||
new DecisionState(decider, "decision"), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(
|
||||
new DecisionState(decider, "decision"), "SWITCH", "step3"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "decision"));
|
||||
transitions.add(StateTransition.createStateTransition(new DecisionState(decider, "decision"), "step2"));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.FAILED.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end1")));
|
||||
transitions.add(StateTransition
|
||||
.createStateTransition(new StepState(new StubStep("step3")),
|
||||
ExitStatus.FAILED.getExitCode(), "end2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step3")), ExitStatus.COMPLETED.getExitCode(),
|
||||
"end3"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.FAILED, ExitStatus.FAILED, "end2")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end3")));
|
||||
.createStateTransition(new DecisionState(decider, "decision"), "SWITCH", "step3"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end0"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
|
||||
.getExitCode(), "end1"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")), ExitStatus.FAILED
|
||||
.getExitCode(), "end2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")),
|
||||
ExitStatus.COMPLETED.getExitCode(), "end3"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2")));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3")));
|
||||
flow.setStateTransitions(transitions);
|
||||
|
||||
job.setFlow(flow);
|
||||
@@ -387,12 +326,9 @@ public class FlowJobTests {
|
||||
public void testGetStepExists() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
flow.setStateTransitions(transitions);
|
||||
flow.afterPropertiesSet();
|
||||
job.setFlow(flow);
|
||||
@@ -407,12 +343,9 @@ public class FlowJobTests {
|
||||
public void testGetStepNotExists() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
flow.setStateTransitions(transitions);
|
||||
flow.afterPropertiesSet();
|
||||
job.setFlow(flow);
|
||||
@@ -426,12 +359,9 @@ public class FlowJobTests {
|
||||
public void testGetStepNotStepState() throws Exception {
|
||||
SimpleFlow flow = new SimpleFlow("job");
|
||||
List<StateTransition> transitions = new ArrayList<StateTransition>();
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(
|
||||
new StubStep("step2")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(
|
||||
BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end0")));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
|
||||
transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
|
||||
transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
|
||||
flow.setStateTransitions(transitions);
|
||||
flow.afterPropertiesSet();
|
||||
job.setFlow(flow);
|
||||
@@ -451,8 +381,7 @@ public class FlowJobTests {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void execute(StepExecution stepExecution)
|
||||
throws JobInterruptedException {
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException {
|
||||
stepExecution.setStatus(BatchStatus.COMPLETED);
|
||||
stepExecution.setExitStatus(ExitStatus.COMPLETED);
|
||||
jobRepository.update(stepExecution);
|
||||
@@ -465,8 +394,7 @@ public class FlowJobTests {
|
||||
* @param stepName
|
||||
* @return the StepExecution corresponding to the specified step
|
||||
*/
|
||||
private StepExecution getStepExecution(JobExecution jobExecution,
|
||||
String stepName) {
|
||||
private StepExecution getStepExecution(JobExecution jobExecution, String stepName) {
|
||||
for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
|
||||
if (stepExecution.getStepName().equals(stepName)) {
|
||||
return stepExecution;
|
||||
|
||||
@@ -17,13 +17,10 @@ package org.springframework.batch.core.job.flow;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.State;
|
||||
import org.springframework.batch.core.job.flow.support.state.AbstractState;
|
||||
|
||||
/**
|
||||
* Base class for {@link State} implementations.
|
||||
* Base class for {@link State} implementations in test cases.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -49,7 +46,9 @@ public class StateSupport extends AbstractState {
|
||||
}
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public void validate(String pattern, String nextState) {
|
||||
|
||||
public boolean isEndState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.batch.core.StartLimitExceededException;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
|
||||
@@ -31,8 +32,6 @@ import org.springframework.batch.core.repository.JobRestartException;
|
||||
*/
|
||||
public class JobFlowExecutorSupport implements FlowExecutor {
|
||||
|
||||
private volatile boolean nested = false;
|
||||
|
||||
public String executeStep(Step step) throws JobInterruptedException, JobRestartException,
|
||||
StartLimitExceededException {
|
||||
return ExitStatus.COMPLETED.getExitCode();
|
||||
@@ -49,19 +48,10 @@ public class JobFlowExecutorSupport implements FlowExecutor {
|
||||
public void close(FlowExecution result) {
|
||||
}
|
||||
|
||||
public void updateStepExecutionStatus() {
|
||||
public void abandonStepExecution() {
|
||||
}
|
||||
|
||||
public boolean isNested() {
|
||||
return nested;
|
||||
}
|
||||
|
||||
public void nest() {
|
||||
nested= true;
|
||||
}
|
||||
|
||||
public void unnest() {
|
||||
nested = false;
|
||||
|
||||
public void updateJobExecutionStatus(FlowExecutionStatus status) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,11 +20,10 @@ import static org.junit.Assert.assertEquals;
|
||||
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.JobExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.support.JobFlowExecutorSupport;
|
||||
import org.springframework.batch.core.job.flow.support.state.EndState;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -48,7 +47,7 @@ public class EndStateTests {
|
||||
|
||||
BatchStatus status = jobExecution.getStatus();
|
||||
|
||||
EndState state = new EndState(BatchStatus.UNKNOWN, ExitStatus.UNKNOWN, "end");
|
||||
EndState state = new EndState(FlowExecutionStatus.UNKNOWN, "end");
|
||||
state.handle(new JobFlowExecutorSupport() {
|
||||
@Override
|
||||
public JobExecution getJobExecution() {
|
||||
@@ -69,38 +68,15 @@ public class EndStateTests {
|
||||
|
||||
jobExecution.createStepExecution("foo");
|
||||
|
||||
EndState state = new EndState(BatchStatus.UNKNOWN, ExitStatus.UNKNOWN, "end");
|
||||
state.handle(new JobFlowExecutorSupport() {
|
||||
EndState state = new EndState(FlowExecutionStatus.UNKNOWN, "end");
|
||||
FlowExecutionStatus status = state.handle(new JobFlowExecutorSupport() {
|
||||
@Override
|
||||
public JobExecution getJobExecution() {
|
||||
return jobExecution;
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(BatchStatus.UNKNOWN, jobExecution.getStatus());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link EndState#handle(FlowExecutor)}.
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testHandleOngoingAttemptedDowngrade() throws Exception {
|
||||
|
||||
jobExecution.setStatus(BatchStatus.FAILED);
|
||||
jobExecution.createStepExecution("foo");
|
||||
|
||||
EndState state = new EndState(BatchStatus.COMPLETED, ExitStatus.COMPLETED, "end");
|
||||
state.handle(new JobFlowExecutorSupport() {
|
||||
@Override
|
||||
public JobExecution getJobExecution() {
|
||||
return jobExecution;
|
||||
}
|
||||
});
|
||||
|
||||
// An EndState can downgrade a status - if it failed then it can be unfailed
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.UNKNOWN, status);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<job id="job">
|
||||
<step id="s1" ref="step1" next="fail"/>
|
||||
<step id="fail" ref="failingStep">
|
||||
<end on="*" status="EARLY TERMINATION (FAIL)"/>
|
||||
<end on="*" status="COMPLETED EARLY TERMINATION"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<job id="job">
|
||||
<step id="s1" ref="step1" next="fail"/>
|
||||
<step id="fail" ref="failingStep">
|
||||
<fail on="FAILED" status="EARLY TERMINATION (FAIL)"/>
|
||||
<fail on="FAILED" status="FAILED EARLY TERMINATION"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.batch.sample.loopFlow;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
|
||||
/**
|
||||
@@ -37,12 +38,12 @@ public class LimitDecider implements JobExecutionDecider {
|
||||
* @see org.springframework.batch.core.job.flow.support.state.JobExecutionDecider#decide(org.springframework.batch.core.JobExecution,
|
||||
* org.springframework.batch.core.StepExecution)
|
||||
*/
|
||||
public String decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
if (++count >= limit) {
|
||||
return "COMPLETE";
|
||||
return new FlowExecutionStatus("COMPLETE");
|
||||
}
|
||||
else {
|
||||
return "CONTINUE";
|
||||
return new FlowExecutionStatus("CONTINUE");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@ package org.springframework.batch.sample.common;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
|
||||
public class SkipCheckingDecider implements JobExecutionDecider {
|
||||
|
||||
public String decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
|
||||
if (!stepExecution.getExitStatus().getExitCode().equals(
|
||||
ExitStatus.FAILED.getExitCode())
|
||||
&& stepExecution.getSkipCount() > 0) {
|
||||
return "COMPLETED WITH SKIPS";
|
||||
return new FlowExecutionStatus("COMPLETED WITH SKIPS");
|
||||
} else {
|
||||
return ExitStatus.COMPLETED.getExitCode();
|
||||
return new FlowExecutionStatus(ExitStatus.COMPLETED.getExitCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user