Update Task to BOOT 2.1.M1

Migrating to use ApplicationContextRunner or ImportAutoConfiguration with SpringApp.run, instead of SpringApplicationBuilder, because builder does not handle AutoConfiguration properly

SimpleTaskAutoConfiguration now has an annotation AutoConfigureBefore the BatchTaskAutoConfig so that it is processed prior.  THis is so that that BatchTaskAutoConfig can create the appropriate beans

SimpleTaskAutoConfiguration has new annotations so that it is AutoConfigured after BindingServiceConfiguration and after SimpleTaskAutoConfiguration.  This is so that it does not attempt to start emitting messages before stream is ready and it can create the appropriate beans after SimpleTaskAutoConfiguration has run.

Renamed SimpleTaskConfiguration to SimpleTaskAutoConfiguration.

Task version updated to  2.1.0

Added missing headers

Updated documentation.

Deprecated EnableTask

Added ability to disable Task autoconfiguration.

Removed @EnableTask from tests

Resolves #439
Resolves #440
Resolves #448
Resolves #466
This commit is contained in:
Glenn Renfro
2018-08-09 17:54:56 -04:00
committed by Michael Minella
parent d2c90c5256
commit d2bc2530cc
70 changed files with 1381 additions and 801 deletions

View File

@@ -37,12 +37,27 @@ public class TaskBatchProperties {
private String jobNames = "";
/**
* The order for the {@coce CommandLineRunner} used to run batch jobs when
* The order for the {@code CommandLineRunner} used to run batch jobs when
* {@code spring.cloud.task.batch.fail-on-job-failure=true}. Defaults to 0 (same as the
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner}).
*/
private int commandLineRunnerOrder = 0;
/**
* Maximum wait time in milliseconds that Spring Cloud Task will wait for tasks to complete
* when spring.cloud.task.batch.failOnJobFailure is set to true. Defaults
* to 0. 0 indicates no wait time is enforced.
*/
private long failOnJobFailurewaitTime = 0;
/**
* Fixed delay in milliseconds that Spring Cloud Task will wait when checking if
* {@link org.springframework.batch.core.JobExecution}s have completed,
* when spring.cloud.task.batch.failOnJobFailure is set to true. Defaults
* to 5000.
*/
private long failOnJobFailurePollInterval = 5000l;
public String getJobNames() {
return this.jobNames;
}
@@ -58,4 +73,20 @@ public class TaskBatchProperties {
public void setCommandLineRunnerOrder(int commandLineRunnerOrder) {
this.commandLineRunnerOrder = commandLineRunnerOrder;
}
public long getFailOnJobFailurewaitTime() {
return failOnJobFailurewaitTime;
}
public void setFailOnJobFailurewaitTime(long failOnJobFailurewaitTime) {
this.failOnJobFailurewaitTime = failOnJobFailurewaitTime;
}
public long getFailOnJobFailurePollInterval() {
return failOnJobFailurePollInterval;
}
public void setFailOnJobFailurePollInterval(long failOnJobFailurePollInterval) {
this.failOnJobFailurePollInterval = failOnJobFailurePollInterval;
}
}

View File

@@ -18,11 +18,19 @@ package org.springframework.cloud.task.batch.configuration;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -37,22 +45,31 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(name = "spring.cloud.task.batch.fail-on-job-failure", havingValue = "true", matchIfMissing = false)
@EnableConfigurationProperties(TaskBatchProperties.class)
@AutoConfigureBefore(BatchAutoConfiguration.class)
public class TaskJobLauncherAutoConfiguration {
@Autowired
private TaskBatchProperties properties;
@Bean
@ConditionalOnMissingBean(JobRepository.class)
public JobRepository jobRepository(DataSource dataSource) throws Exception{
JobRepositoryFactoryBean factoryBean = new JobRepositoryFactoryBean();
factoryBean.setDataSource(dataSource);
return factoryBean.getObject();
}
@Bean
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(JobLauncher jobLauncher,
JobExplorer jobExplorer, List<Job> jobs, JobRegistry jobRegistry) {
JobExplorer jobExplorer, List<Job> jobs, JobRegistry jobRegistry, JobRepository jobRepository) {
TaskJobLauncherCommandLineRunnerFactoryBean taskJobLauncherCommandLineRunnerFactoryBean =
new TaskJobLauncherCommandLineRunnerFactoryBean(jobLauncher,
jobExplorer,
jobs,
this.properties.getJobNames(),
jobRegistry);
taskJobLauncherCommandLineRunnerFactoryBean.setOrder(this.properties.getCommandLineRunnerOrder());
this.properties,
jobRegistry,
jobRepository);
return taskJobLauncherCommandLineRunnerFactoryBean;
}

View File

@@ -22,6 +22,7 @@ import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner;
import org.springframework.util.Assert;
@@ -46,15 +47,23 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
private Integer order = 0;
private TaskBatchProperties taskBatchProperties;
private JobRepository jobRepository;
public TaskJobLauncherCommandLineRunnerFactoryBean(JobLauncher jobLauncher,
JobExplorer jobExplorer, List<Job> jobs, String jobNames,
JobRegistry jobRegistry) {
JobExplorer jobExplorer, List<Job> jobs, TaskBatchProperties taskBatchProperties,
JobRegistry jobRegistry, JobRepository jobRepository) {
Assert.notNull(taskBatchProperties, "properties must not be null");
this.jobLauncher = jobLauncher;
this.jobExplorer = jobExplorer;
Assert.notEmpty(jobs, "jobs must not be null nor empty");
this.jobs = jobs;
this.jobNames = jobNames;
this.jobNames = taskBatchProperties.getJobNames();
this.jobRegistry = jobRegistry;
this.taskBatchProperties = taskBatchProperties;
this.order = taskBatchProperties.getCommandLineRunnerOrder();
this.jobRepository = jobRepository;
}
public void setOrder(int order) {
@@ -62,9 +71,9 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
}
@Override
public TaskJobLauncherCommandLineRunner getObject() throws Exception {
public TaskJobLauncherCommandLineRunner getObject() {
TaskJobLauncherCommandLineRunner taskJobLauncherCommandLineRunner =
new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer);
new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer, this.jobRepository, this.taskBatchProperties);
taskJobLauncherCommandLineRunner.setJobs(this.jobs);
if(StringUtils.hasText(this.jobNames)) {
taskJobLauncherCommandLineRunner.setJobNames(this.jobNames);
@@ -74,7 +83,6 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
if(this.order != null) {
taskJobLauncherCommandLineRunner.setOrder(this.order);
}
return taskJobLauncherCommandLineRunner;
}
@@ -82,4 +90,5 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
public Class<?> getObjectType() {
return TaskJobLauncherCommandLineRunner.class;
}
}

