From 365fd46744222d732e3e52c8d21e1c3f1e2e2b56 Mon Sep 17 00:00:00 2001 From: dsyer Date: Tue, 17 Feb 2009 13:11:33 +0000 Subject: [PATCH] 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). --- .../core/configuration/xml/FlowParser.java | 52 ++-- .../core/job/flow/FlowExecutionStatus.java | 16 +- .../batch/core/job/flow/FlowExecutor.java | 26 +- .../batch/core/job/flow/FlowJob.java | 33 +- .../core/job/flow/JobExecutionDecider.java | 2 +- .../batch/core/job/flow/State.java | 12 +- .../job/flow/support/StateTransition.java | 4 +- .../job/flow/support/state/DecisionState.java | 18 +- .../core/job/flow/support/state/EndState.java | 77 ++--- .../job/flow/support/state/SplitState.java | 18 +- .../job/flow/support/state/StepState.java | 18 +- .../xml/DecisionJobParserTests.java | 14 +- .../xml/EndTransitionJobParserTests.java | 2 +- .../xml/FailTransitionJobParserTests.java | 2 +- .../configuration/xml/StopJobParserTests.java | 5 +- .../batch/core/job/flow/FlowJobTests.java | 282 +++++++----------- .../batch/core/job/flow/StateSupport.java | 11 +- .../flow/support/JobFlowExecutorSupport.java | 18 +- .../job/flow/support/state/EndStateTests.java | 34 +-- .../EndTransitionJobParserTests-context.xml | 2 +- .../FailTransitionJobParserTests-context.xml | 2 +- .../batch/sample/loopFlow/LimitDecider.java | 7 +- .../sample/common/SkipCheckingDecider.java | 7 +- 23 files changed, 263 insertions(+), 399 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/FlowParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/FlowParser.java index d965ea28f..94246755a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/FlowParser.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/FlowParser.java @@ -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 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 createTransition(BatchStatus batchStatus, String on, String next, + private static Collection 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; } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutionStatus.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutionStatus.java index 2e2ee1f65..b1cebb198 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutionStatus.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutionStatus.java @@ -70,7 +70,21 @@ public class FlowExecutionStatus implements Comparable { 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 { } public String toString() { - return "FlowExecutionStatus: " + status; + return status; } public String getStatus() { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java index 893a54f66..34866a014 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowExecutor.java @@ -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); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java index 0d0212706..f8ba7b97b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/FlowJob.java @@ -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; } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java index 6f476d493..c0ae167fa 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/JobExecutionDecider.java @@ -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); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/State.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/State.java index 862748054..5f6244be4 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/State.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/State.java @@ -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(); + } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java index cfd91a002..1ce9c631a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/StateTransition.java @@ -100,7 +100,9 @@ public class StateTransition implements Comparable { } 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; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/DecisionState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/DecisionState.java index 6f71308f2..5d51179b7 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/DecisionState.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/DecisionState.java @@ -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."); - } - } } \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/EndState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/EndState.java index 51934ad03..c2d0667c9 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/EndState.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/EndState.java @@ -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 + "]"; } } \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java index efa0fe8e7..0ccc8ed39 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/SplitState.java @@ -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> tasks = new ArrayList>(); @@ -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; } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/StepState.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/StepState.java index ec821ffb0..ed49e7972 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/StepState.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/flow/support/state/StepState.java @@ -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; } + } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DecisionJobParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DecisionJobParserTests.java index 08d2e9d61..8fd272709 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DecisionJobParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/DecisionJobParserTests.java @@ -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"); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests.java index 4ca7874fa..694967087 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests.java @@ -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()); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests.java index f3edce80e..e08501ba8 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests.java @@ -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"); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StopJobParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StopJobParserTests.java index 5703b774e..bcbe30528 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StopJobParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StopJobParserTests.java @@ -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"); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java index adbaa3df4..dab1e99e5 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/FlowJobTests.java @@ -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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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 transitions = new ArrayList(); - 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; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/StateSupport.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/StateSupport.java index e87b08d2a..e79eda64b 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/StateSupport.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/StateSupport.java @@ -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; } + } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/JobFlowExecutorSupport.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/JobFlowExecutorSupport.java index 4f104f7ae..c2433ec4f 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/JobFlowExecutorSupport.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/JobFlowExecutorSupport.java @@ -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) { } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/EndStateTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/EndStateTests.java index adac73bd1..d34d6019e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/EndStateTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/flow/support/state/EndStateTests.java @@ -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); } diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests-context.xml index 43b73538a..95c1c9f19 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/EndTransitionJobParserTests-context.xml @@ -11,7 +11,7 @@ - + diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests-context.xml index a163d4432..9a9ca8216 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/FailTransitionJobParserTests-context.xml @@ -11,7 +11,7 @@ - + diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/loopFlow/LimitDecider.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/loopFlow/LimitDecider.java index 33956c953..1663fa6a2 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/loopFlow/LimitDecider.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/loopFlow/LimitDecider.java @@ -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"); } } diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/common/SkipCheckingDecider.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/common/SkipCheckingDecider.java index 7360ca7b5..be69db195 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/common/SkipCheckingDecider.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/common/SkipCheckingDecider.java @@ -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()); } } } \ No newline at end of file