From cc47fa82d92215fc7e792bc632ea08aa46288a69 Mon Sep 17 00:00:00 2001 From: dsyer Date: Mon, 23 Feb 2009 18:17:52 +0000 Subject: [PATCH] FIXED - issue BATCH-1092: Fix naming conventions for exit status in Changed ExitSTatus aggregation rule so that custom codes come out on top. --- .../batch/core/ExitStatus.java | 14 ++++++------ .../core/configuration/xml/FlowParser.java | 10 ++++----- .../batch/core/job/flow/FlowExecutor.java | 10 +++++++++ .../batch/core/job/flow/FlowJob.java | 13 ++++++++++- .../core/job/flow/support/state/EndState.java | 22 ++++++++++++++----- .../batch/core/ExitStatusTests.java | 6 ++--- .../xml/EndTransitionJobParserTests.java | 2 +- ...ferentResultsFailSecondJobParserTests.java | 5 +++-- .../flow/support/JobFlowExecutorSupport.java | 7 ++++++ .../EndTransitionJobParserTests-context.xml | 2 +- 10 files changed, 64 insertions(+), 27 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/ExitStatus.java b/spring-batch-core/src/main/java/org/springframework/batch/core/ExitStatus.java index 327fad577..19f9b8de0 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/ExitStatus.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/ExitStatus.java @@ -108,14 +108,14 @@ public class ExitStatus implements Serializable, Comparable { * * Severity is defined by the exit code: *
    - *
  • Codes beginning with EXECUTING have severity 0
  • + *
  • Codes beginning with EXECUTING have severity 1
  • *
  • Codes beginning with COMPLETED have severity 2
  • *
  • Codes beginning with NOOP have severity 3
  • - *
  • Codes beginning with INTERRUPTED have severity 4
  • + *
  • Codes beginning with STOPPED have severity 4
  • *
  • Codes beginning with FAILED have severity 5
  • *
  • Codes beginning with UNKNOWN have severity 6
  • *
- * Others have severity 1.
+ * Others have severity 7, so custom exit codes always win.
* * If the input is null just return this. * @@ -153,6 +153,9 @@ public class ExitStatus implements Serializable, Comparable { * @return */ private int severity(ExitStatus status) { + if (status.exitCode.startsWith(EXECUTING.exitCode)) { + return 1; + } if (status.exitCode.startsWith(COMPLETED.exitCode)) { return 2; } @@ -168,10 +171,7 @@ public class ExitStatus implements Serializable, Comparable { if (status.exitCode.startsWith(UNKNOWN.exitCode)) { return 6; } - if (!status.exitCode.startsWith(EXECUTING.exitCode)) { - return 1; - } - return 0; + return 7; } /* 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 0d570c3fe..0e927b58a 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 @@ -255,13 +255,11 @@ public class FlowParser extends AbstractSingleBeanDefinitionParser { .genericBeanDefinition("org.springframework.batch.core.job.flow.support.state.EndState"); boolean exitCodeExists = StringUtils.hasText(exitCode); - // Make sure exit code is consistent with status for aggregation - // purposes - if (exitCodeExists && !exitCode.startsWith(status.getName())) { - exitCode = status.getName() + (exitCode.contains(" ") ? " " : "_") + exitCode; - } - endBuilder.addConstructorArgValue(exitCodeExists ? new FlowExecutionStatus(exitCode) : status); + endBuilder.addConstructorArgValue(status); + + endBuilder.addConstructorArgValue(exitCodeExists ? exitCode : status.getName()); + String endName = (status == FlowExecutionStatus.STOPPED ? STOP : status == FlowExecutionStatus.FAILED ? FAIL : END) + (endCounter++); 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 34866a014..d4a8fe6ba 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 @@ -69,4 +69,14 @@ public interface FlowExecutor { */ void updateJobExecutionStatus(FlowExecutionStatus status); + /** + * @return true if the flow is at the beginning of a restart + */ + boolean isRestart(); + + /** + * @param code the label for the exit status when a flow or sub-flow ends + */ + void addExitStatus(String code); + } 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 720ba5a84..a94ffbc94 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 @@ -101,6 +101,8 @@ public class FlowJob extends AbstractJob { private final JobExecution execution; + private ExitStatus exitStatus = ExitStatus.EXECUTING; + /** * @param execution */ @@ -129,7 +131,8 @@ public class FlowJob extends AbstractJob { public void updateJobExecutionStatus(FlowExecutionStatus status) { execution.setStatus(findBatchStatus(status)); - execution.setExitStatus(new ExitStatus(status.getName())); + exitStatus = exitStatus.and(new ExitStatus(status.getName())); + execution.setExitStatus(exitStatus); } public JobExecution getJobExecution() { @@ -143,6 +146,14 @@ public class FlowJob extends AbstractJob { public void close(FlowExecution result) { stepExecutionHolder.set(null); } + + public boolean isRestart() { + return execution.getStepExecutions().isEmpty(); + } + + public void addExitStatus(String code) { + exitStatus = exitStatus.and(new ExitStatus(code)); + } /** * @param status 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 c2d0667c9..fe7ed0fe6 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,7 +16,6 @@ package org.springframework.batch.core.job.flow.support.state; -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.State; @@ -34,12 +33,22 @@ public class EndState extends AbstractState { private final boolean abandon; + private final String code; + /** * @param status The {@link FlowExecutionStatus} to end with * @param name The name of the state */ public EndState(FlowExecutionStatus status, String name) { - this(status, name, false); + this(status, status.getName(), name); + } + + /** + * @param status The {@link FlowExecutionStatus} to end with + * @param name The name of the state + */ + public EndState(FlowExecutionStatus status, String code, String name) { + this(status, code, name, false); } /** @@ -49,9 +58,10 @@ public class EndState extends AbstractState { * marked as abandoned (if there is one) * */ - public EndState(FlowExecutionStatus status, String name, boolean abandon) { + public EndState(FlowExecutionStatus status, String code, String name, boolean abandon) { super(name); this.status = status; + this.code = code; this.abandon = abandon; } @@ -62,11 +72,10 @@ public class EndState extends AbstractState { */ @Override public FlowExecutionStatus handle(FlowExecutor executor) throws Exception { - JobExecution jobExecution = executor.getJobExecution(); - synchronized (jobExecution) { + synchronized (executor) { if (status.isStop()) { - if (!jobExecution.getStepExecutions().isEmpty()) { + if (!executor.isRestart()) { /* * If there are step executions, then we are not at the * beginning of a restart. @@ -89,6 +98,7 @@ public class EndState extends AbstractState { } } + executor.addExitStatus(code); return status; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/ExitStatusTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/ExitStatusTests.java index 79720942d..2731976b6 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/ExitStatusTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/ExitStatusTests.java @@ -134,7 +134,8 @@ public class ExitStatusTests { */ @Test public void testAndExitStatusWhenCustomCompletedAddedToCompleted() { - assertEquals("COMPLETED_CUSTOM", ExitStatus.COMPLETED.and(ExitStatus.EXECUTING.replaceExitCode("COMPLETED_CUSTOM")).getExitCode()); + assertEquals("COMPLETED_CUSTOM", ExitStatus.COMPLETED.and( + ExitStatus.EXECUTING.replaceExitCode("COMPLETED_CUSTOM")).getExitCode()); } /** @@ -155,8 +156,7 @@ public class ExitStatusTests { */ @Test public void testAndExitStatusWhenCustomContinuableAddedToFinished() { - assertEquals(ExitStatus.COMPLETED.getExitCode(), ExitStatus.COMPLETED.and( - ExitStatus.EXECUTING.replaceExitCode("CUSTOM")).getExitCode()); + assertEquals("CUSTOM", ExitStatus.COMPLETED.and(ExitStatus.EXECUTING.replaceExitCode("CUSTOM")).getExitCode()); } @Test 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 694967087..f46a2c90d 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("COMPLETED EARLY TERMINATION", jobExecution.getExitStatus().getExitCode()); + assertEquals("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/SplitDifferentResultsFailSecondJobParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/SplitDifferentResultsFailSecondJobParserTests.java index 975ed2dbf..e34f87238 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/SplitDifferentResultsFailSecondJobParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/SplitDifferentResultsFailSecondJobParserTests.java @@ -40,13 +40,14 @@ public class SplitDifferentResultsFailSecondJobParserTests extends AbstractJobPa JobExecution jobExecution = createJobExecution(); job.execute(jobExecution); - assertEquals("Wrong step anmes: "+stepNamesList, 3, stepNamesList.size()); + assertEquals("Wrong step names: "+stepNamesList, 3, stepNamesList.size()); assertTrue(stepNamesList.contains("s1")); assertTrue(stepNamesList.contains("fail")); assertTrue(stepNamesList.contains("s3")); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); - assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + // You can't suppress a FAILED exit status + assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus()); StepExecution stepExecution1 = getStepExecution(jobExecution, "s1"); assertEquals(BatchStatus.COMPLETED, stepExecution1.getStatus()); 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 c2433ec4f..24658b2c7 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 @@ -53,5 +53,12 @@ public class JobFlowExecutorSupport implements FlowExecutor { public void updateJobExecutionStatus(FlowExecutionStatus status) { } + + public boolean isRestart() { + return false; + } + + public void addExitStatus(String code) { + } } 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 ac7e1b16d..931b7cce7 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 @@ - +