View File

@@ -16,177 +16,218 @@
package org.springframework.cloud.task.batch.handler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.batch.core.JobParametersInvalidException;
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.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.JobParametersNotFoundException;
import org.springframework.batch.core.launch.NoSuchJobException;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.batch.JobExecutionEvent;
import org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner;
import org.springframework.cloud.task.batch.configuration.TaskBatchProperties;
import org.springframework.cloud.task.listener.TaskException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.core.Ordered;
import org.springframework.util.PatternMatchUtils;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.StringUtils;
/**
* {@link CommandLineRunner} to {@link JobLauncher launch} Spring Batch jobs. Runs all
* jobs in the surrounding context by default and throw an exception upon the
* first job that returns an {@link ExitStatus} of FAILED.
* Can also be used to launch a specific job by providing a jobName. The
* TaskJobLaunchercommandLineRunner takes the place of the
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner}
* when it is in use.
* jobs in the surrounding context by default and throws an exception upon the first job
* that returns an {@link BatchStatus} of FAILED if a {@link TaskExecutor} in the
* {@link JobLauncher} is not specified. If a {@link TaskExecutor} is specified
* in the {@link JobLauncher} then all Jobs are launched and an
* exception is thrown if one or more of the jobs has an {@link BatchStatus} of FAILED.
* TaskJobLauncherCommandLineRunner can also be used to launch a specific job by
* providing a jobName. The TaskJobLaunchercommandLineRunner takes the place of the
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner} when
* it is in use.
*
* @author Glenn Renfro
* @since 2.0.0
*/
public class TaskJobLauncherCommandLineRunner implements CommandLineRunner, Ordered, ApplicationEventPublisherAware{
/**
* The default order for the command line runner.
*/
public static final int DEFAULT_ORDER = 0;
public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunner {
private JobLauncher taskJobLauncher;
private JobExplorer taskJobExplorer;
private JobRepository taskJobRepository;
private static final Log logger = LogFactory
.getLog(TaskJobLauncherCommandLineRunner.class);
private JobParametersConverter converter = new DefaultJobParametersConverter();
private List<JobExecution> jobExecutionList = new ArrayList<>();
private JobLauncher jobLauncher;
private ApplicationEventPublisher taskApplicationEventPublisher;
private JobRegistry jobRegistry;
private TaskBatchProperties taskBatchProperties;
private JobExplorer jobExplorer;
private String jobNames;
private Collection<Job> jobs = Collections.emptySet();
private int order = DEFAULT_ORDER;
private ApplicationEventPublisher publisher;
public TaskJobLauncherCommandLineRunner(JobLauncher jobLauncher,
JobExplorer jobExplorer) {
this.jobLauncher = jobLauncher;
this.jobExplorer = jobExplorer;
/**
* Create a new {@link TaskJobLauncherCommandLineRunner}.
* @param jobLauncher to launch jobs
* @param jobExplorer to check the job repository for previous executions
* @param jobRepository to check if a job instance exists with the given parameters
* when running a job
* @param taskBatchProperties the properties used to configure the taskBatchProperties.
*/
public TaskJobLauncherCommandLineRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
JobRepository jobRepository, TaskBatchProperties taskBatchProperties) {
super(jobLauncher, jobExplorer, jobRepository);
this.taskJobLauncher = jobLauncher;
this.taskJobExplorer = jobExplorer;
this.taskJobRepository = jobRepository;
this.taskBatchProperties = taskBatchProperties;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void setJobRegistry(JobRegistry jobRegistry) {
this.jobRegistry = jobRegistry;
}
public void setJobNames(String jobNames) {
this.jobNames = jobNames;
}
public void setJobParametersConverter(JobParametersConverter converter) {
this.converter = converter;
}
public void setJobs(Collection<Job> jobs) {
this.jobs = jobs;
super.setApplicationEventPublisher(publisher);
this.taskApplicationEventPublisher = publisher;
}
@Override
public void run(String... args) throws JobExecutionException {
logger.info("Running default command line with: " + Arrays.asList(args));
launchJobFromProperties(StringUtils.splitArrayElementsIntoProperties(args, "="));
}
protected void launchJobFromProperties(Properties properties)
throws JobExecutionException {
JobParameters jobParameters = this.converter.getJobParameters(properties);
executeLocalJobs(jobParameters);
executeRegisteredJobs(jobParameters);
}
private void executeRegisteredJobs(JobParameters jobParameters)
throws JobExecutionException {
if (this.jobRegistry != null && StringUtils.hasText(this.jobNames)) {
String[] jobsToRun = this.jobNames.split(",");
for (String jobName : jobsToRun) {
try {
Job job = this.jobRegistry.getJob(jobName);
if (this.jobs.contains(job)) {
continue;
}
execute(job, jobParameters);
}
catch (NoSuchJobException ex) {
logger.debug("No job found in registry for job name: " + jobName);
}
}
}
validateJobExecutions();
}
protected void execute(Job job, JobParameters jobParameters)
throws JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException, JobParametersInvalidException,
JobParametersNotFoundException {
JobParameters nextParameters = new JobParametersBuilder(jobParameters,
this.jobExplorer).getNextJobParameters(job).toJobParameters();
JobExecution execution = this.jobLauncher.run(job, nextParameters);
if (this.publisher != null) {
this.publisher.publishEvent(new JobExecutionEvent(execution));
JobInstanceAlreadyCompleteException, JobParametersInvalidException {
String jobName = job.getName();
JobParameters parameters = jobParameters;
boolean jobInstanceExists = this.taskJobRepository.isJobInstanceExists(jobName,
parameters);
if (jobInstanceExists) {
JobExecution lastJobExecution = this.taskJobRepository
.getLastJobExecution(jobName, jobParameters);
if (lastJobExecution != null && isStoppedOrFailed(lastJobExecution)
&& job.isRestartable()) {
// Retry a failed or stopped execution with previous parameters
JobParameters previousParameters = lastJobExecution.getJobParameters();
/*
* remove Non-identifying parameters from the previous execution's
* parameters since there is no way to remove them programmatically. If
* they are required (or need to be modified) on a restart, they need to
* be (re)specified.
*/
JobParameters previousIdentifyingParameters = removeNonIdentifying(
previousParameters);
// merge additional parameters with previous ones (overriding those with
// the same key)
parameters = merge(previousIdentifyingParameters, jobParameters);
}
}
if(execution.getExitStatus().getExitCode().equals(ExitStatus.FAILED.getExitCode())) {
String message = String.format("Job %s failed during " +
"execution for jobId %s with jobExecutionId of %s",
execution.getJobInstance().getJobName(),
execution.getJobId(), execution.getId());
logger.error(message);
throw new TaskException(message);
else {
JobParametersIncrementer incrementer = job.getJobParametersIncrementer();
if (incrementer != null) {
JobParameters nextParameters = new JobParametersBuilder(jobParameters,
this.taskJobExplorer).getNextJobParameters(job).toJobParameters();
parameters = merge(nextParameters, jobParameters);
}
}
JobExecution execution = this.taskJobLauncher.run(job, parameters);
if (this.taskApplicationEventPublisher != null) {
this.taskApplicationEventPublisher.publishEvent(new JobExecutionEvent(execution));
}
this.jobExecutionList.add(execution);
if (execution.getStatus().equals(BatchStatus.FAILED)) {
throwJobFailedException(Collections.singletonList(execution));
}
}
private void executeLocalJobs(JobParameters jobParameters)
throws JobExecutionException {
for (Job job : this.jobs) {
if (StringUtils.hasText(this.jobNames)) {
String[] jobsToRun = this.jobNames.split(",");
if (!PatternMatchUtils.simpleMatch(jobsToRun, job.getName())) {
logger.debug("Skipped job: " + job.getName());
continue;
private void validateJobExecutions() {
RepeatTemplate template = new RepeatTemplate();
Date startDate = new Date();
template.iterate(new RepeatCallback() {
public RepeatStatus doInIteration(RepeatContext context) throws InterruptedException {
List<JobExecution> failedJobExecutions = new ArrayList<>();
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
for (JobExecution jobExecution : jobExecutionList) {
JobExecution currentJobExecution = taskJobExplorer.getJobExecution(jobExecution.getId());
BatchStatus batchStatus = currentJobExecution.getStatus();
if (batchStatus.isRunning()) {
repeatStatus = RepeatStatus.CONTINUABLE;
}
if (batchStatus.equals(BatchStatus.FAILED)) {
failedJobExecutions.add(jobExecution);
}
}
Thread.sleep(taskBatchProperties.getFailOnJobFailurePollInterval());
if (repeatStatus.equals(RepeatStatus.FINISHED) && failedJobExecutions.size() > 0) {
throwJobFailedException(failedJobExecutions);
}
if (repeatStatus.isContinuable() && taskBatchProperties.getFailOnJobFailurewaitTime() != 0
&& (new Date()).getTime() - startDate.getTime() > taskBatchProperties.getFailOnJobFailurewaitTime()) {
throw new IllegalStateException("Not all jobs were completed " +
"within the time specified by spring.cloud.task.batch." +
"failOnJobFailurewaitTime.");
}
return repeatStatus;
}
execute(job, jobParameters);
});
}
public void throwJobFailedException(List<JobExecution> failedJobExecutions) {
String message = "The following Jobs have failed: \n";
for (JobExecution failedJobExecution : failedJobExecutions) {
message += String.format("Job %s failed during " +
"execution for jobId %s with jobExecutionId of %s \n",
failedJobExecution.getJobInstance().getJobName(),
failedJobExecution.getJobId(), failedJobExecution.getId());
}
logger.error(message);
throw new TaskException(message);
}
private JobParameters removeNonIdentifying(JobParameters parameters) {
Map<String, JobParameter> parameterMap = parameters.getParameters();
HashMap<String, JobParameter> copy = new HashMap<>(parameterMap);
for (Map.Entry<String, JobParameter> parameter : copy.entrySet()) {
if (!parameter.getValue().isIdentifying()) {
parameterMap.remove(parameter.getKey());
}
}
return new JobParameters(parameterMap);
}
private boolean isStoppedOrFailed(JobExecution execution) {
BatchStatus status = execution.getStatus();
return (status == BatchStatus.STOPPED || status == BatchStatus.FAILED);
}
private JobParameters merge(JobParameters parameters, JobParameters additionals) {
Map<String, JobParameter> merged = new HashMap<>();
merged.putAll(parameters.getParameters());
merged.putAll(additionals.getParameters());
return new JobParameters(merged);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.configuration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
/**
* Contains the common configurations to run a unit test for the task batch features of
* SCT.
*
* @author Glenn Renfro
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ImportAutoConfiguration
public @interface TaskBatchTest {
}

View File

@@ -42,13 +42,10 @@ public class TaskJobLauncherAutoConfigurationTests {
@Test
public void testAutoBuiltDataSourceWithTaskJobLauncherCLR() {
this.contextRunner.
withPropertyValues("spring.cloud.task.batch.fail-on-job-failure=true").
run(context -> {
this.contextRunner.withPropertyValues("spring.cloud.task.batch.fail-on-job-failure=true").run(context -> {
assertThat(context).hasSingleBean(TaskJobLauncherCommandLineRunner.class);
assertThat(context).doesNotHaveBean(JobLauncherCommandLineRunner.class);
assertThat(context.getBean(TaskJobLauncherCommandLineRunner.class)
.getOrder())
assertThat(context.getBean(TaskJobLauncherCommandLineRunner.class)
.getOrder())
.isEqualTo(0);
});
}

View File

@@ -16,11 +16,16 @@
package org.springframework.cloud.task.batch.handler;
import org.assertj.core.api.AssertionsForClassTypes;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.function.Executable;
import org.junit.runner.RunWith;
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.JobParametersBuilder;
import org.springframework.batch.core.Step;
@@ -34,10 +39,12 @@ import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.task.batch.configuration.TaskBatchProperties;
import org.springframework.cloud.task.listener.TaskException;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SyncTaskExecutor;
@@ -47,6 +54,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.PlatformTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Glenn Renfro
@@ -64,6 +72,9 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
@Autowired
private JobExplorer jobExplorer;
@Autowired
private BatchConfiguration batchConfigurer;
@Autowired
private PlatformTransactionManager transactionManager;
@@ -79,12 +90,14 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
@Before
public void init() {
batchConfigurer.clear();
this.jobs = new JobBuilderFactory(this.jobRepository);
this.steps = new StepBuilderFactory(this.jobRepository, this.transactionManager);
Tasklet tasklet = (contribution, chunkContext) -> null;
this.step = this.steps.get("step").tasklet(tasklet).build();
this.job = this.jobs.get("job").start(this.step).build();
this.runner = new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer);
this.runner = new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer, jobRepository, new TaskBatchProperties());
}
@@ -115,10 +128,27 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
.start(this.steps.get("step").tasklet(throwingTasklet()).build())
.incrementer(new RunIdIncrementer()).build();
runFailedJob(new JobParameters());
runFailedJob(new JobParameters());
runFailedJob(new JobParametersBuilder().addLong("run.id", 1L).toJobParameters());
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
}
@Test
public void runDifferentInstances() throws Exception {
this.job = this.jobs.get("job")
.start(this.steps.get("step").tasklet(throwingTasklet()).build()).build();
// start a job instance
JobParameters jobParameters = new JobParametersBuilder().addString("name", "foo")
.toJobParameters();
runFailedJob(jobParameters);
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
// start a different job instance
JobParameters otherJobParameters = new JobParametersBuilder()
.addString("name", "bar").toJobParameters();
runFailedJob(otherJobParameters);
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
}
@DirtiesContext
@Test
public void retryFailedExecutionOnNonRestartableJob() throws Exception {
@@ -130,6 +160,15 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
// A failed job that is not restartable does not re-use the job params of
// the last execution, but creates a new job instance when running it again.
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
// try to re-run a failed execution
Executable executable = () -> {
this.runner.execute(this.job,
new JobParametersBuilder().addLong("run.id", 1L).toJobParameters());
};
Throwable exception = assertThrows(JobRestartException.class, executable);
AssertionsForClassTypes.assertThat(exception.getMessage())
.isEqualTo("JobInstance already exists and is not restartable");
}
@DirtiesContext
@@ -140,11 +179,47 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
.incrementer(new RunIdIncrementer()).build();
JobParameters jobParameters = new JobParametersBuilder().addLong("id", 1L, false)
.addLong("foo", 2L, false).toJobParameters();
runFailedJob(new JobParameters());
runFailedJob(new JobParameters());
runFailedJob(jobParameters);
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
runFailedJob(new JobParametersBuilder(jobParameters)
.addLong("run.id", 1L).toJobParameters());
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
}
@Test
public void retryFailedExecutionWithDifferentNonIdentifyingParametersFromPreviousExecution()
throws Exception {
this.job = this.jobs.get("job")
.start(this.steps.get("step").tasklet(throwingTasklet()).build())
.incrementer(new RunIdIncrementer()).build();
JobParameters jobParameters = new JobParametersBuilder().addLong("id", 1L, false)
.addLong("foo", 2L, false).toJobParameters();
runFailedJob(jobParameters);
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
// try to re-run a failed execution with non identifying parameters
runFailedJob( new JobParametersBuilder().addLong("run.id", 1L)
.addLong("id", 2L, false).addLong("foo", 3L, false).toJobParameters());
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
JobInstance jobInstance = this.jobExplorer.getJobInstance(0L);
assertThat(this.jobExplorer.getJobExecutions(jobInstance)).hasSize(2);
// first execution
JobExecution firstJobExecution = this.jobExplorer.getJobExecution(0L);
JobParameters parameters = firstJobExecution.getJobParameters();
assertThat(parameters.getLong("run.id")).isEqualTo(1L);
assertThat(parameters.getLong("id")).isEqualTo(1L);
assertThat(parameters.getLong("foo")).isEqualTo(2L);
// second execution
JobExecution secondJobExecution = this.jobExplorer.getJobExecution(1L);
parameters = secondJobExecution.getJobParameters();
// identifying parameters should be the same as previous execution
assertThat(parameters.getLong("run.id")).isEqualTo(1L);
// non-identifying parameters should be the newly specified ones
assertThat(parameters.getLong("id")).isEqualTo(2L);
assertThat(parameters.getLong("foo")).isEqualTo(3L);
}
private Tasklet throwingTasklet() {
return (contribution, chunkContext) -> {
throw new RuntimeException("Planned");
@@ -154,7 +229,7 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
private void runFailedJob(JobParameters jobParameters) throws Exception {
boolean isExceptionThrown = false;
try {
this.runner.execute(this.job, new JobParameters());
this.runner.execute(this.job, jobParameters);
}
catch (TaskException taskException) {
isExceptionThrown = true;

View File

@@ -18,36 +18,49 @@ package org.springframework.cloud.task.batch.handler;
import java.util.Set;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Test;
import org.junit.jupiter.api.function.Executable;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration;
import org.springframework.cloud.task.batch.configuration.TaskJobLauncherAutoConfiguration;
import org.springframework.cloud.task.batch.configuration.TaskBatchTest;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Glenn Renfro
@@ -56,6 +69,9 @@ public class TaskJobLauncherCommandLineRunnerTests {
private ConfigurableApplicationContext applicationContext;
private static final String DEFAULT_ERROR_MESSAGE = "The following Jobs have failed: \n" +
"Job jobA failed during execution for jobId 1 with jobExecutionId of 1 \n";
@After
public void tearDown() {
if (this.applicationContext != null) {
@@ -65,37 +81,55 @@ public class TaskJobLauncherCommandLineRunnerTests {
@Test
public void testTaskJobLauncherCLRSuccessFail() {
String[] enabledArgs = new String[] { "--spring.cloud.task.batch.fail-on-job-failure=true" };
boolean isExceptionThrown = false;
try {
this.applicationContext = SpringApplication
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class,
TaskJobLauncherAutoConfiguration.class }, enabledArgs);
}
catch (IllegalStateException exception) {
isExceptionThrown = true;
}
assertThat(isExceptionThrown).isTrue();
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.failOnJobFailure=true"};
validateForFail(DEFAULT_ERROR_MESSAGE, TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class,
enabledArgs);
}
/**
* Verifies that the task will return an exit code other than zero if the
* job fails with the deprecated EnableTask annotation.
*/
@Test
public void testTaskJobLauncherCLRSuccessFailWithAnnotation() {
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.failOnJobFailure=true"};
validateForFail(DEFAULT_ERROR_MESSAGE, TaskJobLauncherCommandLineRunnerTests.JobWithFailureAnnotatedConfiguration.class,
enabledArgs);
}
@Test
public void testTaskJobLauncherCLRSuccessFailWithTaskExecutor() {
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.failOnJobFailure=true",
"--spring.cloud.task.batch.failOnJobFailurePollInterval=500"};
validateForFail(DEFAULT_ERROR_MESSAGE, TaskJobLauncherCommandLineRunnerTests.JobWithFailureTaskExecutorConfiguration.class,
enabledArgs);
}
@Test
public void testTaskJobLauncherCLRSuccessWithLongWaitTaskExecutor() {
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.failOnJobFailure=true",
"--spring.cloud.task.batch.failOnJobFailurePollInterval=500",
"--spring.cloud.task.batch.failOnJobFailurewaitTime=1000"
};
validateForFail("Not all jobs were completed within the time specified by spring.cloud.task.batch.failOnJobFailurewaitTime.",
TaskJobLauncherCommandLineRunnerTests.JobWithFailureTaskExecutorLongWaitConfiguration.class,
enabledArgs);
}
@Test
public void testTaskJobLauncherPickOneJob() {
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.fail-on-job-failure=true",
"--spring.cloud.task.batch.jobNames=jobSucceed" };
"--spring.cloud.task.batch.jobNames=jobSucceed"};
boolean isExceptionThrown = false;
try {
this.applicationContext = SpringApplication
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class,
TaskJobLauncherAutoConfiguration.class }, enabledArgs);
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class }, enabledArgs);
}
catch (IllegalStateException exception) {
isExceptionThrown = true;
@@ -106,24 +140,18 @@ public class TaskJobLauncherCommandLineRunnerTests {
@Test
public void testCommandLineRunnerSetToFalse() {
String[] enabledArgs = new String[] { };
String[] enabledArgs = new String[] {};
this.applicationContext = SpringApplication
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class,
TaskJobLauncherAutoConfiguration.class }, enabledArgs);
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobConfiguration.class }, enabledArgs);
validateContext();
assertThat(applicationContext.getBean(JobLauncherCommandLineRunner.class)).isNotNull();
boolean exceptionThrown = false;
try {
Executable executable = () -> {
applicationContext.getBean(TaskJobLauncherCommandLineRunner.class);
}
catch (NoSuchBeanDefinitionException exception) {
exceptionThrown = true;
}
assertThat(exceptionThrown).isTrue();
};
Throwable exception = assertThrows(NoSuchBeanDefinitionException.class, executable);
assertThat(exception.getMessage()).isEqualTo("No qualifying bean of type " +
"'org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner' available");
validateContext();
}
@@ -137,12 +165,20 @@ public class TaskJobLauncherCommandLineRunnerTests {
assertThat(jobExecutionIds.size()).isEqualTo(1);
assertThat(taskExplorer.getTaskExecution(jobExecutionIds.iterator().next()).getExecutionId()).isEqualTo(1);
}
@Configuration
private void validateForFail(String errorMessage, Class clazz, String [] enabledArgs) {
Executable executable = () -> {
this.applicationContext = SpringApplication
.run(new Class[] { clazz,PropertyPlaceholderAutoConfiguration.class}, enabledArgs);};
Throwable exception = assertThrows(IllegalStateException.class, executable);
assertThat(exception.getCause().getMessage()).isEqualTo(errorMessage);
}
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobConfiguration {
@Autowired
@@ -156,8 +192,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
return jobBuilderFactory.get("job")
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
throws Exception {
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
System.out.println("Executed");
return RepeatStatus.FINISHED;
}
@@ -166,9 +201,15 @@ public class TaskJobLauncherCommandLineRunnerTests {
}
}
@Configuration
@EnableBatchProcessing
@EnableTask
@ImportAutoConfiguration({
PropertyPlaceholderAutoConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class,
TaskJobLauncherAutoConfiguration.class,
SingleTaskConfiguration.class,
SimpleTaskAutoConfiguration.class })
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobWithFailureConfiguration {
@Autowired
@@ -198,8 +239,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
.start(stepBuilderFactory.get("step1Succeed").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext)
throws Exception {
ChunkContext chunkContext) {
System.out.println("Executed");
return RepeatStatus.FINISHED;
}
@@ -207,4 +247,83 @@ public class TaskJobLauncherCommandLineRunnerTests {
.build();
}
}
@EnableTask
public static class JobWithFailureAnnotatedConfiguration extends JobWithFailureConfiguration{
}
public static class JobWithFailureTaskExecutorConfiguration extends JobWithFailureConfiguration{
@Bean
public BatchConfigurer batchConfigurer(DataSource dataSource) {
return new TestBatchConfigurer(dataSource);
}
}
@EnableBatchProcessing
@ImportAutoConfiguration({
PropertyPlaceholderAutoConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class,
TaskJobLauncherAutoConfiguration.class,
SingleTaskConfiguration.class,
SimpleTaskAutoConfiguration.class })
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobWithFailureTaskExecutorLongWaitConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public BatchConfigurer batchConfigurer(DataSource dataSource) {
return new TestBatchConfigurer(dataSource);
}
@Bean
public Job jobShortRunner() {
return jobBuilderFactory.get("jobSucceedShort")
.start(stepBuilderFactory.get("step1SucceedSort").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext)
throws Exception {
System.out.println("Executed Short Runner");
return RepeatStatus.FINISHED;
}
}).build())
.build();
}
@Bean
public Job jobLongRunner() {
return jobBuilderFactory.get("jobSucceedLong")
.start(stepBuilderFactory.get("step1SucceedLong").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext)
throws Exception {
System.out.println("Executed Long Runner");
Thread.sleep(5000);
return RepeatStatus.FINISHED;
}
}).build())
.build();
}
}
private static class TestBatchConfigurer extends DefaultBatchConfigurer{
public TestBatchConfigurer(DataSource dataSource) {
super(dataSource);
}
protected JobLauncher createJobLauncher() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(getJobRepository());
jobLauncher.setTaskExecutor(new ConcurrentTaskExecutor());
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
}
}

