From f47e8382d25db436fed4d874fa5e12d61313f9a9 Mon Sep 17 00:00:00 2001 From: dsyer Date: Sun, 1 Feb 2009 09:56:22 +0000 Subject: [PATCH] RESOLVED BATCH-1030: Added BatchStatus.INCOMPLETE. --- .../batch/core/BatchStatus.java | 19 +++++++++++++++---- .../batch/core/job/AbstractJob.java | 13 ++++++++++++- .../batch/core/job/flow/FlowJob.java | 6 ++++++ .../batch/core/job/flow/FlowJobTests.java | 3 +-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java b/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java index 71b56df69..86f8c7915 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java @@ -32,9 +32,11 @@ public enum BatchStatus { * execution are COMPLETED will the aggregate status be COMPLETED. A running * execution is expected to move from STARTING to STARTED to COMPLETED * (through the order defined by {@link #upgradeTo(BatchStatus)}). Higher - * values than STARTED signify more serious failure. + * values than STARTED signify more serious failure. INCOMPLETE is used for + * steps that have finished processing, but were not successful, and where + * they should be skipped on a restart (so FAILED is the wrong status). */ - COMPLETED, STARTING, STARTED, FAILED, STOPPING, STOPPED, UNKNOWN; + INCOMPLETE, COMPLETED, STARTING, STARTED, FAILED, STOPPING, STOPPED, UNKNOWN; public static BatchStatus max(BatchStatus status1, BatchStatus status2) { if (status1.isLessThan(status2)) { @@ -57,12 +59,13 @@ public enum BatchStatus { } /** - * Convenience method to decide if a status indicates execution was unsuccessful. + * Convenience method to decide if a status indicates execution was + * unsuccessful. * * @return true if the status is FAILED or greater */ public boolean isUnsuccessful() { - return this==FAILED || this.isGreaterThan(FAILED); + return this == FAILED || this.isGreaterThan(FAILED); } /** @@ -104,4 +107,12 @@ public enum BatchStatus { return this.compareTo(other) < 0; } + /** + * @param other a status value to compare + * @return true if this is less than other + */ + public boolean isLessThanOrEqualTo(BatchStatus other) { + return this.compareTo(other) <= 0; + } + } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java b/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java index 8e4b4b9c5..71222968a 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java @@ -339,6 +339,17 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea } + /** + * Convenience method for subclasses so they can change the state of a + * {@link StepExecution} if necessary. Use with care (and not at all + * preferably) and only before or after a step is executed. + * + * @param stepExecution + */ + protected void updateStepExecution(StepExecution stepExecution) { + jobRepository.update(stepExecution); + } + /** * Given a step and configuration, return true if the step should start, * false if it should not, and throw an exception if the job should finish. @@ -368,7 +379,7 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea + "so it may be dangerous to proceed. " + "Manual intervention is probably necessary."); } - if (stepStatus == BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) { + if (stepStatus.isLessThanOrEqualTo(BatchStatus.COMPLETED) && step.isAllowStartIfComplete() == false) { // step is complete, false should be returned, indicating that the // step should not be started return false; 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 48f797b5c..3bb7f7c7e 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 @@ -15,6 +15,7 @@ */ package org.springframework.batch.core.job.flow; +import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionException; import org.springframework.batch.core.JobInterruptedException; @@ -142,6 +143,11 @@ public class FlowJob extends AbstractJob { } public String executeStep(Step step) throws JobInterruptedException, JobRestartException, StartLimitExceededException { + StepExecution lastStepExecution = stepExecutionHolder.get(); + if (lastStepExecution!=null && lastStepExecution.getStatus()==BatchStatus.FAILED) { + lastStepExecution.setStatus(BatchStatus.INCOMPLETE); + updateStepExecution(lastStepExecution); + } StepExecution stepExecution = handleStep(step, execution); stepExecutionHolder.set(stepExecution); return stepExecution==null ? FlowExecution.COMPLETED : stepExecution.getExitStatus().getExitCode(); 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 50d0f50ea..46ad4a501 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 @@ -143,8 +143,7 @@ public class FlowJobTests { fail = false; job.execute(jobExecution); assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); - // TODO: fix this (BATCH-1030) - // assertEquals(1, jobExecution.getStepExecutions().size()); + assertEquals(1, jobExecution.getStepExecutions().size()); } @Test