Remove support for multiple batch jobs
Closes gh-25373
This commit is contained in:
@@ -24,6 +24,7 @@ import javax.sql.DataSource;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
@@ -31,6 +32,8 @@ import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.DuplicateJobException;
|
||||
import org.springframework.batch.core.configuration.JobFactory;
|
||||
import org.springframework.batch.core.configuration.JobRegistry;
|
||||
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
|
||||
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
|
||||
@@ -39,7 +42,9 @@ import org.springframework.batch.core.explore.JobExplorer;
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.DefaultApplicationArguments;
|
||||
@@ -60,6 +65,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
@@ -138,11 +144,11 @@ class BatchAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefinesAndLaunchesNamedJob() {
|
||||
void testDefinesAndLaunchesNamedRegisteredJob() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(NamedJobConfigurationWithRegisteredJob.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.names:discreteRegisteredJob").run((context) -> {
|
||||
.withPropertyValues("spring.batch.job.name:discreteRegisteredJob").run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherApplicationRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class).getLastJobExecution("discreteRegisteredJob",
|
||||
@@ -150,11 +156,46 @@ class BatchAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegisteredAndLocalJob() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(NamedJobConfigurationWithRegisteredAndLocalJob.class,
|
||||
EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.name:discreteRegisteredJob").run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherApplicationRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class)
|
||||
.getLastJobExecution("discreteRegisteredJob", new JobParameters()).getStatus())
|
||||
.isEqualTo(BatchStatus.COMPLETED);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefinesAndLaunchesLocalJob() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(NamedJobConfigurationWithLocalJob.class, EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.names:discreteLocalJob").run((context) -> {
|
||||
.withPropertyValues("spring.batch.job.name:discreteLocalJob").run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherApplicationRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class).getLastJobExecution("discreteLocalJob",
|
||||
new JobParameters())).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultipleJobsAndNoJobName() {
|
||||
this.contextRunner.withUserConfiguration(MultipleJobConfiguration.class, EmbeddedDataSourceConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure().getCause().getMessage())
|
||||
.contains("Job name must be specified in case of multiple jobs");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultipleJobsAndJobName() {
|
||||
this.contextRunner.withUserConfiguration(MultipleJobConfiguration.class, EmbeddedDataSourceConfiguration.class)
|
||||
.withPropertyValues("spring.batch.job.name:discreteLocalJob").run((context) -> {
|
||||
assertThat(context).hasSingleBean(JobLauncher.class);
|
||||
context.getBean(JobLauncherApplicationRunner.class).run();
|
||||
assertThat(context.getBean(JobRepository.class).getLastJobExecution("discreteLocalJob",
|
||||
@@ -395,18 +436,15 @@ class BatchAutoConfigurationTests {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBatchProcessing
|
||||
static class NamedJobConfigurationWithRegisteredJob {
|
||||
|
||||
@Autowired
|
||||
private JobRegistry jobRegistry;
|
||||
static class NamedJobConfigurationWithRegisteredAndLocalJob {
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
JobRegistryBeanPostProcessor registryProcessor() {
|
||||
static JobRegistryBeanPostProcessor registryProcessor(JobRegistry jobRegistry) {
|
||||
JobRegistryBeanPostProcessor processor = new JobRegistryBeanPostProcessor();
|
||||
processor.setJobRegistry(this.jobRegistry);
|
||||
processor.setJobRegistry(jobRegistry);
|
||||
return processor;
|
||||
}
|
||||
|
||||
@@ -414,6 +452,8 @@ class BatchAutoConfigurationTests {
|
||||
Job discreteJob() {
|
||||
AbstractJob job = new AbstractJob("discreteRegisteredJob") {
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
@Override
|
||||
public Collection<String> getStepNames() {
|
||||
return Collections.emptySet();
|
||||
@@ -426,7 +466,13 @@ class BatchAutoConfigurationTests {
|
||||
|
||||
@Override
|
||||
protected void doExecute(JobExecution execution) {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
if (count == 0) {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
else {
|
||||
execution.setStatus(BatchStatus.FAILED);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
@@ -435,6 +481,75 @@ class BatchAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBatchProcessing
|
||||
static class NamedJobConfigurationWithRegisteredJob {
|
||||
|
||||
@Bean
|
||||
static BeanPostProcessor registryProcessor(ApplicationContext applicationContext) {
|
||||
return new NamedJobJobRegistryBeanPostProcessor(applicationContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NamedJobJobRegistryBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
NamedJobJobRegistryBeanPostProcessor(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof JobRegistry jobRegistry) {
|
||||
try {
|
||||
jobRegistry.register(getJobFactory());
|
||||
}
|
||||
catch (DuplicateJobException ex) {
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private JobFactory getJobFactory() {
|
||||
JobRepository jobRepository = this.applicationContext.getBean(JobRepository.class);
|
||||
return new JobFactory() {
|
||||
|
||||
@Override
|
||||
public Job createJob() {
|
||||
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) {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
};
|
||||
job.setJobRepository(jobRepository);
|
||||
return job;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJobName() {
|
||||
return "discreteRegisteredJob";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBatchProcessing
|
||||
static class NamedJobConfigurationWithLocalJob {
|
||||
@@ -467,6 +582,43 @@ class BatchAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBatchProcessing
|
||||
static class MultipleJobConfiguration {
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Bean
|
||||
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) {
|
||||
execution.setStatus(BatchStatus.COMPLETED);
|
||||
}
|
||||
};
|
||||
job.setJobRepository(this.jobRepository);
|
||||
return job;
|
||||
}
|
||||
|
||||
@Bean
|
||||
Job job2() {
|
||||
return Mockito.mock(Job.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableBatchProcessing
|
||||
static class JobConfiguration {
|
||||
|
||||
Reference in New Issue
Block a user