BATCH-1067:
* FlowJob waits until the Job is finished before updating BatchStatus and ExitStatus. This is required so that individual flows in a split don't modifify the JobExecution prematurely. * Removed FlowExecution$Status and replaced it with FlowExecutionStatus, a class that holds both a BatchStatus and an ExitStatus. This is required by the EndState because the handle() method needs to be able to return both BatchStatus and ExitStatus so that they can be applied correctly to the JobExecution when ending the job.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.batch.core;
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration representing the status of a an Execution.
|
||||
*
|
||||
@@ -115,4 +116,21 @@ public enum BatchStatus {
|
||||
return this.compareTo(other) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a BatchStatus that matches the beginning of the given value. If
|
||||
* no match is found, return COMPLETED as the default because has is low
|
||||
* precedence.
|
||||
*
|
||||
* @param value a string representing a status
|
||||
* @return a BatchStatus
|
||||
*/
|
||||
public static BatchStatus match(String value) {
|
||||
for (BatchStatus status : values()) {
|
||||
if (value.startsWith(status.toString())) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
// Default match should be the lowest priority
|
||||
return COMPLETED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,61 +15,35 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class FlowExecution implements Comparable<FlowExecution> {
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final String COMPLETED = Status.COMPLETED.toString();
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final String PAUSED = Status.PAUSED.toString();
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final String FAILED = Status.FAILED.toString();
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final String UNKNOWN = Status.UNKNOWN.toString();
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String status;
|
||||
|
||||
private enum Status {
|
||||
|
||||
COMPLETED, PAUSED, FAILED, UNKNOWN;
|
||||
|
||||
static Status match(String value) {
|
||||
for (int i = 0; i < values().length; i++) {
|
||||
Status status = values()[i];
|
||||
if (value.startsWith(status.toString())) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
// Default match should be the lowest priority
|
||||
return COMPLETED;
|
||||
}
|
||||
|
||||
};
|
||||
private final FlowExecutionStatus status;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
* @param status
|
||||
*/
|
||||
public FlowExecution(String name, String status) {
|
||||
public FlowExecution(String name, FlowExecutionStatus status) {
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor that converts a String status to a {@link FlowExecutionStatus}.
|
||||
*
|
||||
* @param name
|
||||
* @param status
|
||||
*/
|
||||
public FlowExecution(String name, String status) {
|
||||
this(name, new FlowExecutionStatus(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the end state reached
|
||||
*/
|
||||
@@ -80,7 +54,7 @@ public class FlowExecution implements Comparable<FlowExecution> {
|
||||
/**
|
||||
* @return the exit status
|
||||
*/
|
||||
public String getStatus() {
|
||||
public FlowExecutionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -94,13 +68,7 @@ public class FlowExecution implements Comparable<FlowExecution> {
|
||||
* @return negative, zero or positive as per the contract
|
||||
*/
|
||||
public int compareTo(FlowExecution other) {
|
||||
Status one = Status.match(this.getStatus());
|
||||
Status two = Status.match(other.getStatus());
|
||||
int comparison = one.compareTo(two);
|
||||
if (comparison==0) {
|
||||
return this.getStatus().compareTo(other.getStatus());
|
||||
}
|
||||
return comparison;
|
||||
return this.status.compareTo(other.getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
|
||||
/**
|
||||
* This class is used as a holder for a BatchStatus/ExitStatus pair.
|
||||
*
|
||||
* @author Dan Garrette
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FlowExecutionStatus implements Comparable<FlowExecutionStatus> {
|
||||
|
||||
private final String status;
|
||||
private final ExitStatus exitStatus;
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final FlowExecutionStatus COMPLETED = new FlowExecutionStatus(BatchStatus.COMPLETED,
|
||||
ExitStatus.COMPLETED);
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final FlowExecutionStatus STOPPED = new FlowExecutionStatus(BatchStatus.STOPPED, ExitStatus.FAILED);
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final FlowExecutionStatus FAILED = new FlowExecutionStatus(BatchStatus.FAILED, ExitStatus.FAILED);
|
||||
|
||||
/**
|
||||
* Special well-known status value.
|
||||
*/
|
||||
public static final FlowExecutionStatus UNKNOWN = new FlowExecutionStatus(BatchStatus.UNKNOWN, ExitStatus.UNKNOWN);
|
||||
|
||||
/**
|
||||
* @param status
|
||||
*/
|
||||
public FlowExecutionStatus(String status) {
|
||||
this(status, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param status
|
||||
* @param exitStatus
|
||||
*/
|
||||
public FlowExecutionStatus(String status, ExitStatus exitStatus) {
|
||||
this.status = status;
|
||||
this.exitStatus = exitStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor that accepts a {@link BatchStatus} and
|
||||
* {@link ExitStatus}.
|
||||
*
|
||||
* @param batchStatus
|
||||
* @param exitStatus
|
||||
*/
|
||||
public FlowExecutionStatus(BatchStatus batchStatus, ExitStatus exitStatus) {
|
||||
this(batchStatus.toString(), exitStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience getter for the {@link BatchStatus}.
|
||||
*
|
||||
* @return a {@link BatchStatus} representing the status
|
||||
*/
|
||||
public BatchStatus getBatchStatus() {
|
||||
return BatchStatus.match(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ordering on {@link FlowExecutionStatus} instances by comparing
|
||||
* their statuses.
|
||||
*
|
||||
* @see Comparable#compareTo(Object)
|
||||
*
|
||||
* @param other
|
||||
* @return negative, zero or positive as per the contract
|
||||
*/
|
||||
public int compareTo(FlowExecutionStatus other) {
|
||||
BatchStatus one = this.getBatchStatus();
|
||||
BatchStatus two = other.getBatchStatus();
|
||||
int comparison = one.compareTo(two);
|
||||
if (comparison == 0) {
|
||||
return status.compareTo(other.getStatus());
|
||||
}
|
||||
return comparison;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the equality of the statuses.
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof FlowExecutionStatus)) {
|
||||
return false;
|
||||
}
|
||||
FlowExecutionStatus flowExecutionStatus = (FlowExecutionStatus) other;
|
||||
return status.equals(flowExecutionStatus.getStatus());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "FlowExecutionStatus: status=[" + status + "] exitstatus=[" + exitStatus + "]";
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public ExitStatus getExitStatus() {
|
||||
return exitStatus;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.batch.core.job.flow;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
@@ -76,7 +77,13 @@ public class FlowJob extends AbstractJob {
|
||||
@Override
|
||||
protected void doExecute(final JobExecution execution) throws JobExecutionException {
|
||||
try {
|
||||
flow.start(new JobFlowExecutor(execution));
|
||||
FlowExecution flowExecution = flow.start(new JobFlowExecutor(execution));
|
||||
|
||||
synchronized (execution) {
|
||||
FlowExecutionStatus status = flowExecution.getStatus();
|
||||
execution.upgradeStatus(status.getBatchStatus());
|
||||
execution.setExitStatus(status.getExitStatus());
|
||||
}
|
||||
}
|
||||
catch (FlowExecutionException e) {
|
||||
if (e.getCause() instanceof JobExecutionException) {
|
||||
@@ -111,7 +118,7 @@ public class FlowJob extends AbstractJob {
|
||||
}
|
||||
StepExecution stepExecution = handleStep(step, execution);
|
||||
stepExecutionHolder.set(stepExecution);
|
||||
return stepExecution==null ? FlowExecution.COMPLETED : stepExecution.getExitStatus().getExitCode();
|
||||
return stepExecution==null ? ExitStatus.COMPLETED.getExitCode() : stepExecution.getExitStatus().getExitCode();
|
||||
}
|
||||
|
||||
public JobExecution getJobExecution() {
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.job.flow.Flow;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionException;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
@@ -115,7 +116,7 @@ public class SimpleFlow implements Flow, InitializingBean {
|
||||
*/
|
||||
public FlowExecution resume(String stateName, FlowExecutor executor) throws FlowExecutionException {
|
||||
|
||||
String status = FlowExecution.UNKNOWN;
|
||||
FlowExecutionStatus status = FlowExecutionStatus.UNKNOWN;
|
||||
State state = stateMap.get(stateName);
|
||||
|
||||
// Terminate if there are no more states
|
||||
@@ -146,13 +147,7 @@ public class SimpleFlow implements Flow, InitializingBean {
|
||||
* @return the next {@link Step} (or null if this is the end)
|
||||
* @throws JobExecutionException
|
||||
*/
|
||||
private State nextState(String stateName, String status) throws FlowExecutionException {
|
||||
|
||||
// Special status value indicating that a state wishes to pause
|
||||
// execution
|
||||
if (status.equals(FlowExecution.PAUSED)) {
|
||||
return null;
|
||||
}
|
||||
private State nextState(String stateName, FlowExecutionStatus status) throws FlowExecutionException {
|
||||
|
||||
Set<StateTransition> set = transitionMap.get(stateName);
|
||||
|
||||
@@ -163,7 +158,7 @@ public class SimpleFlow implements Flow, InitializingBean {
|
||||
|
||||
String next = null;
|
||||
for (StateTransition stateTransition : set) {
|
||||
if (stateTransition.matches(status)) {
|
||||
if (stateTransition.matches(status.getStatus())) {
|
||||
if (stateTransition.isEnd()) {
|
||||
// End of job
|
||||
return null;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.batch.core.job.flow.support;
|
||||
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
|
||||
|
||||
@@ -42,9 +43,9 @@ public interface State {
|
||||
* context is thread safe, or used in a thread safe manner.
|
||||
*
|
||||
* @param executor the context passed in by the caller
|
||||
* @return a status for the execution
|
||||
* @return a {@link FlowExecutionStatus} for the execution
|
||||
* @throws Exception if anything goes wrong
|
||||
*/
|
||||
String handle(FlowExecutor executor) throws Exception;
|
||||
FlowExecutionStatus handle(FlowExecutor executor) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow.support.state;
|
||||
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
|
||||
@@ -46,6 +47,6 @@ public abstract class AbstractState implements State {
|
||||
return getClass().getSimpleName()+": name=["+name+"]";
|
||||
}
|
||||
|
||||
public abstract String handle(FlowExecutor executor) throws Exception;
|
||||
public abstract FlowExecutionStatus handle(FlowExecutor executor) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package org.springframework.batch.core.job.flow.support.state;
|
||||
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -37,8 +37,8 @@ public class DecisionState extends AbstractState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String handle(FlowExecutor executor) throws Exception {
|
||||
return decider.decide(executor.getJobExecution(), executor.getStepExecution());
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
return new FlowExecutionStatus(decider.decide(executor.getJobExecution(), executor.getStepExecution()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,7 @@ 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.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
|
||||
@@ -57,32 +57,25 @@ public class EndState extends AbstractState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status as long the {@link JobExecution} is in progress. If this
|
||||
* is the first place we came after a restart we do nothing (otherwise the
|
||||
* same outcome that ended the job on the last run will occur).
|
||||
* Return the {@link BatchStatus} and {@link ExitStatus} stored. If the
|
||||
* {@link BatchStatus} is {@link BatchStatus#STOPPED}, then mark it on the
|
||||
* {@link JobExecution} so that the job will know to stop.
|
||||
*
|
||||
* @see State#handle(FlowExecutor)
|
||||
*/
|
||||
@Override
|
||||
public String handle(FlowExecutor executor) throws Exception {
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
JobExecution jobExecution = executor.getJobExecution();
|
||||
// If there are no step executions, then we are at the beginning of a
|
||||
// restart
|
||||
synchronized (jobExecution) {
|
||||
if (!jobExecution.getStepExecutions().isEmpty()) {
|
||||
BatchStatus beforeStatus = jobExecution.getStatus();
|
||||
|
||||
jobExecution.upgradeStatus(status);
|
||||
|
||||
//
|
||||
// If the status was changed or the target status is the same as the old
|
||||
//
|
||||
if(beforeStatus != jobExecution.getStatus() || beforeStatus == status)
|
||||
{
|
||||
if (status == BatchStatus.STOPPED) {
|
||||
jobExecution.upgradeStatus(status);
|
||||
jobExecution.setExitStatus(exitStatus);
|
||||
}
|
||||
}
|
||||
return FlowExecution.COMPLETED;
|
||||
return new FlowExecutionStatus(status, exitStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.batch.core.job.flow.support.state;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
|
||||
/**
|
||||
* Strategy interface for aggregating {@link FlowExecution} instances into a
|
||||
@@ -32,6 +33,6 @@ public interface FlowExecutionAggregator {
|
||||
* @param executions the executions to aggregate
|
||||
* @return a summary status for the whole lot
|
||||
*/
|
||||
String aggregate(Collection<FlowExecution> executions);
|
||||
FlowExecutionStatus aggregate(Collection<FlowExecution> executions);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,19 +19,24 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MaxValueFlowExecutionAggregator implements FlowExecutionAggregator {
|
||||
|
||||
/**
|
||||
* Aggregate all of the {@link FlowExecutionStatus}es of the
|
||||
* {@link FlowExecution}s into one status. The aggregate status will be the
|
||||
* status with the highest precedence.
|
||||
*
|
||||
* @see FlowExecutionAggregator#aggregate(Collection)
|
||||
*/
|
||||
public String aggregate(Collection<FlowExecution> executions) {
|
||||
if (executions==null || executions.size()==0) {
|
||||
return FlowExecution.UNKNOWN;
|
||||
public FlowExecutionStatus aggregate(Collection<FlowExecution> executions) {
|
||||
if (executions == null || executions.size() == 0) {
|
||||
return FlowExecutionStatus.UNKNOWN;
|
||||
}
|
||||
return Collections.max(executions).getStatus();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.FutureTask;
|
||||
import org.springframework.batch.core.job.flow.Flow;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionException;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
import org.springframework.core.task.SyncTaskExecutor;
|
||||
@@ -68,7 +69,7 @@ public class SplitState extends AbstractState {
|
||||
* @see State#handle(FlowExecutor)
|
||||
*/
|
||||
@Override
|
||||
public String handle(final FlowExecutor executor) throws Exception {
|
||||
public FlowExecutionStatus handle(final FlowExecutor executor) throws Exception {
|
||||
|
||||
Collection<Future<FlowExecution>> tasks = new ArrayList<Future<FlowExecution>>();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.batch.core.job.flow.support.state;
|
||||
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
|
||||
@@ -49,8 +50,8 @@ public class StepState extends AbstractState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String handle(FlowExecutor executor) throws Exception {
|
||||
return executor.executeStep(step);
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
return new FlowExecutionStatus(executor.executeStep(step));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,12 +40,13 @@ public class SplitDifferentResultsFailSecondJobParserTests extends AbstractJobPa
|
||||
|
||||
JobExecution jobExecution = createJobExecution();
|
||||
job.execute(jobExecution);
|
||||
assertEquals(2, stepNamesList.size());
|
||||
assertEquals(3, stepNamesList.size());
|
||||
assertTrue(stepNamesList.contains("step1"));
|
||||
assertTrue(stepNamesList.contains("failingStep"));
|
||||
assertTrue(stepNamesList.contains("step3"));
|
||||
|
||||
assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
|
||||
assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus());
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
|
||||
|
||||
StepExecution stepExecution1 = getStepExecution(jobExecution, "step1");
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution1.getStatus());
|
||||
@@ -55,6 +56,10 @@ public class SplitDifferentResultsFailSecondJobParserTests extends AbstractJobPa
|
||||
assertEquals(BatchStatus.FAILED, stepExecution2.getStatus());
|
||||
assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution2.getExitStatus().getExitCode());
|
||||
|
||||
StepExecution stepExecution3 = getStepExecution(jobExecution, "step3");
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution3.getStatus());
|
||||
assertEquals(ExitStatus.COMPLETED, stepExecution3.getExitStatus());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class FlowExecutionTests {
|
||||
public void testBasicProperties() throws Exception {
|
||||
FlowExecution execution = new FlowExecution("foo", "BAR");
|
||||
assertEquals("foo",execution.getName());
|
||||
assertEquals("BAR",execution.getStatus());
|
||||
assertEquals("BAR",execution.getStatus().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -44,8 +44,8 @@ public class FlowExecutionTests {
|
||||
|
||||
@Test
|
||||
public void testEnumOrdering() throws Exception {
|
||||
FlowExecution first = new FlowExecution("foo", FlowExecution.COMPLETED);
|
||||
FlowExecution second = new FlowExecution("foo", FlowExecution.FAILED);
|
||||
FlowExecution first = new FlowExecution("foo", FlowExecutionStatus.COMPLETED);
|
||||
FlowExecution second = new FlowExecution("foo", FlowExecutionStatus.FAILED);
|
||||
assertTrue("Should be negative",first.compareTo(second)<0);
|
||||
assertTrue("Should be positive",second.compareTo(first)>0);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow.support;
|
||||
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.StartLimitExceededException;
|
||||
@@ -26,13 +27,13 @@ import org.springframework.batch.core.repository.JobRestartException;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class JobFlowExecutorSupport implements FlowExecutor {
|
||||
|
||||
public String executeStep(Step step) throws JobInterruptedException, JobRestartException,
|
||||
StartLimitExceededException {
|
||||
return FlowExecution.COMPLETED;
|
||||
return ExitStatus.COMPLETED.getExitCode();
|
||||
}
|
||||
|
||||
public JobExecution getJobExecution() {
|
||||
|
||||
@@ -26,9 +26,13 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionException;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.batch.core.job.flow.support.state.EndState;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -56,17 +60,17 @@ public class SimpleFlowTests {
|
||||
@Test
|
||||
public void testStepLoop() throws Exception {
|
||||
flow.setStateTransitions(collect(StateTransition.createStateTransition(new StateSupport("step"),
|
||||
FlowExecution.FAILED, "step"), StateTransition.createEndStateTransition(new StateSupport("step"))));
|
||||
ExitStatus.FAILED.getExitCode(), "step"), StateTransition.createEndStateTransition(new StateSupport("step"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step", execution.getName());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNoEndStep() throws Exception {
|
||||
flow.setStateTransitions(Collections.singletonList(StateTransition.createStateTransition(new StateSupport(
|
||||
"step"), FlowExecution.FAILED, "step")));
|
||||
"step"), ExitStatus.FAILED.getExitCode(), "step")));
|
||||
flow.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@@ -76,7 +80,7 @@ public class SimpleFlowTests {
|
||||
StateTransition.createEndStateTransition(new StubState("step2"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step1", execution.getName());
|
||||
}
|
||||
|
||||
@@ -102,7 +106,7 @@ public class SimpleFlowTests {
|
||||
"step1"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step1", execution.getName());
|
||||
}
|
||||
|
||||
@@ -120,17 +124,17 @@ public class SimpleFlowTests {
|
||||
};
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(1, list.size());
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step1", execution.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitStartStep() throws Exception {
|
||||
flow.setStateTransitions(collect(StateTransition.createStateTransition(new StubState("step"),
|
||||
FlowExecution.FAILED, "step"), StateTransition.createEndStateTransition(new StubState("step"))));
|
||||
ExitStatus.FAILED.getExitCode(), "step"), StateTransition.createEndStateTransition(new StubState("step"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step", execution.getName());
|
||||
}
|
||||
|
||||
@@ -140,7 +144,7 @@ public class SimpleFlowTests {
|
||||
StateTransition.createEndStateTransition(new StubState("step2"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step2", execution.getName());
|
||||
}
|
||||
|
||||
@@ -150,7 +154,7 @@ public class SimpleFlowTests {
|
||||
StateTransition.createEndStateTransition(new StubState("step2"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.resume("step2", executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step2", execution.getName());
|
||||
}
|
||||
|
||||
@@ -158,54 +162,28 @@ public class SimpleFlowTests {
|
||||
public void testFailedStep() throws Exception {
|
||||
flow.setStateTransitions(collect(StateTransition.createStateTransition(new StubState("step1") {
|
||||
@Override
|
||||
public String handle(FlowExecutor executor) {
|
||||
return FlowExecution.FAILED;
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) {
|
||||
return FlowExecutionStatus.FAILED;
|
||||
}
|
||||
}, "step2"), StateTransition.createEndStateTransition(new StubState("step2"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step2", execution.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBranching() throws Exception {
|
||||
flow.setStateTransitions(collect(StateTransition.createStateTransition(new StubState("step1"), "step2"),
|
||||
StateTransition.createStateTransition(new StubState("step1"), FlowExecution.COMPLETED, "step3"),
|
||||
StateTransition.createStateTransition(new StubState("step1"), ExitStatus.COMPLETED.getExitCode(), "step3"),
|
||||
StateTransition.createEndStateTransition(new StubState("step2")), StateTransition
|
||||
.createEndStateTransition(new StubState("step3"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, execution.getStatus());
|
||||
assertEquals("step3", execution.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPause() throws Exception {
|
||||
flow.setStateTransitions(collect(StateTransition.createStateTransition(new StubState("step1"), "step2"),
|
||||
StateTransition.createStateTransition(new StubState("step2") {
|
||||
private boolean paused = false;
|
||||
|
||||
@Override
|
||||
public String handle(FlowExecutor executor) throws Exception {
|
||||
if (!paused) {
|
||||
paused = true;
|
||||
return FlowExecution.PAUSED;
|
||||
}
|
||||
paused = false;
|
||||
return FlowExecution.COMPLETED;
|
||||
}
|
||||
|
||||
}, "step3"), StateTransition.createEndStateTransition(new StubState("step3"))));
|
||||
flow.afterPropertiesSet();
|
||||
FlowExecution execution = flow.start(executor);
|
||||
assertEquals(FlowExecution.PAUSED, execution.getStatus());
|
||||
assertEquals("step2", execution.getName());
|
||||
execution = flow.resume(execution.getName(), executor);
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals("step3", execution.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateExists() throws Exception {
|
||||
flow.setStateTransitions(Collections.singletonList(StateTransition.createEndStateTransition(new StubState(
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow.support;
|
||||
|
||||
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.job.flow.support.State;
|
||||
import org.springframework.batch.core.job.flow.support.state.AbstractState;
|
||||
|
||||
/**
|
||||
@@ -36,8 +35,8 @@ public class StateSupport extends AbstractState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String handle(FlowExecutor executor) throws Exception {
|
||||
return FlowExecution.COMPLETED;
|
||||
public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
|
||||
return FlowExecutionStatus.COMPLETED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class EndStateTests {
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(BatchStatus.UNKNOWN, jobExecution.getStatus());
|
||||
assertEquals(BatchStatus.STARTING, jobExecution.getStatus());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.support.state.MaxValueFlowExecutionAggregator;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -35,16 +35,16 @@ public class SimpleFlowExecutionAggregatorTests {
|
||||
|
||||
@Test
|
||||
public void testFailed() throws Exception {
|
||||
FlowExecution first = new FlowExecution("foo", FlowExecution.COMPLETED);
|
||||
FlowExecution second = new FlowExecution("foo", FlowExecution.FAILED);
|
||||
FlowExecution first = new FlowExecution("foo", FlowExecutionStatus.COMPLETED);
|
||||
FlowExecution second = new FlowExecution("foo", FlowExecutionStatus.FAILED);
|
||||
assertTrue("Should be negative", first.compareTo(second)<0);
|
||||
assertTrue("Should be positive", second.compareTo(first)>0);
|
||||
assertEquals(FlowExecution.FAILED, aggregator.aggregate(Arrays.asList(first, second)));
|
||||
assertEquals(FlowExecutionStatus.FAILED, aggregator.aggregate(Arrays.asList(first, second)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() throws Exception {
|
||||
assertEquals(FlowExecution.UNKNOWN, aggregator.aggregate(Collections.<FlowExecution> emptySet()));
|
||||
assertEquals(FlowExecutionStatus.UNKNOWN, aggregator.aggregate(Collections.<FlowExecution> emptySet()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.easymock.EasyMock;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.job.flow.Flow;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.support.state.SplitState;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ public class SplitStateTests {
|
||||
|
||||
SplitState state = new SplitState(flows, "foo");
|
||||
|
||||
EasyMock.expect(flow1.start(null)).andReturn(new FlowExecution("step1", FlowExecution.COMPLETED));
|
||||
EasyMock.expect(flow2.start(null)).andReturn(new FlowExecution("step1", FlowExecution.COMPLETED));
|
||||
EasyMock.expect(flow1.start(null)).andReturn(new FlowExecution("step1", FlowExecutionStatus.COMPLETED));
|
||||
EasyMock.expect(flow2.start(null)).andReturn(new FlowExecution("step1", FlowExecutionStatus.COMPLETED));
|
||||
EasyMock.replay(flow1, flow2);
|
||||
|
||||
String result = state.handle(null);
|
||||
assertEquals(FlowExecution.COMPLETED, result);
|
||||
FlowExecutionStatus result = state.handle(null);
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, result);
|
||||
|
||||
EasyMock.verify(flow1, flow2);
|
||||
|
||||
@@ -68,12 +68,12 @@ public class SplitStateTests {
|
||||
SplitState state = new SplitState(flows, "foo");
|
||||
state.setTaskExecutor(new SimpleAsyncTaskExecutor());
|
||||
|
||||
EasyMock.expect(flow1.start(null)).andReturn(new FlowExecution("step1", FlowExecution.COMPLETED));
|
||||
EasyMock.expect(flow2.start(null)).andReturn(new FlowExecution("step1", FlowExecution.COMPLETED));
|
||||
EasyMock.expect(flow1.start(null)).andReturn(new FlowExecution("step1", FlowExecutionStatus.COMPLETED));
|
||||
EasyMock.expect(flow2.start(null)).andReturn(new FlowExecution("step1", FlowExecutionStatus.COMPLETED));
|
||||
EasyMock.replay(flow1, flow2);
|
||||
|
||||
String result = state.handle(null);
|
||||
assertEquals(FlowExecution.COMPLETED, result);
|
||||
FlowExecutionStatus result = state.handle(null);
|
||||
assertEquals(FlowExecutionStatus.COMPLETED, result);
|
||||
|
||||
EasyMock.verify(flow1, flow2);
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
<job id="job">
|
||||
<split id="split1">
|
||||
<next on="FAILED" to="step3"/>
|
||||
<fail on="COMPLETED" />
|
||||
|
||||
<flow>
|
||||
<step name="step1"/>
|
||||
</flow>
|
||||
@@ -17,6 +20,7 @@
|
||||
<step name="failingStep"/>
|
||||
</flow>
|
||||
</split>
|
||||
<step name="step3"/>
|
||||
</job>
|
||||
|
||||
</beans:beans>
|
||||
Reference in New Issue
Block a user