BATCH-677: tidied up some loose ends with BatchStatus (e.g. PAUSED->WAITING).
This commit is contained in:
@@ -26,21 +26,82 @@ package org.springframework.batch.core;
|
||||
public enum BatchStatus {
|
||||
|
||||
/**
|
||||
* The order of the status values is significant. An execution is expected
|
||||
* to move up from lowest to highest, hopefully stopping at COMPLETED. After
|
||||
* COMPLETED, higher values signify more serious failure.
|
||||
* The order of the status values is significant because it can be used to
|
||||
* aggregate a set of status values - the result should be the maximum
|
||||
* value. Since COMPLETED is first in the order, only if all elements of an
|
||||
* 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.
|
||||
*/
|
||||
STARTING, STARTED, COMPLETED, PAUSED, FAILED, STOPPING, STOPPED, UNKNOWN;
|
||||
COMPLETED, STARTING, WAITING, STARTED, FAILED, STOPPING, STOPPED, UNKNOWN;
|
||||
|
||||
public static BatchStatus max(BatchStatus status1, BatchStatus status2) {
|
||||
if (status1.compareTo(status2) < 0) {
|
||||
if (status1.isLessThan(status2)) {
|
||||
return status2;
|
||||
}
|
||||
if (status1.compareTo(status2) > 0) {
|
||||
if (status1.isGreaterThan(status2)) {
|
||||
return status1;
|
||||
}
|
||||
else
|
||||
return status1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to decide if a status indicates work is in progress.
|
||||
*
|
||||
* @return true if the status is STARTING, STARTED or WAITING
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return this == STARTING || this == STARTED || this == WAITING;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to move status values through their logical progression, and
|
||||
* override less severe failures with more severe ones. This value is
|
||||
* compared with the parameter and the one that has higher priority is
|
||||
* returned. If both are STARTED or less than the value returned is the
|
||||
* largest in the sequence STARTING, STARTED, COMPLETED. Otherwise the value
|
||||
* returned is the maximum of the two.
|
||||
*
|
||||
* @param other another status to compare to
|
||||
* @return either this or the other status depending on their priority
|
||||
*/
|
||||
public BatchStatus upgradeTo(BatchStatus other) {
|
||||
if (isGreaterThan(STARTED) || other.isGreaterThan(STARTED)) {
|
||||
return max(this, other);
|
||||
}
|
||||
// Both less than or equal to STARTED
|
||||
if (this == COMPLETED)
|
||||
return COMPLETED;
|
||||
if (other == COMPLETED)
|
||||
return COMPLETED;
|
||||
return max(this, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param other a status value to compare
|
||||
* @return true if this is greater than other
|
||||
*/
|
||||
public boolean isGreaterThan(BatchStatus other) {
|
||||
return this.compareTo(other) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param other a status value to compare
|
||||
* @return true if this is less than other
|
||||
*/
|
||||
public boolean isLessThan(BatchStatus other) {
|
||||
return this.compareTo(other) < 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -121,9 +121,7 @@ public class JobExecution extends Entity {
|
||||
* @param status the new status value
|
||||
*/
|
||||
public void upgradeStatus(BatchStatus status) {
|
||||
if (status.compareTo(this.status) > 0) {
|
||||
this.status = status;
|
||||
}
|
||||
this.status = this.status.upgradeTo(status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,23 +209,26 @@ public class JobExecution extends Entity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal that this job execution wishes to be paused. Uses
|
||||
* {@link #upgradeStatus(BatchStatus)} so that a failed execution stays
|
||||
* failed.
|
||||
* Signal that this job execution wishes to wait for work to complete, and
|
||||
* no more processing will take place on the current thread. A failed
|
||||
* execution stays failed.
|
||||
*/
|
||||
public void pause() {
|
||||
upgradeStatus(BatchStatus.PAUSED);
|
||||
public void pauseAndWait() {
|
||||
if (!status.isUnsuccessful()) {
|
||||
status = BatchStatus.WAITING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the {@link JobExecution} has been paused.
|
||||
* Test if the {@link JobExecution} has been paused and is waiting for work
|
||||
* to be done.
|
||||
*
|
||||
* @see #pause()
|
||||
* @see #pauseAndWait()
|
||||
*
|
||||
* @return true if this instance is paused
|
||||
* @return true if this instance is waiting
|
||||
*/
|
||||
public boolean isPaused() {
|
||||
return status == BatchStatus.PAUSED;
|
||||
public boolean isWaiting() {
|
||||
return status == BatchStatus.WAITING;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,7 +53,7 @@ public class StepExecution extends Entity {
|
||||
private volatile int rollbackCount = 0;
|
||||
|
||||
private volatile int readSkipCount = 0;
|
||||
|
||||
|
||||
private volatile int processSkipCount = 0;
|
||||
|
||||
private volatile int writeSkipCount = 0;
|
||||
@@ -71,7 +71,7 @@ public class StepExecution extends Entity {
|
||||
private volatile boolean terminateOnly;
|
||||
|
||||
private volatile int filterCount;
|
||||
|
||||
|
||||
private transient volatile List<Throwable> failureExceptions = new ArrayList<Throwable>();
|
||||
|
||||
/**
|
||||
@@ -155,7 +155,7 @@ public class StepExecution extends Entity {
|
||||
public void setEndTime(Date endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current number of items read for this execution
|
||||
*
|
||||
@@ -209,10 +209,11 @@ public class StepExecution extends Entity {
|
||||
public int getFilterCount() {
|
||||
return filterCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Public setter for the number of items filtered out of this execution.
|
||||
* @param filterCount the number of items filtered out of this execution to set
|
||||
* @param filterCount the number of items filtered out of this execution to
|
||||
* set
|
||||
*/
|
||||
public void setFilterCount(int filterCount) {
|
||||
this.filterCount = filterCount;
|
||||
@@ -261,6 +262,40 @@ public class StepExecution extends Entity {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade the status field if the provided value is greater than the
|
||||
* existing one. Clients using this method to set the status can be sure
|
||||
* that they don't overwrite a failed status with an successful one.
|
||||
*
|
||||
* @param status the new status value
|
||||
*/
|
||||
public void upgradeStatus(BatchStatus status) {
|
||||
this.status = this.status.upgradeTo(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal that this job execution wishes to wait for work to complete, and
|
||||
* no more processing will take place on the current thread. A failed
|
||||
* execution stays failed.
|
||||
*/
|
||||
public void pauseAndWait() {
|
||||
if (!status.isUnsuccessful()) {
|
||||
status = BatchStatus.WAITING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the {@link JobExecution} has been paused and is waiting for work
|
||||
* to be done.
|
||||
*
|
||||
* @see #pauseAndWait()
|
||||
*
|
||||
* @return true if this instance is waiting
|
||||
*/
|
||||
public boolean isWaiting() {
|
||||
return status == BatchStatus.WAITING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the step
|
||||
*/
|
||||
@@ -410,7 +445,7 @@ public class StepExecution extends Entity {
|
||||
public void setWriteSkipCount(int writeSkipCount) {
|
||||
this.writeSkipCount = writeSkipCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the number of records skipped during processing
|
||||
*/
|
||||
@@ -442,12 +477,12 @@ public class StepExecution extends Entity {
|
||||
public void setLastUpdated(Date lastUpdated) {
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
||||
|
||||
public List<Throwable> getFailureExceptions() {
|
||||
return failureExceptions;
|
||||
}
|
||||
|
||||
public void addFailureException(Throwable throwable){
|
||||
|
||||
public void addFailureException(Throwable throwable) {
|
||||
this.failureExceptions.add(throwable);
|
||||
}
|
||||
|
||||
@@ -470,7 +505,8 @@ public class StepExecution extends Entity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialise and ensure transient fields are re-instantiated when read back
|
||||
* Deserialise and ensure transient fields are re-instantiated when read
|
||||
* back
|
||||
*/
|
||||
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
@@ -490,9 +526,10 @@ public class StepExecution extends Entity {
|
||||
|
||||
public String toString() {
|
||||
return super.toString()
|
||||
+ String.format(", name=%s, status=%s, exitStatus=%s, readCount=%d, filterCount=%d, writeCount=%d readSkipCount=%d, writeSkipCount=%d"
|
||||
+ ", commitCount=%d, rollbackCount=%d", stepName, status, exitStatus, readCount, filterCount, writeCount, readSkipCount, writeSkipCount,
|
||||
commitCount, rollbackCount);
|
||||
+ String.format(
|
||||
", name=%s, status=%s, exitStatus=%s, readCount=%d, filterCount=%d, writeCount=%d readSkipCount=%d, writeSkipCount=%d"
|
||||
+ ", commitCount=%d, rollbackCount=%d", stepName, status, exitStatus, readCount,
|
||||
filterCount, writeCount, readSkipCount, writeSkipCount, commitCount, rollbackCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class SimpleJobExplorer implements JobExplorer {
|
||||
* @see org.springframework.batch.core.explore.JobExplorer#getStepExecution(java.lang.Long)
|
||||
*/
|
||||
public StepExecution getStepExecution(Long executionId, String stepName) {
|
||||
JobExecution jobExecution = jobExecutionDao.getJobExecution(executionId);
|
||||
JobExecution jobExecution = getJobExecution(executionId);
|
||||
return stepExecutionDao.getStepExecution(jobExecution, stepName);
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
|
||||
execution.setStartTime(new Date());
|
||||
// If paused we need to retain the status so that subclasses can
|
||||
// handle the resume, otherwise we mark it as started...
|
||||
if (!execution.isPaused()) {
|
||||
if (!execution.isWaiting()) {
|
||||
updateStatus(execution, BatchStatus.STARTED);
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
|
||||
StepExecution lastStepExecution = doExecute(execution);
|
||||
|
||||
if (lastStepExecution != null) {
|
||||
if (!execution.isPaused()) {
|
||||
if (!execution.isWaiting()) {
|
||||
// If the subclass wants to pause don't change the
|
||||
// status.
|
||||
execution.setStatus(lastStepExecution.getStatus());
|
||||
@@ -247,13 +247,13 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
|
||||
|
||||
}
|
||||
catch (JobInterruptedException e) {
|
||||
logger.error(e);
|
||||
logger.error("Encountered interruption executing job", e);
|
||||
execution.setExitStatus(ExitStatus.FAILED);
|
||||
execution.setStatus(BatchStatus.STOPPED);
|
||||
execution.addFailureException(e);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error(t);
|
||||
logger.error("Encountered error executing job", t);
|
||||
execution.setExitStatus(ExitStatus.FAILED);
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
execution.addFailureException(t);
|
||||
@@ -307,14 +307,13 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
|
||||
|
||||
JobInstance jobInstance = execution.getJobInstance();
|
||||
|
||||
StepExecution currentStepExecution = null;
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, step.getName());
|
||||
StepExecution currentStepExecution = lastStepExecution;
|
||||
|
||||
if (shouldStart(jobInstance, step)) {
|
||||
if (shouldStart(lastStepExecution, jobInstance, step)) {
|
||||
|
||||
currentStepExecution = execution.createStepExecution(step.getName());
|
||||
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, step.getName());
|
||||
|
||||
boolean isRestart = (lastStepExecution != null && !lastStepExecution.getStatus().equals(
|
||||
BatchStatus.COMPLETED)) ? true : false;
|
||||
|
||||
@@ -343,18 +342,19 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
|
||||
/**
|
||||
* 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.
|
||||
* @param lastStepExecution the last step execution
|
||||
* @param jobInstance
|
||||
* @param step
|
||||
*
|
||||
* @throws StartLimitExceededException if the start limit has been exceeded
|
||||
* for this step
|
||||
* @throws JobRestartException if the job is in an inconsistent state from
|
||||
* an earlier failure
|
||||
*/
|
||||
private boolean shouldStart(JobInstance jobInstance, Step step) throws JobRestartException,
|
||||
private boolean shouldStart(StepExecution lastStepExecution, JobInstance jobInstance, Step step) throws JobRestartException,
|
||||
StartLimitExceededException {
|
||||
|
||||
BatchStatus stepStatus;
|
||||
// if the last execution is null, the step has never been executed.
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, step.getName());
|
||||
if (lastStepExecution == null) {
|
||||
stepStatus = BatchStatus.STARTING;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ public class PauseState extends AbstractState {
|
||||
// not already paused we pause it, and expect the flow to respect the
|
||||
// status.
|
||||
synchronized (jobExecution) {
|
||||
if (!jobExecution.isPaused()) {
|
||||
jobExecution.pause();
|
||||
if (!jobExecution.isWaiting()) {
|
||||
jobExecution.pauseAndWait();
|
||||
return FlowExecution.PAUSED;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
final JobExecution jobExecution;
|
||||
JobExecution lastExecution = jobRepository.getLastJobExecution(job.getName(), jobParameters);
|
||||
if (lastExecution != null) {
|
||||
if (lastExecution.isPaused()) {
|
||||
if (lastExecution.isWaiting()) {
|
||||
jobExecution = lastExecution;
|
||||
// this execution will be continued => delete the end time
|
||||
jobExecution.setEndTime(null);
|
||||
|
||||
@@ -370,7 +370,7 @@ public class SimpleJobOperator implements JobOperator, InitializingBean {
|
||||
|
||||
public boolean pause(long executionId) throws NoSuchJobExecutionException {
|
||||
JobExecution jobExecution = findExecutionById(executionId);
|
||||
jobExecution.pause();
|
||||
jobExecution.pauseAndWait();
|
||||
jobRepository.update(jobExecution);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -73,15 +73,16 @@ public class PartitionStep extends AbstractStep {
|
||||
|
||||
// Wait for task completion and then aggregate the results
|
||||
Collection<StepExecution> executions = partitionHandler.handle(stepExecutionSplitter, stepExecution);
|
||||
stepExecution.upgradeStatus(BatchStatus.COMPLETED);
|
||||
aggregator.aggregate(stepExecution, executions);
|
||||
|
||||
if (stepExecution.getJobExecution().isPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If anything failed or had a problem we need to crap out
|
||||
if (stepExecution.getStatus().isUnsuccessful()) {
|
||||
throw new JobExecutionException("Partition handler returned an unsuccessful step");
|
||||
}
|
||||
|
||||
if (stepExecution.getStatus() != BatchStatus.COMPLETED) {
|
||||
throw new JobExecutionException("Partition handler returned an incomplete step");
|
||||
stepExecution.pauseAndWait();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
|
||||
if (count == 0) {
|
||||
int curentVersion = getJdbcTemplate().queryForInt(getQuery(CURRENT_VERSION_JOB_EXECUTION),
|
||||
new Object[] { jobExecution.getId() });
|
||||
throw new OptimisticLockingFailureException("Attempt to update step execution id="
|
||||
throw new OptimisticLockingFailureException("Attempt to update job execution id="
|
||||
+ jobExecution.getId() + " with wrong version (" + jobExecution.getVersion()
|
||||
+ "), where current version is " + curentVersion);
|
||||
}
|
||||
|
||||
@@ -199,6 +199,7 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
|
||||
}
|
||||
|
||||
stepExecution.setStatus(BatchStatus.COMPLETED);
|
||||
logger.debug("Step execution success: " + stepExecution);
|
||||
|
||||
try {
|
||||
getJobRepository().update(stepExecution);
|
||||
@@ -265,6 +266,9 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
|
||||
+ "This job is now in an unknown state and should not be restarted.", commitException);
|
||||
stepExecution.addFailureException(commitException);
|
||||
}
|
||||
|
||||
logger.debug("Step execution complete: " + stepExecution);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,42 @@ public class BatchStatusTests {
|
||||
assertEquals(BatchStatus.FAILED, BatchStatus.max(BatchStatus.FAILED,BatchStatus.COMPLETED));
|
||||
assertEquals(BatchStatus.FAILED, BatchStatus.max(BatchStatus.COMPLETED, BatchStatus.FAILED));
|
||||
assertEquals(BatchStatus.FAILED, BatchStatus.max(BatchStatus.FAILED, BatchStatus.FAILED));
|
||||
assertEquals(BatchStatus.STARTED, BatchStatus.max(BatchStatus.STARTED, BatchStatus.STARTING));
|
||||
assertEquals(BatchStatus.STARTED, BatchStatus.max(BatchStatus.COMPLETED, BatchStatus.STARTED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpgradeStatusFinished() {
|
||||
assertEquals(BatchStatus.FAILED, BatchStatus.FAILED.upgradeTo(BatchStatus.COMPLETED));
|
||||
assertEquals(BatchStatus.FAILED, BatchStatus.COMPLETED.upgradeTo(BatchStatus.FAILED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpgradeStatusUnfinished() {
|
||||
assertEquals(BatchStatus.COMPLETED, BatchStatus.STARTING.upgradeTo(BatchStatus.COMPLETED));
|
||||
assertEquals(BatchStatus.COMPLETED, BatchStatus.COMPLETED.upgradeTo(BatchStatus.STARTING));
|
||||
assertEquals(BatchStatus.STARTED, BatchStatus.STARTING.upgradeTo(BatchStatus.STARTED));
|
||||
assertEquals(BatchStatus.STARTED, BatchStatus.STARTED.upgradeTo(BatchStatus.STARTING));
|
||||
assertEquals(BatchStatus.COMPLETED, BatchStatus.COMPLETED.upgradeTo(BatchStatus.WAITING));
|
||||
assertEquals(BatchStatus.STARTED, BatchStatus.STARTED.upgradeTo(BatchStatus.WAITING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsRunning() {
|
||||
assertFalse(BatchStatus.FAILED.isRunning());
|
||||
assertFalse(BatchStatus.COMPLETED.isRunning());
|
||||
assertTrue(BatchStatus.STARTED.isRunning());
|
||||
assertTrue(BatchStatus.STARTING.isRunning());
|
||||
assertTrue(BatchStatus.WAITING.isRunning());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsUnsuccessful() {
|
||||
assertTrue(BatchStatus.FAILED.isUnsuccessful());
|
||||
assertFalse(BatchStatus.COMPLETED.isUnsuccessful());
|
||||
assertFalse(BatchStatus.STARTED.isUnsuccessful());
|
||||
assertFalse(BatchStatus.STARTING.isUnsuccessful());
|
||||
assertFalse(BatchStatus.WAITING.isUnsuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -109,12 +109,34 @@ public class JobExecutionTests {
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#pause()}.
|
||||
* {@link org.springframework.batch.core.JobExecution#pauseAndWait()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPause() {
|
||||
execution.pause();
|
||||
assertEquals(BatchStatus.PAUSED, execution.getStatus());
|
||||
public void testPauseAndWait() {
|
||||
execution.pauseAndWait();
|
||||
assertEquals(BatchStatus.WAITING, execution.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#pauseAndWait()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPauseAndWaitWhenFailed() {
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
execution.pauseAndWait();
|
||||
assertEquals(BatchStatus.FAILED, execution.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#pauseAndWait()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPauseAndWaitWhenStarted() {
|
||||
execution.setStatus(BatchStatus.STARTED);
|
||||
execution.pauseAndWait();
|
||||
assertEquals(BatchStatus.WAITING, execution.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -275,6 +275,49 @@ public class StepExecutionTests {
|
||||
assertEquals(exception, execution.getFailureExceptions().get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#pauseAndWait()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPauseAndWait() {
|
||||
execution.pauseAndWait();
|
||||
assertEquals(BatchStatus.WAITING, execution.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#pauseAndWait()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPauseAndWaitWhenFailed() {
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
execution.pauseAndWait();
|
||||
assertEquals(BatchStatus.FAILED, execution.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#pauseAndWait()}.
|
||||
*/
|
||||
@Test
|
||||
public void testPauseAndWaitWhenStarted() {
|
||||
execution.setStatus(BatchStatus.STARTED);
|
||||
execution.pauseAndWait();
|
||||
assertEquals(BatchStatus.WAITING, execution.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.JobExecution#getStatus()}.
|
||||
*/
|
||||
@Test
|
||||
public void testDowngradeStatus() {
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
execution.upgradeStatus(BatchStatus.COMPLETED);
|
||||
assertEquals(BatchStatus.FAILED, execution.getStatus());
|
||||
}
|
||||
|
||||
private StepExecution newStepExecution(Step step, Long long2) {
|
||||
JobInstance job = new JobInstance(new Long(3), new JobParameters(), "testJob");
|
||||
StepExecution execution = new StepExecution(step.getName(), new JobExecution(job, long2), new Long(4));
|
||||
|
||||
@@ -76,6 +76,7 @@ public class SimpleJobExplorerTests extends TestCase {
|
||||
public void testGetStepExecution() throws Exception {
|
||||
expect(jobExecutionDao.getJobExecution(123L)).andReturn(jobExecution);
|
||||
expect(stepExecutionDao.getStepExecution(jobExecution, "foo")).andReturn(null);
|
||||
expect(stepExecutionDao.getStepExecutions(jobExecution)).andReturn(null);
|
||||
replay(jobExecutionDao, stepExecutionDao);
|
||||
jobExplorer.getStepExecution(123L,"foo");
|
||||
verify(jobExecutionDao, stepExecutionDao);
|
||||
|
||||
@@ -313,6 +313,16 @@ public class SimpleJobTests {
|
||||
ex.getMessage().indexOf("start limit exceeded") >= 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStepAlreadyComplete() throws Exception {
|
||||
stepExecution1.setStatus(BatchStatus.COMPLETED);
|
||||
jobRepository.add(stepExecution1);
|
||||
job.execute(jobExecution);
|
||||
assertEquals(0, jobExecution.getFailureExceptions().size());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
assertEquals(stepExecution2.getStepName(), jobExecution.getStepExecutions().iterator().next().getStepName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSteps() throws Exception {
|
||||
job.setSteps(new ArrayList<Step>());
|
||||
|
||||
@@ -265,7 +265,7 @@ public class FlowJobTests {
|
||||
if (!jobExecution.getAllFailureExceptions().isEmpty()) {
|
||||
throw jobExecution.getAllFailureExceptions().get(0);
|
||||
}
|
||||
assertEquals(BatchStatus.PAUSED, jobExecution.getStatus());
|
||||
assertEquals(BatchStatus.WAITING, jobExecution.getStatus());
|
||||
assertEquals(1, jobExecution.getStepExecutions().size());
|
||||
|
||||
job.execute(jobExecution);
|
||||
|
||||
@@ -194,7 +194,7 @@ public class SimpleJobLauncherTests {
|
||||
public void testResumePausedInstance() throws Exception {
|
||||
long id = 9;
|
||||
JobExecution jobExecution = new JobExecution(null, id);
|
||||
jobExecution.pause();
|
||||
jobExecution.pauseAndWait();
|
||||
expect(jobRepository.getLastJobExecution(job.getName(), jobParameters)).andReturn(jobExecution);
|
||||
replay(jobRepository);
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ public class SimpleJobOperatorTests {
|
||||
jobOperator.pause(111L);
|
||||
verify(jobExplorer);
|
||||
verify(jobRepository);
|
||||
assertEquals(BatchStatus.PAUSED, jobExecution.getStatus());
|
||||
assertEquals(BatchStatus.WAITING, jobExecution.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class StepExecutionAggregatorTests {
|
||||
stepExecution2.setStatus(BatchStatus.COMPLETED);
|
||||
aggregator.aggregate(result, Arrays.<StepExecution> asList(stepExecution1, stepExecution2));
|
||||
assertNotNull(result);
|
||||
assertEquals(BatchStatus.COMPLETED, result.getStatus());
|
||||
assertEquals(BatchStatus.STARTING, result.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -224,6 +224,7 @@ public abstract class AbstractJobExecutionDaoTests extends AbstractTransactional
|
||||
JobExecution value = dao.getJobExecution(exec.getId());
|
||||
|
||||
assertEquals(exec, value);
|
||||
// N.B. the job instance is not re-hydrated in the JDBC case...
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,9 +77,10 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
dao = getStepExecutionDao();
|
||||
}
|
||||
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testSaveExecutionAssignsIdAndVersion() throws Exception {
|
||||
|
||||
|
||||
assertNull(stepExecution.getId());
|
||||
assertNull(stepExecution.getVersion());
|
||||
dao.saveStepExecution(stepExecution);
|
||||
@@ -87,9 +88,10 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
assertNotNull(stepExecution.getVersion());
|
||||
}
|
||||
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testSaveAndGetExecution() {
|
||||
|
||||
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
stepExecution.setReadSkipCount(7);
|
||||
stepExecution.setWriteSkipCount(5);
|
||||
@@ -102,18 +104,26 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
dao.saveStepExecution(stepExecution);
|
||||
|
||||
StepExecution retrieved = dao.getStepExecution(jobExecution, step.getName());
|
||||
|
||||
|
||||
assertStepExecutionsAreEqual(stepExecution, retrieved);
|
||||
assertNotNull(retrieved.getVersion());
|
||||
assertNotNull(retrieved.getJobExecution());
|
||||
assertNotNull(retrieved.getJobExecution().getId());
|
||||
|
||||
assertNotNull(retrieved.getJobExecution().getJobId());
|
||||
assertNotNull(retrieved.getJobExecution().getJobInstance());
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Test
|
||||
public void testSaveAndGetNonExistentExecution() {
|
||||
assertNull(dao.getStepExecution(jobExecution, "not-existing step"));
|
||||
}
|
||||
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testSaveAndFindExecution() {
|
||||
|
||||
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
stepExecution.setReadSkipCount(7);
|
||||
stepExecution.setWriteSkipCount(5);
|
||||
@@ -124,7 +134,8 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
assertStepExecutionsAreEqual(stepExecution, retrieved.get(0));
|
||||
}
|
||||
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testGetForNotExistingJobExecution() {
|
||||
assertNull(dao.getStepExecution(new JobExecution(jobInstance, (long) 777), step.getName()));
|
||||
}
|
||||
@@ -132,7 +143,8 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
/**
|
||||
* To-be-saved execution must not already have an id.
|
||||
*/
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testSaveExecutionWithIdAlreadySet() {
|
||||
stepExecution.setId((long) 7);
|
||||
try {
|
||||
@@ -147,7 +159,8 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
/**
|
||||
* To-be-saved execution must not already have a version.
|
||||
*/
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testSaveExecutionWithVersionAlreadySet() {
|
||||
stepExecution.incrementVersion();
|
||||
try {
|
||||
@@ -163,7 +176,8 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
* Update and retrieve updated StepExecution - make sure the update is
|
||||
* reflected as expected and version number has been incremented
|
||||
*/
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testUpdateExecution() {
|
||||
stepExecution.setStatus(BatchStatus.STARTED);
|
||||
dao.saveStepExecution(stepExecution);
|
||||
@@ -184,7 +198,8 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
* Exception should be raised when the version of update argument doesn't
|
||||
* match the version of persisted entity.
|
||||
*/
|
||||
@Transactional @Test
|
||||
@Transactional
|
||||
@Test
|
||||
public void testConcurrentModificationException() {
|
||||
step = new StepSupport("foo");
|
||||
|
||||
@@ -210,7 +225,7 @@ public abstract class AbstractStepExecutionDaoTests extends AbstractTransactiona
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void assertStepExecutionsAreEqual(StepExecution expected, StepExecution actual) {
|
||||
assertEquals(expected.getId(), actual.getId());
|
||||
assertEquals(expected.getStartTime(), actual.getStartTime());
|
||||
|
||||
Reference in New Issue
Block a user