RESOLVED - issue BATCH-1483: Make the JobParametersValidator instance accessible from the Job interface

This commit is contained in:
dsyer
2010-01-12 09:49:37 +00:00
parent b551563ebe
commit 860e596cba
8 changed files with 107 additions and 22 deletions

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.batch.core;
import org.springframework.batch.core.job.JobParametersValidator;
/**
* Batch domain object representing a job. Job is an explicit abstraction
* representing the configuration of a job specified by a developer. It should
@@ -34,7 +36,7 @@ public interface Job {
* @return true if this job can be restarted after a failure
*/
boolean isRestartable();
/**
* Run the {@link JobExecution} and update the meta information like status
* and statistics as necessary. This method should not throw any exceptions
@@ -54,4 +56,14 @@ public interface Job {
*/
JobParametersIncrementer getJobParametersIncrementer();
/**
* A validator for the job parameters of a {@link JobExecution}. Clients of
* a Job may need to validate the parameters for a launch, before or during
* the execution.
*
* @return a validator that can be used to check parameter values (never
* null)
*/
JobParametersValidator getJobParametersValidator();
}

View File

@@ -18,6 +18,7 @@ package org.springframework.batch.core.configuration.support;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.batch.core.job.JobParametersValidator;
/**
* A {@link Job} that can optionally prepend a group name to another job's name,
@@ -87,6 +88,10 @@ public class GroupAwareJob implements Job {
return delegate.getJobParametersIncrementer();
}
public JobParametersValidator getJobParametersValidator() {
return delegate.getJobParametersValidator();
}
/*
* (non-Javadoc)
*

View File

@@ -157,6 +157,10 @@ public abstract class AbstractJob implements Job, StepLocator, BeanNameAware, In
* @return the step names
*/
public abstract Collection<String> getStepNames();
public JobParametersValidator getJobParametersValidator() {
return jobParametersValidator;
}
/**
* Boolean flag to prevent categorically a job from restarting, even if it

View File

@@ -18,9 +18,32 @@ import org.springframework.util.Assert;
*/
public class DefaultJobParametersValidator implements JobParametersValidator, InitializingBean {
private Collection<String> requiredKeys = new HashSet<String>();
private Collection<String> requiredKeys;
private Collection<String> optionalKeys = new HashSet<String>();
private Collection<String> optionalKeys;
/**
* Convenient default constructor for unconstrained validation.
*/
public DefaultJobParametersValidator() {
this(new String[0], new String[0]);
}
/**
* Create a new validator with the required and optional job parameter keys
* provided.
*
* @see DefaultJobParametersValidator#setOptionalKeys(String[])
* @see DefaultJobParametersValidator#setRequiredKeys(String[])
*
* @param requiredKeys the required keys
* @param optionalKeys the optional keys
*/
public DefaultJobParametersValidator(String[] requiredKeys, String[] optionalKeys) {
super();
setRequiredKeys(requiredKeys);
setOptionalKeys(optionalKeys);
}
/**
* Check that there are no overlaps between required and optional keys.

View File

@@ -52,7 +52,10 @@ import org.springframework.util.Assert;
* Repository can reliably recreate it.
*
* @author Lucas Ward
* @Author Dave Syer
*
* @since 1.0
*
* @see JobRepository
* @see TaskExecutor
*/
@@ -93,21 +96,20 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
if (!job.isRestartable()) {
throw new JobRestartException("JobInstance already exists and is not restartable");
}
else {
/*
* There is a very small probability that a non-restartable job
* can be restarted, but only if another process or thread
* manages to launch <i>and</i> fail a job execution for this
* instance between the last assertion and the next method
* returning successfully.
*/
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
}
}
else {
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
}
// Check the validity of the parameters before doing creating anything
// in the repository...
job.getJobParametersValidator().validate(jobParameters);
/*
* There is a very small probability that a non-restartable job can be
* restarted, but only if another process or thread manages to launch
* <i>and</i> fail a job execution for this instance between the last
* assertion and the next method returning successfully.
*/
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
try {
taskExecutor.execute(new Runnable() {

View File

@@ -22,6 +22,7 @@ import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.job.JobParametersValidator;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
@@ -88,6 +89,10 @@ public class DefaultJobLoaderTests {
return false;
}
public JobParametersValidator getJobParametersValidator() {
return null;
}
}
}

View File

@@ -46,6 +46,8 @@ public class JobSupport implements BeanNameAware, Job {
private int startLimit = Integer.MAX_VALUE;
private DefaultJobParametersValidator jobParametersValidator = new DefaultJobParametersValidator();
/**
* Default constructor.
*/
@@ -97,6 +99,13 @@ public class JobSupport implements BeanNameAware, Job {
public String getName() {
return name;
}
/**
* @param jobParametersValidator the jobParametersValidator to set
*/
public void setJobParametersValidator(DefaultJobParametersValidator jobParametersValidator) {
this.jobParametersValidator = jobParametersValidator;
}
public void setSteps(List<Step> steps) {
this.steps.clear();
@@ -157,4 +166,9 @@ public class JobSupport implements BeanNameAware, Job {
public JobParametersIncrementer getJobParametersIncrementer() {
return null;
}
public JobParametersValidator getJobParametersValidator() {
return jobParametersValidator;
}
}

View File

@@ -33,10 +33,11 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
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.JobParametersInvalidException;
import org.springframework.batch.core.job.DefaultJobParametersValidator;
import org.springframework.batch.core.job.JobSupport;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
@@ -52,7 +53,7 @@ public class SimpleJobLauncherTests {
private SimpleJobLauncher jobLauncher;
private Job job = new JobSupport("foo") {
private JobSupport job = new JobSupport("foo") {
@Override
public void execute(JobExecution execution) {
execution.setExitStatus(ExitStatus.COMPLETED);
@@ -78,11 +79,13 @@ public class SimpleJobLauncherTests {
run(ExitStatus.COMPLETED);
}
private void run(ExitStatus exitStatus) throws Exception {
JobExecution jobExecution = new JobExecution(null, null);
@Test(expected=JobParametersInvalidException.class)
public void testRunWithValidator() throws Exception {
job.setJobParametersValidator(new DefaultJobParametersValidator(new String[] { "missing-and-required" },
new String[0]));
expect(jobRepository.getLastJobExecution(job.getName(), jobParameters)).andReturn(null);
expect(jobRepository.createJobExecution(job.getName(), jobParameters)).andReturn(jobExecution);
replay(jobRepository);
jobLauncher.afterPropertiesSet();
@@ -90,9 +93,9 @@ public class SimpleJobLauncherTests {
jobLauncher.run(job, jobParameters);
}
finally {
assertEquals(exitStatus, jobExecution.getExitStatus());
verify(jobRepository);
}
}
/*
@@ -228,6 +231,23 @@ public class SimpleJobLauncherTests {
jobLauncher.setJobRepository(jobRepository);
jobLauncher.afterPropertiesSet(); // no error
}
private void run(ExitStatus exitStatus) throws Exception {
JobExecution jobExecution = new JobExecution(null, null);
expect(jobRepository.getLastJobExecution(job.getName(), jobParameters)).andReturn(null);
expect(jobRepository.createJobExecution(job.getName(), jobParameters)).andReturn(jobExecution);
replay(jobRepository);
jobLauncher.afterPropertiesSet();
try {
jobLauncher.run(job, jobParameters);
}
finally {
assertEquals(exitStatus, jobExecution.getExitStatus());
verify(jobRepository);
}
}
private boolean contains(String str, String searchStr) {
return str.indexOf(searchStr) != -1;