FIXED - issue BATCH-1092: Fix naming conventions for exit status in <end/>

Changed ExitSTatus aggregation rule so that custom codes come out on top.
This commit is contained in:
dsyer
2009-02-23 18:17:52 +00:00
parent 6d171f2884
commit cc47fa82d9
10 changed files with 64 additions and 27 deletions

View File

@@ -108,14 +108,14 @@ public class ExitStatus implements Serializable, Comparable<ExitStatus> {
*
* Severity is defined by the exit code:
* <ul>
* <li>Codes beginning with EXECUTING have severity 0</li>
* <li>Codes beginning with EXECUTING have severity 1</li>
* <li>Codes beginning with COMPLETED have severity 2</li>
* <li>Codes beginning with NOOP have severity 3</li>
* <li>Codes beginning with INTERRUPTED have severity 4</li>
* <li>Codes beginning with STOPPED have severity 4</li>
* <li>Codes beginning with FAILED have severity 5</li>
* <li>Codes beginning with UNKNOWN have severity 6</li>
* </ul>
* Others have severity 1.<br/>
* Others have severity 7, so custom exit codes always win.<br/>
*
* If the input is null just return this.
*
@@ -153,6 +153,9 @@ public class ExitStatus implements Serializable, Comparable<ExitStatus> {
* @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<ExitStatus> {
if (status.exitCode.startsWith(UNKNOWN.exitCode)) {
return 6;
}
if (!status.exitCode.startsWith(EXECUTING.exitCode)) {
return 1;
}
return 0;
return 7;
}
/*

View File

@@ -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++);

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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());

View File

@@ -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());

View File

@@ -53,5 +53,12 @@ public class JobFlowExecutorSupport implements FlowExecutor {
public void updateJobExecutionStatus(FlowExecutionStatus status) {
}
public boolean isRestart() {
return false;
}
public void addExitStatus(String code) {
}
}

View File

@@ -11,7 +11,7 @@
<job id="job">
<step id="s1" ref="step1" next="fail"/>
<step id="fail" ref="failingStep">
<end on="*" exit-code="COMPLETED EARLY TERMINATION"/>
<end on="*" exit-code="EARLY TERMINATION"/>
</step>
</job>