View File

@@ -29,10 +29,7 @@ import org.springframework.batch.core.configuration.annotation.StepBuilderFactor
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.cloud.task.batch.configuration.TaskBatchTest;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -58,11 +55,8 @@ public class PrefixTests {
@Test
public void testPrefix() {
this.applicationContext = SpringApplication.run(new Class[] {
JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class }, new String[] { "--spring.cloud.task.tablePrefix=FOO_" });
this.applicationContext = SpringApplication.run(
JobConfiguration.class, new String[] { "--spring.cloud.task.tablePrefix=FOO_" });
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
@@ -73,7 +67,7 @@ public class PrefixTests {
@Configuration
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
public static class JobConfiguration {
@Autowired

View File

@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.sql.DataSource;
import org.junit.After;
@@ -43,15 +44,16 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration;
import org.springframework.cloud.task.batch.configuration.TaskBatchExecutionListenerBeanPostProcessor;
import org.springframework.cloud.task.batch.configuration.TaskBatchTest;
import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import org.springframework.cloud.task.configuration.TaskConfigurer;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.cloud.task.repository.support.TaskRepositoryInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@@ -62,6 +64,7 @@ import static org.junit.Assert.assertEquals;
/**
* @author Michael Minella
* @author Glenn Renfro
*/
public class TaskBatchExecutionListenerTests {
@@ -78,71 +81,50 @@ public class TaskBatchExecutionListenerTests {
@Test
public void testAutobuiltDataSource() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
ARGS);
validateContext();
}
@Test(expected = AssertionError.class)
public void testNoAutoConfigurationEnabled() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, new String[] {"--spring.cloud.task.batch.listener.enabled=false"});
this.applicationContext = SpringApplication.run(JobConfiguration.class,
new String[] {"--spring.cloud.task.batch.listener.enabled=false"});
validateContext();
}
@Test(expected = AssertionError.class)
public void testNoAutoConfigurationEnable() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, new String[] {"--spring.cloud.task.batch.listener.enable=false"});
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
new String[] {"--spring.cloud.task.batch.listener.enable=false"});
validateContext();
}
@Test(expected = AssertionError.class)
public void testNoAutoConfigurationBothDisabled() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, new String[] {"--spring.cloud.task.batch.listener.enable=false --spring.cloud.task.batch.listener.enabled=false"});
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
new String[] {"--spring.cloud.task.batch.listener.enable=false --spring.cloud.task.batch.listener.enabled=false"});
validateContext();
}
@Test
public void testAutoConfigurationEnable() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, new String[] {"--spring.cloud.task.batch.listener.enable=true"});
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
new String[] {"--spring.cloud.task.batch.listener.enable=true"});
validateContext();
}
@Test
public void testAutoConfigurationEnabled() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, new String[] {"--spring.cloud.task.batch.listener.enabled=true"});
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
new String[] {"--spring.cloud.task.batch.listener.enabled=true"});
validateContext();
}
@Test
public void testFactoryBean() {
this.applicationContext = SpringApplication.run(new Class[]{JobFactoryBeanConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
this.applicationContext = SpringApplication.run(JobFactoryBeanConfiguration.class,
ARGS);
validateContext();
}
@@ -159,11 +141,7 @@ public class TaskBatchExecutionListenerTests {
}
@Test
public void testMultipleDataSources() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfigurationMultipleDataSources.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
this.applicationContext = SpringApplication.run(JobConfigurationMultipleDataSources.class, ARGS);
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
@@ -177,11 +155,7 @@ public class TaskBatchExecutionListenerTests {
@Test
public void testAutobuiltDataSourceNoJob() {
this.applicationContext = SpringApplication.run(new Class[] {NoJobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
this.applicationContext = SpringApplication.run(NoJobConfiguration.class, ARGS);
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
@@ -194,10 +168,7 @@ public class TaskBatchExecutionListenerTests {
@Test
public void testMapBased() {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
this.applicationContext = SpringApplication.run(JobConfiguration.class, ARGS);
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
@@ -211,10 +182,7 @@ public class TaskBatchExecutionListenerTests {
@Test
public void testMultipleJobs() {
this.applicationContext = SpringApplication.run(new Class[] {EmbeddedDataSourceConfiguration.class, MultipleJobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
this.applicationContext = SpringApplication.run(MultipleJobConfiguration.class, ARGS);
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
@@ -267,7 +235,9 @@ public class TaskBatchExecutionListenerTests {
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, EmbeddedDataSourceConfiguration.class,
BatchAutoConfiguration.class,
TaskBatchAutoConfiguration.class}, ARGS);
TaskBatchAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class }, ARGS);
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor =
this.applicationContext.getBean(
@@ -277,16 +247,16 @@ public class TaskBatchExecutionListenerTests {
return beanPostProcessor;
}
@Configuration
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
@Import(EmbeddedDataSourceConfiguration.class)
public static class NoJobConfiguration {
}
@Configuration
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobConfiguration {
@Autowired
@@ -309,9 +279,9 @@ public class TaskBatchExecutionListenerTests {
}
}
@Configuration
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobFactoryBeanConfiguration {
@Autowired
@@ -349,9 +319,9 @@ public class TaskBatchExecutionListenerTests {
}
}
@Configuration
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
@Import(EmbeddedDataSourceConfiguration.class)
public static class JobConfigurationMultipleDataSources {
@Autowired
@@ -396,24 +366,15 @@ public class TaskBatchExecutionListenerTests {
return new DefaultTaskConfigurer(myDataSource());
}
@Bean
public TaskRepositoryInitializer taskRepositoryInitializer() {
TaskRepositoryInitializer taskRepositoryInitializer = new TaskRepositoryInitializer();
taskRepositoryInitializer.setDataSource(myDataSource());
return taskRepositoryInitializer;
}
@Bean
public DefaultBatchConfigurer batchConfigurer() {
return new DefaultBatchConfigurer(myDataSource());
}
}
@Configuration
@EnableBatchProcessing
@EnableTask
@TaskBatchTest
@Import(EmbeddedDataSourceConfiguration.class)
public static class MultipleJobConfiguration {
@Autowired

View File

@@ -0,0 +1,6 @@
org.springframework.cloud.task.batch.configuration.TaskBatchTest=\
org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration,\
org.springframework.cloud.task.configuration.SingleTaskConfiguration