RESOLVED - issue BATCH-1483: Make the JobParametersValidator instance accessible from the Job interface
This commit is contained in:
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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() {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user