OPEN - issue BATCH-814: JobRepository should not require Step or Job (only their names)
Fixed the step execution methods (not job execution yet)
This commit is contained in:
@@ -12,16 +12,16 @@ public class ClassPathXmlApplicationContextFactory implements ApplicationContext
|
||||
|
||||
private ConfigurableApplicationContext parent;
|
||||
|
||||
private Resource[] path;
|
||||
private Resource path;
|
||||
|
||||
/**
|
||||
* Setter for the path to the xml to load to create an
|
||||
* {@link ApplicationContext}. Can include wild cards as per the usual
|
||||
* Spring resource resolution.
|
||||
* {@link ApplicationContext}. Use imports to centralise the configuration in
|
||||
* one file.
|
||||
*
|
||||
* @param path the resource path to the xml to load for the child context.
|
||||
*/
|
||||
public void setPath(Resource[] path) {
|
||||
public void setPath(Resource path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ClassPathXmlApplicationContextFactory implements ApplicationContext
|
||||
* @see ApplicationContextFactory#createApplicationContext()
|
||||
*/
|
||||
public ConfigurableApplicationContext createApplicationContext() {
|
||||
if (path==null) {
|
||||
if (path == null) {
|
||||
return parent;
|
||||
}
|
||||
return new ResourceXmlApplicationContext(parent);
|
||||
@@ -49,7 +49,7 @@ public class ClassPathXmlApplicationContextFactory implements ApplicationContext
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
private final class ResourceXmlApplicationContext extends AbstractXmlApplicationContext {
|
||||
/**
|
||||
@@ -61,9 +61,8 @@ public class ClassPathXmlApplicationContextFactory implements ApplicationContext
|
||||
}
|
||||
|
||||
protected Resource[] getConfigResources() {
|
||||
return path;
|
||||
return new Resource[] {path};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class ClassPathXmlJobRegistry implements ListableJobRegistry, Application
|
||||
jobRegistry = new MapJobRegistry();
|
||||
for(Resource resource:jobPaths){
|
||||
ClassPathXmlApplicationContextFactory applicationContextFactory = new ClassPathXmlApplicationContextFactory();
|
||||
applicationContextFactory.setPath(new Resource[]{resource});
|
||||
applicationContextFactory.setPath(resource);
|
||||
applicationContextFactory.setApplicationContext(parent);
|
||||
ApplicationContext context = applicationContextFactory.createApplicationContext();
|
||||
String[] names = context.getBeanNamesForType(Job.class);
|
||||
|
||||
@@ -83,7 +83,7 @@ public class SimpleJob extends AbstractJob {
|
||||
updateStatus(execution, BatchStatus.STARTED);
|
||||
currentStepExecution = execution.createStepExecution(step.getName());
|
||||
|
||||
StepExecution lastStepExecution = getJobRepository().getLastStepExecution(jobInstance, step);
|
||||
StepExecution lastStepExecution = getJobRepository().getLastStepExecution(jobInstance, step.getName());
|
||||
|
||||
boolean isRestart = (lastStepExecution != null && !lastStepExecution.getStatus().equals(
|
||||
BatchStatus.COMPLETED)) ? true : false;
|
||||
@@ -155,7 +155,7 @@ public class SimpleJob extends AbstractJob {
|
||||
|
||||
BatchStatus stepStatus;
|
||||
// if the last execution is null, the step has never been executed.
|
||||
StepExecution lastStepExecution = getJobRepository().getLastStepExecution(jobInstance, step);
|
||||
StepExecution lastStepExecution = getJobRepository().getLastStepExecution(jobInstance, step.getName());
|
||||
if (lastStepExecution == null) {
|
||||
stepStatus = BatchStatus.STARTING;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public class SimpleJob extends AbstractJob {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getJobRepository().getStepExecutionCount(jobInstance, step) < step.getStartLimit()) {
|
||||
if (getJobRepository().getStepExecutionCount(jobInstance, step.getName()) < step.getStartLimit()) {
|
||||
// step start count is less than start max, return true
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ public class JobRegistryBackgroundJobRunner {
|
||||
for (int k = 0; k < names.length; k++) {
|
||||
ClassPathXmlApplicationContextFactory factory = new ClassPathXmlApplicationContextFactory();
|
||||
factory.setApplicationContext(parentContext);
|
||||
factory.setPath(new Resource[] { path });
|
||||
factory.setPath(path);
|
||||
logger.info("Registering Job definition: " + names[k]);
|
||||
registry.register(new ApplicationContextJobFactory(factory, names[k]));
|
||||
}
|
||||
|
||||
@@ -32,16 +32,19 @@ import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple implementation of the {@link JobLauncher} interface. The Spring Core {@link TaskExecutor}
|
||||
* interface is used to launch a {@link Job}. This means that the type of executor set is very
|
||||
* important. If a {@link SyncTaskExecutor} is used, then the job will be processed <strong>within
|
||||
* the same thread that called the launcher.</strong> Care should be taken to ensure any users of
|
||||
* this class understand fully whether or not the implementation of TaskExecutor used will start
|
||||
* tasks synchronously or asynchronously. The default setting uses a synchronous task executor.
|
||||
* Simple implementation of the {@link JobLauncher} interface. The Spring Core
|
||||
* {@link TaskExecutor} interface is used to launch a {@link Job}. This means
|
||||
* that the type of executor set is very important. If a
|
||||
* {@link SyncTaskExecutor} is used, then the job will be processed
|
||||
* <strong>within the same thread that called the launcher.</strong> Care should
|
||||
* be taken to ensure any users of this class understand fully whether or not
|
||||
* the implementation of TaskExecutor used will start tasks synchronously or
|
||||
* asynchronously. The default setting uses a synchronous task executor.
|
||||
*
|
||||
* There is only one required dependency of this Launcher, a {@link JobRepository}. The
|
||||
* JobRepository is used to obtain a valid JobExecution. The Repository must be used because the
|
||||
* provided {@link Job} could be a restart of an existing {@link JobInstance}, and only the
|
||||
* There is only one required dependency of this Launcher, a
|
||||
* {@link JobRepository}. The JobRepository is used to obtain a valid
|
||||
* JobExecution. The Repository must be used because the provided {@link Job}
|
||||
* could be a restart of an existing {@link JobInstance}, and only the
|
||||
* Repository can reliably recreate it.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
@@ -58,20 +61,22 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
private TaskExecutor taskExecutor;
|
||||
|
||||
/**
|
||||
* Run the provided job with the given {@link JobParameters}. The {@link JobParameters} will be
|
||||
* used to determine if this is an execution of an existing job instance, or if a new one should
|
||||
* be created.
|
||||
* Run the provided job with the given {@link JobParameters}. The
|
||||
* {@link JobParameters} will be used to determine if this is an execution
|
||||
* of an existing job instance, or if a new one should be created.
|
||||
*
|
||||
* @param job the job to be run.
|
||||
* @param jobParameters the {@link JobParameters} for this particular execution.
|
||||
* @return JobExecutionAlreadyRunningException if the JobInstance already exists and has an
|
||||
* execution already running.
|
||||
* @throws JobRestartException if the execution would be a re-start, but a re-start is either
|
||||
* not allowed or not needed.
|
||||
* @throws JobInstanceAlreadyCompleteException
|
||||
* @param jobParameters the {@link JobParameters} for this particular
|
||||
* execution.
|
||||
* @return JobExecutionAlreadyRunningException if the JobInstance already
|
||||
* exists and has an execution already running.
|
||||
* @throws JobRestartException if the execution would be a re-start, but a
|
||||
* re-start is either not allowed or not needed.
|
||||
* @throws JobInstanceAlreadyCompleteException if this instance has already
|
||||
* completed successfully
|
||||
*/
|
||||
public JobExecution run(final Job job, final JobParameters jobParameters)
|
||||
throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
|
||||
throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
|
||||
|
||||
Assert.notNull(job, "The Job must not be null.");
|
||||
Assert.notNull(jobParameters, "The JobParameters must not be null.");
|
||||
@@ -85,8 +90,9 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
logger.info("Job: [" + job + "] launched with the following parameters: [" + jobParameters + "]");
|
||||
job.execute(jobExecution);
|
||||
logger.info("Job: [" + job + "] completed successfully with the following parameters: ["
|
||||
+ jobParameters + "]");
|
||||
} catch (Throwable t) {
|
||||
+ jobParameters + "]");
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.info("Job: [" + job + "] failed with the following parameters: [" + jobParameters + "]", t);
|
||||
rethrow(t);
|
||||
}
|
||||
@@ -122,7 +128,8 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the required dependencies of a {@link JobRepository} have been set.
|
||||
* Ensure the required dependencies of a {@link JobRepository} have been
|
||||
* set.
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.state(jobRepository != null, "A JobRepository has not been set.");
|
||||
|
||||
@@ -104,13 +104,15 @@ public interface JobRepository {
|
||||
void updateExecutionContext(StepExecution stepExecution);
|
||||
|
||||
/**
|
||||
* @param stepName the name of the step execution that might have run.
|
||||
* @return the last execution of step for the given job instance.
|
||||
*/
|
||||
StepExecution getLastStepExecution(JobInstance jobInstance, Step step);
|
||||
StepExecution getLastStepExecution(JobInstance jobInstance, String stepName);
|
||||
|
||||
/**
|
||||
* @param stepName the name of the step execution that might have run.
|
||||
* @return the execution count of the step within the given job instance.
|
||||
*/
|
||||
int getStepExecutionCount(JobInstance jobInstance, Step step);
|
||||
int getStepExecutionCount(JobInstance jobInstance, String stepName);
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
@@ -270,11 +269,11 @@ public class SimpleJobRepository implements JobRepository {
|
||||
/**
|
||||
* @return the last execution of the step within given job instance
|
||||
*/
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, Step step) {
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
|
||||
List<JobExecution> jobExecutions = jobExecutionDao.findJobExecutions(jobInstance);
|
||||
List<StepExecution> stepExecutions = new ArrayList<StepExecution>(jobExecutions.size());
|
||||
for (JobExecution jobExecution : jobExecutions) {
|
||||
StepExecution stepExecution = stepExecutionDao.getStepExecution(jobExecution, step.getName());
|
||||
StepExecution stepExecution = stepExecutionDao.getStepExecution(jobExecution, stepName);
|
||||
if (stepExecution != null) {
|
||||
stepExecutions.add(stepExecution);
|
||||
}
|
||||
@@ -298,11 +297,11 @@ public class SimpleJobRepository implements JobRepository {
|
||||
/**
|
||||
* @return number of executions of the step within given job instance
|
||||
*/
|
||||
public int getStepExecutionCount(JobInstance jobInstance, Step step) {
|
||||
public int getStepExecutionCount(JobInstance jobInstance, String stepName) {
|
||||
int count = 0;
|
||||
List<JobExecution> jobExecutions = jobExecutionDao.findJobExecutions(jobInstance);
|
||||
for (JobExecution jobExecution : jobExecutions) {
|
||||
if (stepExecutionDao.getStepExecution(jobExecution, step.getName()) != null) {
|
||||
if (stepExecutionDao.getStepExecution(jobExecution, stepName) != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -31,12 +30,12 @@ public class ClassPathXmlApplicationContextFactoryTests extends TestCase {
|
||||
private ClassPathXmlApplicationContextFactory factory = new ClassPathXmlApplicationContextFactory();
|
||||
|
||||
public void testCreateJob() {
|
||||
factory.setPath(new Resource[] {new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml"))});
|
||||
factory.setPath(new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml")));
|
||||
assertNotNull(factory.createApplicationContext());
|
||||
}
|
||||
|
||||
public void testGetJobName() {
|
||||
factory.setPath(new Resource[] {new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml"))});
|
||||
factory.setPath(new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml")));
|
||||
assertEquals("test-job", factory.createApplicationContext().getBeanNamesForType(Job.class)[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,8 +123,8 @@ public class SimpleJobRepositoryIntegrationTests {
|
||||
jobRepository.update(firstJobExec);
|
||||
jobRepository.add(firstStepExec);
|
||||
|
||||
assertEquals(1, jobRepository.getStepExecutionCount(firstJobExec.getJobInstance(), step));
|
||||
assertEquals(firstStepExec, jobRepository.getLastStepExecution(firstJobExec.getJobInstance(), step));
|
||||
assertEquals(1, jobRepository.getStepExecutionCount(firstJobExec.getJobInstance(), step.getName()));
|
||||
assertEquals(firstStepExec, jobRepository.getLastStepExecution(firstJobExec.getJobInstance(), step.getName()));
|
||||
|
||||
// first execution failed
|
||||
firstJobExec.setStartTime(new Date(4));
|
||||
@@ -142,8 +142,8 @@ public class SimpleJobRepositoryIntegrationTests {
|
||||
jobRepository.update(secondJobExec);
|
||||
jobRepository.add(secondStepExec);
|
||||
|
||||
assertEquals(2, jobRepository.getStepExecutionCount(secondJobExec.getJobInstance(), step));
|
||||
assertEquals(secondStepExec, jobRepository.getLastStepExecution(secondJobExec.getJobInstance(), step));
|
||||
assertEquals(2, jobRepository.getStepExecutionCount(secondJobExec.getJobInstance(), step.getName()));
|
||||
assertEquals(secondStepExec, jobRepository.getLastStepExecution(secondJobExec.getJobInstance(), step.getName()));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,7 +166,7 @@ public class SimpleJobRepositoryIntegrationTests {
|
||||
jobRepository.add(stepExec);
|
||||
jobRepository.updateExecutionContext(stepExec);
|
||||
|
||||
StepExecution retrievedStepExec = jobRepository.getLastStepExecution(jobExec.getJobInstance(), step);
|
||||
StepExecution retrievedStepExec = jobRepository.getLastStepExecution(jobExec.getJobInstance(), step.getName());
|
||||
assertEquals(stepExec, retrievedStepExec);
|
||||
assertEquals(ctx, retrievedStepExec.getExecutionContext());
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
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;
|
||||
|
||||
@@ -48,11 +47,11 @@ public class JobRepositorySupport implements JobRepository {
|
||||
public void update(JobInstance job) {
|
||||
}
|
||||
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, Step step) {
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getStepExecutionCount(JobInstance jobInstance, Step step) {
|
||||
public int getStepExecutionCount(JobInstance jobInstance, String stepName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ public class ChunkOrientedStepIntegrationTests {
|
||||
catch (RuntimeException e) {
|
||||
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobExecution.getJobInstance(), step);
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobExecution.getJobInstance(), step.getName());
|
||||
assertEquals(lastStepExecution, stepExecution);
|
||||
assertFalse(lastStepExecution == stepExecution);
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class StepExecutionMessageHandler {
|
||||
StepExecution stepExecution = jobExecution.createStepExecution(step.getName());
|
||||
try {
|
||||
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, step);
|
||||
StepExecution lastStepExecution = jobRepository.getLastStepExecution(jobInstance, step.getName());
|
||||
|
||||
// Even if it completed successfully we want to pass on the output
|
||||
// attributes, so set up the execution context here if it is
|
||||
@@ -176,7 +176,7 @@ public class StepExecutionMessageHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (jobRepository.getStepExecutionCount(lastStepExecution.getJobExecution().getJobInstance(), step) < step
|
||||
if (jobRepository.getStepExecutionCount(lastStepExecution.getJobExecution().getJobInstance(), step.getName()) < step
|
||||
.getStartLimit()) {
|
||||
// step start count is less than start max, return true
|
||||
return true;
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInstance;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
@@ -43,14 +42,14 @@ public class JobRepositorySupport implements JobRepository {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.repository.JobRepository#getLastStepExecution(org.springframework.batch.core.JobInstance, org.springframework.batch.core.Step)
|
||||
*/
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, Step step) {
|
||||
public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.repository.JobRepository#getStepExecutionCount(org.springframework.batch.core.JobInstance, org.springframework.batch.core.Step)
|
||||
*/
|
||||
public int getStepExecutionCount(JobInstance jobInstance, Step step) {
|
||||
public int getStepExecutionCount(JobInstance jobInstance, String stepName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user