BATCH-1053: Moved getStep() logic from AbstractJobTests to Job implementations. Added getStep(String) to AbstractJob. Added getState(String) to Flow.
This commit is contained in:
@@ -125,6 +125,14 @@ public abstract class AbstractJob implements Job, BeanNameAware, InitializingBea
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the step with the given name
|
||||
*
|
||||
* @param stepName
|
||||
* @return the step
|
||||
*/
|
||||
public abstract Step getStep(String stepName);
|
||||
|
||||
/**
|
||||
* Boolean flag to prevent categorically a job from restarting, even if it
|
||||
* has failed previously.
|
||||
|
||||
@@ -60,11 +60,18 @@ public class SimpleJob extends AbstractJob {
|
||||
this.steps.add(step);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the steps currently set for this job
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.AbstractJob#getStep(java.lang.String)
|
||||
*/
|
||||
public List<Step> getSteps(){
|
||||
return steps;
|
||||
public Step getStep(String stepName){
|
||||
for (Step step : this.steps) {
|
||||
if(step.getName().equals(stepName))
|
||||
{
|
||||
return step;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No Step found with name: [" + stepName + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.flow;
|
||||
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -26,6 +28,12 @@ public interface Flow {
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* @param stateName
|
||||
* @return the State in the flow with given name
|
||||
*/
|
||||
public State getState(String stateName);
|
||||
|
||||
/**
|
||||
* @throws FlowExecutionException
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,8 @@ import org.springframework.batch.core.StartLimitExceededException;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
import org.springframework.batch.core.job.flow.support.state.StepState;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -57,11 +59,14 @@ public class FlowJob extends AbstractJob {
|
||||
this.flow = flow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the flow
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.AbstractJob#getStep(java.lang.String)
|
||||
*/
|
||||
public Flow getFlow(){
|
||||
return this.flow;
|
||||
public Step getStep(String stepName){
|
||||
State state = this.flow.getState(stepName);
|
||||
Assert.isInstanceOf(StepState.class, state, "State is not a StepState: [" + stepName + "]");
|
||||
return ((StepState) state).getStep();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionException;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutor;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link Flow} that branches conditionally depending on the exit status of
|
||||
@@ -81,12 +82,14 @@ public class SimpleFlow implements Flow, InitializingBean {
|
||||
this.stateTransitions = stateTransitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stateName
|
||||
* @return state with given name, null if not found
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.flow.Flow#getState(java.lang.String)
|
||||
*/
|
||||
public State getState(String stateName) {
|
||||
return stateMap.get(stateName);
|
||||
State state = stateMap.get(stateName);
|
||||
Assert.notNull(state, "No State found with name: [" + stateName + "]");
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
@@ -170,6 +171,11 @@ public class AbstractJobTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step getStep(String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.batch.core.job.flow.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@@ -203,6 +204,24 @@ public class SimpleFlowTests {
|
||||
assertEquals(FlowExecution.COMPLETED, execution.getStatus());
|
||||
assertEquals("step3", execution.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateExists() throws Exception {
|
||||
flow.setStateTransitions(Collections.singletonList(StateTransition.createEndStateTransition(new StubState(
|
||||
"step1"))));
|
||||
flow.afterPropertiesSet();
|
||||
State state = flow.getState("step1");
|
||||
assertNotNull(state);
|
||||
assertEquals("step1", state.getName());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetStateDoesNotExist() throws Exception {
|
||||
flow.setStateTransitions(Collections.singletonList(StateTransition.createEndStateTransition(new StubState(
|
||||
"step1"))));
|
||||
flow.afterPropertiesSet();
|
||||
flow.getState("bar");
|
||||
}
|
||||
|
||||
private List<StateTransition> collect(StateTransition s1, StateTransition s2) {
|
||||
List<StateTransition> list = new ArrayList<StateTransition>();
|
||||
|
||||
@@ -27,27 +27,24 @@ import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameter;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
import org.springframework.batch.core.job.SimpleJob;
|
||||
import org.springframework.batch.core.job.flow.FlowJob;
|
||||
import org.springframework.batch.core.job.flow.support.SimpleFlow;
|
||||
import org.springframework.batch.core.job.flow.support.State;
|
||||
import org.springframework.batch.core.job.flow.support.state.StepState;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Base class for testing batch jobs. It provides methods for launching an
|
||||
* entire {@link Job}, allowing for end to end testing of individual steps,
|
||||
* without having to run every step in the job. Any test classes inheriting from
|
||||
* this class should make sure they are part of an {@link ApplicationContext},
|
||||
* which is generally expected to be done as part of the Spring test framework.
|
||||
* Furthermore, the {@link ApplicationContext} in which it is a part of is
|
||||
* expected to have one {@link JobLauncher}, {@link JobRepository}, and a
|
||||
* single {@link Job} implementation.
|
||||
* entire {@link AbstractJob}, allowing for end to end testing of individual
|
||||
* steps, without having to run every step in the job. Any test classes
|
||||
* inheriting from this class should make sure they are part of an
|
||||
* {@link ApplicationContext}, which is generally expected to be done as part
|
||||
* of the Spring test framework. Furthermore, the {@link ApplicationContext} in
|
||||
* which it is a part of is expected to have one {@link JobLauncher},
|
||||
* {@link JobRepository}, and a single {@link AbstractJob} implementation.
|
||||
*
|
||||
* <p>
|
||||
* This class also provides the ability to run {@link Step}s from a
|
||||
@@ -74,13 +71,12 @@ public abstract class AbstractJobTests {
|
||||
private JobLauncher launcher;
|
||||
|
||||
@Autowired
|
||||
private Job job;
|
||||
private AbstractJob job;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private StepRunner stepRunner;
|
||||
private Map<String, Step> stepMap;
|
||||
|
||||
/**
|
||||
* @return the job repository
|
||||
@@ -92,7 +88,7 @@ public abstract class AbstractJobTests {
|
||||
/**
|
||||
* @return the job
|
||||
*/
|
||||
public Job getJob() {
|
||||
public AbstractJob getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
@@ -147,69 +143,14 @@ public abstract class AbstractJobTests {
|
||||
* @param stepName
|
||||
*/
|
||||
public JobExecution launchStep(String stepName) {
|
||||
return getStepRunner().launchStep(getStep(stepName));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stepName
|
||||
* @return
|
||||
*/
|
||||
public Step getStep(String stepName) {
|
||||
Job job = getJob();
|
||||
if (job instanceof FlowJob) {
|
||||
return getFlowJobStep(stepName);
|
||||
Step step;
|
||||
try {
|
||||
step = this.job.getStep(stepName);
|
||||
}
|
||||
else if (job instanceof SimpleJob) {
|
||||
return getSimpleJobStep(stepName);
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new IllegalStateException("No Step found with name: [" + stepName + "]", e);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Job is neither a FlowJob or a SimpleJob");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the step from a FlowJob. Throw an exception of the step does not
|
||||
* exist.
|
||||
*
|
||||
* @param stepName
|
||||
* @return the step
|
||||
*/
|
||||
private Step getFlowJobStep(String stepName) {
|
||||
try{
|
||||
State state = ((SimpleFlow) ((FlowJob) getJob()).getFlow()).getState(stepName);
|
||||
Assert.notNull(state, "no matching state found in flow for " + stepName);
|
||||
Assert.isInstanceOf(StepState.class, state);
|
||||
return ((StepState) state).getStep();
|
||||
}
|
||||
catch(IllegalArgumentException e)
|
||||
{
|
||||
throw new IllegalStateException("No Step found with name: [" + stepName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the step from a SimpleJob. Throw an exception of the step does
|
||||
* not exist.
|
||||
*
|
||||
* @param stepName
|
||||
* @return the step
|
||||
*/
|
||||
private Step getSimpleJobStep(String stepName) {
|
||||
if (this.stepMap == null) {
|
||||
//
|
||||
// Populate the step map
|
||||
//
|
||||
SimpleJob simpleJob = (SimpleJob) getJob();
|
||||
this.stepMap = new HashMap<String, Step>();
|
||||
for (Step step : simpleJob.getSteps()) {
|
||||
this.stepMap.put(step.getName(), step);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.stepMap.containsKey(stepName)) {
|
||||
throw new IllegalStateException("No Step found with name: [" + stepName + "]");
|
||||
}
|
||||
return this.stepMap.get(stepName);
|
||||
return getStepRunner().launchStep(step);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,6 +160,6 @@ public abstract class AbstractJobTests {
|
||||
* @param jobParameters
|
||||
*/
|
||||
public JobExecution launchStep(String stepName, JobParameters jobParameters) {
|
||||
return getStepRunner().launchStep(getStep(stepName), jobParameters);
|
||||
return getStepRunner().launchStep(this.job.getStep(stepName), jobParameters);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user