Adding support for multiple configured job names
This commit is contained in:
parent
08d8cb8efd
commit
3ad6c96ce5
|
@ -44,10 +44,14 @@ import org.springframework.jdbc.core.JdbcOperations;
|
|||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Batch. By default all
|
||||
* jobs in the context will be executed on startup (disable this behaviour with
|
||||
* <code>spring.boot.exec.enabled=false</code>). User can supply a job name to execute on
|
||||
* startup with <code>spring.batch.exec.name=...</code>.
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Batch. By default a Runner
|
||||
* will be created and all jobs in the context will be executed on startup.
|
||||
*
|
||||
* Disable this behaviour with <code>spring.batch.job.enabled=false</code>).
|
||||
*
|
||||
* Alternatively, discrete Job names to execute on startup can be supplied by the User with
|
||||
* a comma-delimited list: <code>spring.batch.job.names=job1,job2</code>. In this case the
|
||||
* Runner will first find jobs registered as Beans, then those in the existing JobRegistry.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
|
@ -57,8 +61,8 @@ import org.springframework.util.StringUtils;
|
|||
@ConditionalOnBean(JobLauncher.class)
|
||||
public class BatchAutoConfiguration {
|
||||
|
||||
@Value("${spring.batch.job.name:}")
|
||||
private String jobName;
|
||||
@Value("${spring.batch.job.names:}")
|
||||
private String jobNames;
|
||||
|
||||
@Autowired(required = false)
|
||||
private JobParametersConverter jobParametersConverter;
|
||||
|
@ -74,8 +78,8 @@ public class BatchAutoConfiguration {
|
|||
@ConditionalOnExpression("${spring.batch.job.enabled:true}")
|
||||
public JobLauncherCommandLineRunner jobLauncherCommandLineRunner() {
|
||||
JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner();
|
||||
if (StringUtils.hasText(this.jobName)) {
|
||||
runner.setJobName(this.jobName);
|
||||
if (StringUtils.hasText(this.jobNames)) {
|
||||
runner.setJobNames(this.jobNames);
|
||||
}
|
||||
return runner;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Properties;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobExecutionException;
|
||||
|
@ -31,6 +32,8 @@ import org.springframework.batch.core.configuration.JobRegistry;
|
|||
import org.springframework.batch.core.converter.DefaultJobParametersConverter;
|
||||
import org.springframework.batch.core.converter.JobParametersConverter;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.launch.NoSuchJobException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
@ -60,16 +63,19 @@ public class JobLauncherCommandLineRunner implements CommandLineRunner,
|
|||
|
||||
@Autowired(required = false)
|
||||
private JobRegistry jobRegistry;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
private String jobName;
|
||||
private String jobNames;
|
||||
|
||||
@Autowired(required = false)
|
||||
private final Collection<Job> jobs = Collections.emptySet();
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
public void setJobName(String jobName) {
|
||||
this.jobName = jobName;
|
||||
public void setJobNames(String jobNames) {
|
||||
this.jobNames = jobNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -86,17 +92,28 @@ public class JobLauncherCommandLineRunner implements CommandLineRunner,
|
|||
protected void launchJobFromProperties(Properties properties)
|
||||
throws JobExecutionException {
|
||||
JobParameters jobParameters = this.converter.getJobParameters(properties);
|
||||
executeRegisteredJobs(jobParameters);
|
||||
executeLocalJobs(jobParameters);
|
||||
executeRegisteredJobs(jobParameters);
|
||||
}
|
||||
|
||||
private void executeRegisteredJobs(JobParameters jobParameters)
|
||||
throws JobExecutionException {
|
||||
if (this.jobRegistry != null && StringUtils.hasText(this.jobName)) {
|
||||
Job job = this.jobRegistry.getJob(this.jobName);
|
||||
JobExecution execution = this.jobLauncher.run(job, jobParameters);
|
||||
if (this.publisher != null) {
|
||||
this.publisher.publishEvent(new JobExecutionEvent(execution));
|
||||
if (this.jobRegistry != null && StringUtils.hasText(this.jobNames)) {
|
||||
String[] jobsToRun = this.jobNames.split(",");
|
||||
for (String jobName : jobsToRun) {
|
||||
try {
|
||||
Job job = this.jobRegistry.getJob(jobName);
|
||||
JobExecution previousExecution = jobRepository.getLastJobExecution(jobName, jobParameters);
|
||||
if (previousExecution == null || previousExecution.getStatus() != BatchStatus.COMPLETED) {
|
||||
JobExecution execution = this.jobLauncher.run(job, jobParameters);
|
||||
if (this.publisher != null) {
|
||||
this.publisher.publishEvent(new JobExecutionEvent(execution));
|
||||
}
|
||||
}
|
||||
} catch (NoSuchJobException nsje) {
|
||||
logger.debug("No job found in registry for job name: " + jobName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,8 +121,9 @@ public class JobLauncherCommandLineRunner implements CommandLineRunner,
|
|||
private void executeLocalJobs(JobParameters jobParameters)
|
||||
throws JobExecutionException {
|
||||
for (Job job : this.jobs) {
|
||||
if (StringUtils.hasText(this.jobName)) {
|
||||
if (!PatternMatchUtils.simpleMatch(this.jobName, job.getName())) {
|
||||
if (StringUtils.hasText(this.jobNames)) {
|
||||
String[] jobsToRun = this.jobNames.split(",");
|
||||
if (!PatternMatchUtils.simpleMatch(jobsToRun, job.getName())) {
|
||||
logger.debug("Skipped job: " + job.getName());
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,9 @@ import org.springframework.batch.core.JobExecution;
|
|||
import org.springframework.batch.core.JobExecutionException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.JobRegistry;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor;
|
||||
import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
|
@ -112,6 +114,36 @@ public class BatchAutoConfigurationTests {
|
|||
assertNotNull(this.context.getBean(JobRepository.class).getLastJobExecution(
|
||||
"job", new JobParameters()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefinesAndLaunchesNamedJob() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"spring.batch.job.names:discreteRegisteredJob");
|
||||
this.context.register(NamedJobConfigurationWithRegisteredJob.class, BatchAutoConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertNotNull(this.context.getBean(JobLauncher.class));
|
||||
this.context.getBean(JobLauncherCommandLineRunner.class).run();
|
||||
assertNotNull(this.context.getBean(JobRepository.class).getLastJobExecution(
|
||||
"discreteRegisteredJob", new JobParameters()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefinesAndLaunchesLocalJob() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"spring.batch.job.names:discreteLocalJob");
|
||||
this.context.register(NamedJobConfigurationWithLocalJob.class, BatchAutoConfiguration.class,
|
||||
EmbeddedDataSourceConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertNotNull(this.context.getBean(JobLauncher.class));
|
||||
this.context.getBean(JobLauncherCommandLineRunner.class).run();
|
||||
assertNotNull(this.context.getBean(JobRepository.class).getLastJobExecution(
|
||||
"discreteLocalJob", new JobParameters()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableLaunchesJob() throws Exception {
|
||||
|
@ -170,6 +202,77 @@ public class BatchAutoConfigurationTests {
|
|||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
protected static class NamedJobConfigurationWithRegisteredJob {
|
||||
@Autowired
|
||||
private JobRegistry jobRegistry;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
public JobRegistryBeanPostProcessor registryProcessor() {
|
||||
JobRegistryBeanPostProcessor processor = new JobRegistryBeanPostProcessor();
|
||||
processor.setJobRegistry(jobRegistry);
|
||||
return processor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Job discreteJob() {
|
||||
AbstractJob job = new AbstractJob("discreteRegisteredJob") {
|
||||
|
||||
@Override
|
||||
public Collection<String> getStepNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step getStep(String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecution execution)
|
||||
throws JobExecutionException {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
return job;
|
||||
}
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
protected static class NamedJobConfigurationWithLocalJob {
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
public Job discreteJob() {
|
||||
AbstractJob job = new AbstractJob("discreteLocalJob") {
|
||||
|
||||
@Override
|
||||
public Collection<String> getStepNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step getStep(String stepName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecution execution)
|
||||
throws JobExecutionException {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
return job;
|
||||
}
|
||||
}
|
||||
|
||||
@EnableBatchProcessing
|
||||
protected static class JobConfiguration {
|
||||
@Autowired
|
||||
|
|
Loading…
Reference in New Issue