diff --git a/README.adoc b/README.adoc
index 6729a9ef..2c083101 100644
--- a/README.adoc
+++ b/README.adoc
@@ -23,7 +23,6 @@ $ ./mvnw clean install
[source,java,indent=2]
----
@SpringBootApplication
-@EnableTask
public class MyApp {
@Bean
diff --git a/pom.xml b/pom.xml
index 7e424ff4..4a8a3db8 100755
--- a/pom.xml
+++ b/pom.xml
@@ -5,13 +5,13 @@
org.springframework.cloud
spring-cloud-build
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
Spring Cloud Task Build
Spring Cloud Task Build
@@ -57,7 +57,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -132,15 +132,16 @@
- 2.0.0.RELEASE
- 1.3.2.RELEASE
- 1.3.5.RELEASE
- 2.0.0.RELEASE
- 1.3.2.RELEASE
- 1.3.2.RELEASE
- 4.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
+ 1.3.3.RELEASE
+ 1.3.6.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
+ 1.3.3.RELEASE
+ 1.3.3.RELEASE
+ 4.1.0.RELEASE
1.1
8.0
+ 5.3.1
UTF-8
${project.build.directory}/coverage-reports/jacoco-ut.exec
diff --git a/spring-cloud-starter-task/pom.xml b/spring-cloud-starter-task/pom.xml
index 2d0008ca..9a99b465 100644
--- a/spring-cloud-starter-task/pom.xml
+++ b/spring-cloud-starter-task/pom.xml
@@ -6,7 +6,7 @@
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
spring-cloud-starter-task
diff --git a/spring-cloud-task-batch/pom.xml b/spring-cloud-task-batch/pom.xml
index 2a8d7e86..ab60d4c8 100644
--- a/spring-cloud-task-batch/pom.xml
+++ b/spring-cloud-task-batch/pom.xml
@@ -6,7 +6,7 @@
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
spring-cloud-task-batch
@@ -50,6 +50,10 @@
spring-test
test
+
+ org.springframework.boot
+ spring-boot-test
+
junit
junit
@@ -69,6 +73,7 @@
org.springframework.boot
spring-boot-configuration-processor
true
+ ${spring-boot.version}
org.assertj
@@ -76,8 +81,11 @@
test
- org.springframework.boot
- spring-boot-test
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
diff --git a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskBatchProperties.java b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskBatchProperties.java
index fe7d7755..b3c8de7e 100644
--- a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskBatchProperties.java
+++ b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskBatchProperties.java
@@ -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;
+ }
}
diff --git a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfiguration.java b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfiguration.java
index 71f331ee..e94c9260 100644
--- a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfiguration.java
+++ b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfiguration.java
@@ -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 jobs, JobRegistry jobRegistry) {
+ JobExplorer jobExplorer, List 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;
}
diff --git a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherCommandLineRunnerFactoryBean.java b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherCommandLineRunnerFactoryBean.java
index f5df4c50..1a658d52 100644
--- a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherCommandLineRunnerFactoryBean.java
+++ b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherCommandLineRunnerFactoryBean.java
@@ -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 jobs, String jobNames,
- JobRegistry jobRegistry) {
+ JobExplorer jobExplorer, List 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;
}
+
}
diff --git a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunner.java b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunner.java
index fb3c54a7..3f8a3cf8 100644
--- a/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunner.java
+++ b/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunner.java
@@ -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 jobExecutionList = new ArrayList<>();
- private JobLauncher jobLauncher;
+ private ApplicationEventPublisher taskApplicationEventPublisher;
- private JobRegistry jobRegistry;
+ private TaskBatchProperties taskBatchProperties;
- private JobExplorer jobExplorer;
-
- private String jobNames;
-
- private Collection 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 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 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 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 parameterMap = parameters.getParameters();
+ HashMap copy = new HashMap<>(parameterMap);
+ for (Map.Entry 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 merged = new HashMap<>();
+ merged.putAll(parameters.getParameters());
+ merged.putAll(additionals.getParameters());
+ return new JobParameters(merged);
}
}
diff --git a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskBatchTest.java b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskBatchTest.java
new file mode 100644
index 00000000..e5797cb0
--- /dev/null
+++ b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskBatchTest.java
@@ -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 {
+}
diff --git a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfigurationTests.java b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfigurationTests.java
index f8f1c8c2..9d7ecd2f 100644
--- a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfigurationTests.java
+++ b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/configuration/TaskJobLauncherAutoConfigurationTests.java
@@ -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);
});
}
diff --git a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerCoreTests.java b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerCoreTests.java
index 38cd20a8..9d62b9a9 100644
--- a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerCoreTests.java
+++ b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerCoreTests.java
@@ -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;
diff --git a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerTests.java b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerTests.java
index 31e89939..96a155fb 100644
--- a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerTests.java
+++ b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/handler/TaskJobLauncherCommandLineRunnerTests.java
@@ -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;
+ }
+ }
}
diff --git a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/PrefixTests.java b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/PrefixTests.java
index a187139a..f7ff20fe 100644
--- a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/PrefixTests.java
+++ b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/PrefixTests.java
@@ -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
diff --git a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/TaskBatchExecutionListenerTests.java b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/TaskBatchExecutionListenerTests.java
index 83827b55..8bce0a2b 100644
--- a/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/TaskBatchExecutionListenerTests.java
+++ b/spring-cloud-task-batch/src/test/java/org/springframework/cloud/task/batch/listener/TaskBatchExecutionListenerTests.java
@@ -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
diff --git a/spring-cloud-task-batch/src/test/resources/META-INF/spring.factories b/spring-cloud-task-batch/src/test/resources/META-INF/spring.factories
new file mode 100644
index 00000000..ddec7ef9
--- /dev/null
+++ b/spring-cloud-task-batch/src/test/resources/META-INF/spring.factories
@@ -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
diff --git a/spring-cloud-task-core/pom.xml b/spring-cloud-task-core/pom.xml
index 4283f505..702057be 100755
--- a/spring-cloud-task-core/pom.xml
+++ b/spring-cloud-task-core/pom.xml
@@ -6,7 +6,7 @@
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
spring-cloud-task-core
@@ -91,6 +91,12 @@
spring-boot-configuration-processor
true
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/EnableTask.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/EnableTask.java
index 26d99364..9b731de4 100644
--- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/EnableTask.java
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/EnableTask.java
@@ -1,6 +1,5 @@
-
/*
- * Copyright 2015 the original author or authors.
+ * Copyright 2015-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.
@@ -54,11 +53,15 @@ import org.springframework.context.annotation.Import;
*
*
* @author Glenn Renfro
+ *
+ * @deprecated The EnableTask annotation is no longer be required to initialize
+ * Spring Cloud Task. This will be handled by AutoConfiguration provided by Spring Cloud Task.
*/
+@Deprecated
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
-@Import({ SimpleTaskConfiguration.class, SingleTaskConfiguration.class })
+@Import({ })
public @interface EnableTask {
}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SimpleTaskConfiguration.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SimpleTaskAutoConfiguration.java
similarity index 90%
rename from spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SimpleTaskConfiguration.java
rename to spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SimpleTaskAutoConfiguration.java
index e5815a52..54171a61 100644
--- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SimpleTaskConfiguration.java
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SimpleTaskAutoConfiguration.java
@@ -29,9 +29,11 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.task.listener.TaskLifecycleListener;
-import org.springframework.cloud.task.listener.annotation.TaskListenerExecutorFactoryBean;
+import org.springframework.cloud.task.listener.TaskListenerExecutorObjectFactory;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.cloud.task.repository.TaskNameResolver;
import org.springframework.cloud.task.repository.TaskRepository;
@@ -55,9 +57,10 @@ import org.springframework.util.CollectionUtils;
@Configuration
@EnableTransactionManagement
@EnableConfigurationProperties(TaskProperties.class)
-public class SimpleTaskConfiguration {
+@ConditionalOnProperty(prefix = "spring.cloud.task.autoconfiguration", name = "enabled", havingValue = "true", matchIfMissing = true)
+public class SimpleTaskAutoConfiguration {
- protected static final Log logger = LogFactory.getLog(SimpleTaskConfiguration.class);
+ protected static final Log logger = LogFactory.getLog(SimpleTaskAutoConfiguration.class);
@Autowired(required = false)
private Collection dataSources;
@@ -77,8 +80,6 @@ public class SimpleTaskConfiguration {
private TaskLifecycleListener taskLifecycleListener;
- private TaskListenerExecutorFactoryBean taskListenerExecutorFactoryBean;
-
private PlatformTransactionManager platformTransactionManager;
private TaskExplorer taskExplorer;
@@ -94,12 +95,7 @@ public class SimpleTaskConfiguration {
}
@Bean
- public TaskListenerExecutorFactoryBean taskListenerExecutor()
- throws Exception {
- return this.taskListenerExecutorFactoryBean;
- }
-
- @Bean
+ @ConditionalOnMissingBean
public PlatformTransactionManager transactionManager() {
return this.platformTransactionManager;
}
@@ -140,12 +136,11 @@ public class SimpleTaskConfiguration {
taskConfigurer.getClass().getName()));
this.taskRepository = taskConfigurer.getTaskRepository();
- this.taskListenerExecutorFactoryBean = new TaskListenerExecutorFactoryBean(context);
this.platformTransactionManager = taskConfigurer.getTransactionManager();
this.taskExplorer = taskConfigurer.getTaskExplorer();
this.taskLifecycleListener = new TaskLifecycleListener(this.taskRepository, taskNameResolver(),
- this.applicationArguments, taskExplorer, taskProperties);
+ this.applicationArguments, taskExplorer, taskProperties, new TaskListenerExecutorObjectFactory(context));
initialized = true;
}
diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java
index 9a426ed3..c6e3c9ec 100644
--- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java
+++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2017 the original author or authors.
+ * Copyright 2016-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.
@@ -46,6 +46,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
@@ -74,7 +75,9 @@ public class TaskLifecycleListener implements ApplicationListener taskExecutionListeners;
+ private Collection taskExecutionListenersFromContext;
+
+ private List taskExecutionListeners;
private final static Log logger = LogFactory.getLog(TaskLifecycleListener.class);
@@ -82,6 +85,8 @@ public class TaskLifecycleListener implements ApplicationListener();
+ this.taskListenerExecutorObjectFactory.getObject();
+ if(!CollectionUtils.isEmpty(this.taskExecutionListenersFromContext)) {
+ this.taskExecutionListeners.addAll(this.taskExecutionListenersFromContext);
+ }
+ this.taskExecutionListeners.add(this.taskListenerExecutorObjectFactory.getObject());
+
List args = new ArrayList<>(0);
if(this.applicationArguments != null) {
@@ -258,11 +273,11 @@ public class TaskLifecycleListener implements ApplicationListener startupListenerList = new ArrayList<>(this.taskExecutionListeners);
+ if (startupListenerList != null) {
try {
- List starterList = new ArrayList<>(taskExecutionListeners);
- Collections.reverse(starterList);
- for (TaskExecutionListener taskExecutionListener : starterList) {
+ Collections.reverse(startupListenerList);
+ for (TaskExecutionListener taskExecutionListener : startupListenerList) {
taskExecutionListener.onTaskStartup(listenerTaskExecution);
}
}
@@ -300,7 +315,7 @@ public class TaskLifecycleListener implements ApplicationListener {
+public class TaskListenerExecutorObjectFactory implements ObjectFactory {
private final static Log logger = LogFactory.getLog(TaskListenerExecutor.class);
@@ -56,29 +65,19 @@ public class TaskListenerExecutorFactoryBean implements FactoryBean failedTaskInstances;
- public TaskListenerExecutorFactoryBean(ConfigurableApplicationContext context){
+ public TaskListenerExecutorObjectFactory(ConfigurableApplicationContext context){
this.context = context;
}
@Override
- public TaskListenerExecutor getObject() throws Exception {
- beforeTaskInstances = new HashMap<>();
- afterTaskInstances = new HashMap<>();
- failedTaskInstances = new HashMap<>();
+ public TaskListenerExecutor getObject() {
+ this.beforeTaskInstances = new HashMap<>();
+ this.afterTaskInstances = new HashMap<>();
+ this.failedTaskInstances = new HashMap<>();
initializeExecutor();
return new TaskListenerExecutor(beforeTaskInstances, afterTaskInstances, failedTaskInstances);
}
- @Override
- public Class> getObjectType() {
- return TaskListenerExecutor.class;
- }
-
- @Override
- public boolean isSingleton() {
- return false;
- }
-
private void initializeExecutor( ) {
ConfigurableListableBeanFactory factory = context.getBeanFactory();
for( String beanName : context.getBeanDefinitionNames()) {
diff --git a/spring-cloud-task-core/src/main/resources/META-INF/spring.factories b/spring-cloud-task-core/src/main/resources/META-INF/spring.factories
index 22ff66d1..ea2f98ee 100644
--- a/spring-cloud-task-core/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-task-core/src/main/resources/META-INF/spring.factories
@@ -1 +1,4 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.cloud.task.configuration.ResourceLoadingAutoConfiguration
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.cloud.task.configuration.SingleTaskConfiguration,\
+org.springframework.cloud.task.configuration.ResourceLoadingAutoConfiguration,\
+org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration\
+
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationTests.java
index 671e4d9e..945ca4a8 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-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.
@@ -17,17 +17,13 @@
package org.springframework.cloud.task;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
-import org.springframework.cloud.task.configuration.TaskProperties;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -39,24 +35,23 @@ import static org.junit.Assert.assertNotNull;
* @author Glenn Renfro
* @since 2.0.0
*/
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = {TaskProperties.class, SimpleTaskConfiguration.class, SingleTaskConfiguration.class})
-@TestPropertySource(properties = {
- "spring.cloud.task.single-instance-enabled=true",
-})
public class SimpleSingleTaskAutoConfigurationTests {
- @Autowired
- private ConfigurableApplicationContext context;
@Test
public void testConfiguration() throws Exception {
- SingleInstanceTaskListener singleInstanceTaskListener = this.context.getBean(SingleInstanceTaskListener.class);
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
+ applicationContextRunner.run((context) -> {
+ SingleInstanceTaskListener singleInstanceTaskListener = context.getBean(SingleInstanceTaskListener.class);
- assertNotNull("singleInstanceTaskListener should not be null", singleInstanceTaskListener);
-
- assertEquals(singleInstanceTaskListener.getClass(), SingleInstanceTaskListener.class);
+ assertNotNull("singleInstanceTaskListener should not be null", singleInstanceTaskListener);
+ assertEquals(singleInstanceTaskListener.getClass(), SingleInstanceTaskListener.class); });
}
}
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationWithDataSourceTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationWithDataSourceTests.java
index b86b1ac3..350fc2d8 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationWithDataSourceTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleSingleTaskAutoConfigurationWithDataSourceTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-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.
@@ -17,17 +17,14 @@
package org.springframework.cloud.task;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
-import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -39,25 +36,24 @@ import static org.junit.Assert.assertNotNull;
* @author Glenn Renfro
* @since 2.0.0
*/
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = {SimpleTaskConfiguration.class,
- SingleTaskConfiguration.class,
- EmbeddedDataSourceConfiguration.class})
-@TestPropertySource(properties = {
- "spring.cloud.task.single-instance-enabled=true",
-})
public class SimpleSingleTaskAutoConfigurationWithDataSourceTests {
- @Autowired
- private ConfigurableApplicationContext context;
-
@Test
public void testConfiguration() throws Exception {
- SingleInstanceTaskListener singleInstanceTaskListener = this.context.getBean(SingleInstanceTaskListener.class);
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class,
+ EmbeddedDataSourceConfiguration.class))
+ .withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
+ applicationContextRunner.run((context) -> {
+ SingleInstanceTaskListener singleInstanceTaskListener = context.getBean(SingleInstanceTaskListener.class);
- assertNotNull("singleInstanceTaskListener should not be null", singleInstanceTaskListener);
+ assertNotNull("singleInstanceTaskListener should not be null", singleInstanceTaskListener);
- assertEquals(singleInstanceTaskListener.getClass(), SingleInstanceTaskListener.class);
+ assertEquals(singleInstanceTaskListener.getClass(), SingleInstanceTaskListener.class);
+ });
}
}
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleTaskAutoConfigurationTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleTaskAutoConfigurationTests.java
new file mode 100644
index 00000000..5bfc1f04
--- /dev/null
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleTaskAutoConfigurationTests.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2015-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;
+
+import javax.sql.DataSource;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.jupiter.api.function.Executable;
+
+import org.springframework.aop.framework.AopProxyUtils;
+import org.springframework.aop.scope.ScopedProxyUtils;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.GenericBeanDefinition;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
+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.TaskExplorer;
+import org.springframework.cloud.task.repository.TaskRepository;
+import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
+import org.springframework.context.ApplicationContextException;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Verifies that the beans created by the SimpleTaskAutoConfiguration.
+ *
+ * @author Glenn Renfro
+ * @author Michael Minella
+ */
+public class SimpleTaskAutoConfigurationTests {
+
+ private ConfigurableApplicationContext context;
+
+ @After
+ public void tearDown() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void testRepository() throws Exception {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class));
+ applicationContextRunner.run((context) -> {
+
+ TaskRepository taskRepository = context.getBean(TaskRepository.class);
+ assertThat(taskRepository).isNotNull();
+ Class> targetClass = AopProxyUtils.ultimateTargetClass(taskRepository);
+ assertThat(targetClass).isEqualTo(SimpleTaskRepository.class);
+ });
+ }
+
+ @Test
+ public void testAutoConfigurationDisabled() throws Exception {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withPropertyValues("spring.cloud.task.autoconfiguration.enabled=false");
+ Executable executable = () -> {
+ applicationContextRunner.run((context) -> {
+ context.getBean(TaskRepository.class);
+ });
+ };
+ verifyExceptionThrown(NoSuchBeanDefinitionException.class, "No qualifying " +
+ "bean of type 'org.springframework.cloud.task.repository.TaskRepository' " +
+ "available", executable);
+ }
+
+ @Test
+ public void testRepositoryInitialized() throws Exception {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class));
+ applicationContextRunner.run((context) -> {
+ TaskExplorer taskExplorer = context.getBean(TaskExplorer.class);
+ assertThat(taskExplorer.getTaskExecutionCount()).isEqualTo(1l);
+ });
+ }
+
+ @Test
+ public void testRepositoryNotInitialized() throws Exception {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withPropertyValues("spring.cloud.task.tablePrefix=foobarless");
+
+ verifyExceptionThrownDefaultExecutable(ApplicationContextException.class, "Failed to start " +
+ "bean 'taskLifecycleListener'; nested exception is " +
+ "org.springframework.dao.DataAccessResourceFailureException: " +
+ "Could not obtain sequence value; nested exception is org.h2.jdbc.JdbcSQLException: " +
+ "Syntax error in SQL statement \"SELECT FOOBARLESSSEQ.NEXTVAL FROM[*] DUAL \"; " +
+ "expected \"identifier\"; SQL statement:\n" +
+ "select foobarlessSEQ.nextval from dual [42001-197]", applicationContextRunner);
+ }
+
+ @Test
+ public void testMultipleConfigurers() {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withUserConfiguration(MultipleConfigurers.class);
+
+ verifyExceptionThrownDefaultExecutable(BeanCreationException.class, "Error creating bean " +
+ "with name 'simpleTaskAutoConfiguration': Invocation of init " +
+ "method failed; nested exception is java.lang.IllegalStateException:" +
+ " Expected one TaskConfigurer but found 2", applicationContextRunner);
+ }
+
+ @Test
+ public void testMultipleDataSources() {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withUserConfiguration(MultipleDataSources.class);
+
+ verifyExceptionThrownDefaultExecutable(BeanCreationException.class, "Error creating bean " +
+ "with name 'simpleTaskAutoConfiguration': Invocation of init method " +
+ "failed; nested exception is java.lang.IllegalStateException: To use " +
+ "the default TaskConfigurer the context must contain no more than " +
+ "one DataSource, found 2", applicationContextRunner);
+
+ }
+
+ public void verifyExceptionThrownDefaultExecutable(Class classToCheck, String message,
+ ApplicationContextRunner applicationContextRunner) {
+ Executable executable = () -> {
+ applicationContextRunner.run((context) -> {
+ Throwable expectedException = context.getStartupFailure();
+ assertThat(expectedException).isNotNull();
+ throw expectedException;
+ });
+ };
+ verifyExceptionThrown(classToCheck, message, executable);
+ }
+
+ public void verifyExceptionThrown(Class classToCheck, String message, Executable executable) {
+ Throwable exception = assertThrows(classToCheck, executable);
+ assertThat(exception.getMessage()).isEqualTo(message);
+ }
+
+ /**
+ * Verify that the verifyEnvironment method skips DataSource Proxy Beans when determining
+ * the number of available dataSources.
+ */
+ @Test
+ public void testWithDataSourceProxy() {
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ EmbeddedDataSourceConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withUserConfiguration(DataSourceProxyConfiguration.class);
+ applicationContextRunner.run((context) -> {
+ assertThat(context.getBeanNamesForType(DataSource.class).length).isEqualTo(2);
+ SimpleTaskAutoConfiguration taskConfiguration = context.getBean(SimpleTaskAutoConfiguration.class);
+ assertThat(taskConfiguration).isNotNull();
+ assertThat(taskConfiguration.taskExplorer()).isNotNull();
+ });
+ }
+
+ @Configuration
+ public static class MultipleConfigurers {
+
+ @Bean
+ public TaskConfigurer taskConfigurer1() {
+ return new DefaultTaskConfigurer((DataSource) null);
+ }
+
+ @Bean
+ public TaskConfigurer taskConfigurer2() {
+ return new DefaultTaskConfigurer((DataSource) null);
+ }
+ }
+
+ @Configuration
+ public static class MultipleDataSources {
+
+ @Bean
+ public DataSource dataSource() {
+ return mock(DataSource.class);
+ };
+
+ @Bean
+ public DataSource dataSource2() {
+ return mock(DataSource.class);
+ };
+
+ }
+
+ @Configuration
+ public static class DataSourceProxyConfiguration {
+
+ @Autowired
+ private ConfigurableApplicationContext context;
+
+ @Bean
+ public BeanDefinitionHolder proxyDataSource() {
+ GenericBeanDefinition proxyBeanDefinition = new GenericBeanDefinition();
+ proxyBeanDefinition.setBeanClassName("javax.sql.DataSource");
+ BeanDefinitionHolder myDataSource = new BeanDefinitionHolder(proxyBeanDefinition, "dataSource2");
+ ScopedProxyUtils.createScopedProxy(myDataSource, (BeanDefinitionRegistry) this.context.getBeanFactory(),
+ true);
+ return myDataSource;
+ }
+
+ }
+
+}
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleTaskConfigurationTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleTaskConfigurationTests.java
deleted file mode 100644
index d5f38101..00000000
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/SimpleTaskConfigurationTests.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2015-2016 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;
-
-import java.util.Properties;
-
-import javax.sql.DataSource;
-
-import org.junit.After;
-import org.junit.Test;
-
-import org.springframework.aop.framework.AopProxyUtils;
-import org.springframework.aop.scope.ScopedProxyUtils;
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.GenericBeanDefinition;
-import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
-import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
-import org.springframework.cloud.task.configuration.EnableTask;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
-import org.springframework.cloud.task.configuration.TaskConfigurer;
-import org.springframework.cloud.task.configuration.TaskProperties;
-import org.springframework.cloud.task.repository.TaskExplorer;
-import org.springframework.cloud.task.repository.TaskRepository;
-import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
-import org.springframework.context.ApplicationContextException;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.PropertiesPropertySource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-/**
- * Verifies that the beans created by the SimpleTaskConfiguration.
- *
- * @author Glenn Renfro
- * @author Michael Minella
- */
-public class SimpleTaskConfigurationTests {
-
- private ConfigurableApplicationContext context;
-
- @After
- public void tearDown() {
- if(this.context != null) {
- this.context.close();
- }
- }
-
- @Test
- public void testRepository() throws Exception {
- this.context = new AnnotationConfigApplicationContext(SimpleTaskConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class);
-
- TaskRepository taskRepository = this.context.getBean(TaskRepository.class);
-
- assertThat(taskRepository).isNotNull();
-
- Class> targetClass = AopProxyUtils.ultimateTargetClass(taskRepository);
-
- assertThat(targetClass).isEqualTo(SimpleTaskRepository.class);
- }
-
-
- @Test
- public void testRepositoryInitialized() throws Exception {
- this.context = new AnnotationConfigApplicationContext(EmbeddedDataSourceConfiguration.class, SimpleTaskConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class);
-
- TaskExplorer taskExplorer = this.context.getBean(TaskExplorer.class);
-
- assertThat(taskExplorer.getTaskExecutionCount()).isEqualTo(1l);
- }
-
- @Test
- public void testRepositoryNotInitialized() throws Exception {
- Properties properties = new Properties();
-
- properties.put("spring.cloud.task.tablePrefix", "foobarless");
- PropertiesPropertySource propertiesSource = new PropertiesPropertySource("test", properties);
-
- this.context = new AnnotationConfigApplicationContext();
- this.context.getEnvironment().getPropertySources().addLast(propertiesSource);
- ((AnnotationConfigApplicationContext)context).register(SimpleTaskConfiguration.class);
- ((AnnotationConfigApplicationContext)context).register(PropertyPlaceholderAutoConfiguration.class);
- ((AnnotationConfigApplicationContext)context).register(EmbeddedDataSourceConfiguration.class);
- boolean wasExceptionThrown = false;
- try {
- this.context.refresh();
- }
- catch (ApplicationContextException ex) {
- wasExceptionThrown = true;
- }
- assertThat( wasExceptionThrown).isTrue();
- }
-
-
- @Test(expected = BeanCreationException.class)
- public void testMultipleConfigurers() {
- this.context = new AnnotationConfigApplicationContext(MultipleConfigurers.class,
- PropertyPlaceholderAutoConfiguration.class);
- }
-
- @Test(expected = BeanCreationException.class)
- public void testMultipleDataSources() {
- this.context = new AnnotationConfigApplicationContext(
- MultipleDataSources.class, SimpleTaskConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class);
- }
-
- /**
- * Verify that the verifyEnvironment method skips DataSource Proxy Beans
- * when determining the number of available dataSources.
- */
- @Test
- public void testWithDataSourceProxy() {
- this.context = new AnnotationConfigApplicationContext(EmbeddedDataSourceConfiguration.class, TaskProperties.class,
- PropertyPlaceholderAutoConfiguration.class, DataSourceProxyConfiguration.class
- );
-
- assertThat(this.context.getBeanNamesForType(DataSource.class).length).isEqualTo(2);
- SimpleTaskConfiguration taskConfiguration = this.context.getBean(SimpleTaskConfiguration.class);
- assertThat(taskConfiguration).isNotNull();
- assertThat(taskConfiguration.taskExplorer()).isNotNull();
- }
-
- @Configuration
- @EnableTask
- public static class MultipleConfigurers {
-
- @Bean
- public TaskConfigurer taskConfigurer1() {
- return new DefaultTaskConfigurer((DataSource) null);
- }
-
- @Bean
- public TaskConfigurer taskConfigurer2() {
- return new DefaultTaskConfigurer((DataSource) null);
- }
- }
-
- @Configuration
- public static class MultipleDataSources {
-
- @Bean
- public DataSource dataSource() {
- return mock(DataSource.class);
- };
-
- @Bean
- public DataSource dataSource2() {
- return mock(DataSource.class);
- };
-
- }
-
- @Configuration
- public static class DataSourceProxyConfiguration {
-
- @Autowired
- private ConfigurableApplicationContext context;
-
- @Bean
- public SimpleTaskConfiguration simpleTaskConfiguration() {
- GenericBeanDefinition proxyBeanDefinition = new GenericBeanDefinition();
- proxyBeanDefinition.setBeanClassName("javax.sql.DataSource");
- BeanDefinitionHolder myDataSource = new BeanDefinitionHolder(proxyBeanDefinition,"dataSource2");
- ScopedProxyUtils.createScopedProxy(myDataSource, (BeanDefinitionRegistry) this.context.getBeanFactory(), true);
- return new SimpleTaskConfiguration();
- }
-
- }
-
-}
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskCoreTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskCoreTests.java
index 95e2eb40..df30c003 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskCoreTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskCoreTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2015-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;
import org.junit.After;
@@ -5,14 +21,15 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
-import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.cloud.task.configuration.EnableTask;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertTrue;
@@ -48,11 +65,31 @@ public class TaskCoreTests {
@Test
public void successfulTaskTest() {
- applicationContext = new SpringApplicationBuilder().sources(new Class[]{TaskConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class}).build().run(new String[]{
- "--spring.cloud.task.closecontext.enable=false",
- "--spring.cloud.task.name=" + TASK_NAME,
- "--spring.main.web-environment=false"});
+ this.applicationContext = SpringApplication.run( TaskConfiguration.class,
+ new String[] {
+ "--spring.cloud.task.closecontext.enable=false",
+ "--spring.cloud.task.name=" + TASK_NAME,
+ "--spring.main.web-environment=false" });
+
+ String output = this.outputCapture.toString();
+ assertTrue("Test results do not show create task message: " + output,
+ output.contains(CREATE_TASK_MESSAGE));
+ assertTrue("Test results do not show success message: " + output,
+ output.contains(UPDATE_TASK_MESSAGE));
+ assertTrue("Test results have incorrect exit code: " + output,
+ output.contains(SUCCESS_EXIT_CODE_MESSAGE));
+ }
+
+ /**
+ * Test to verify that deprecated annotation does not affect task execution.
+ */
+ @Test
+ public void successfulTaskTestWithAnnotation() {
+ this.applicationContext = SpringApplication.run( TaskConfigurationWithAnotation.class,
+ new String[] {
+ "--spring.cloud.task.closecontext.enable=false",
+ "--spring.cloud.task.name=" + TASK_NAME,
+ "--spring.main.web-environment=false" });
String output = this.outputCapture.toString();
assertTrue("Test results do not show create task message: " + output,
@@ -67,11 +104,11 @@ public class TaskCoreTests {
public void exceptionTaskTest() {
boolean exceptionFired = false;
try {
- applicationContext = new SpringApplicationBuilder().sources(TaskExceptionConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class).build().run(new String[]{
- "--spring.cloud.task.closecontext.enable=false",
- "--spring.cloud.task.name=" + TASK_NAME,
- "--spring.main.web-environment=false"});
+ this.applicationContext = SpringApplication.run( TaskExceptionConfiguration.class,
+ new String[] {
+ "--spring.cloud.task.closecontext.enable=false",
+ "--spring.cloud.task.name=" + TASK_NAME,
+ "--spring.main.web-environment=false" });
}
catch (IllegalStateException exception) {
exceptionFired = true;
@@ -95,8 +132,8 @@ public class TaskCoreTests {
public void invalidExecutionId() {
boolean exceptionFired = false;
try {
- applicationContext = new SpringApplicationBuilder().sources(TaskExceptionConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class).build().run(new String[]{
+ applicationContext = this.applicationContext = SpringApplication.run(
+ TaskExceptionConfiguration.class, new String[]{
"--spring.cloud.task.closecontext.enable=false",
"--spring.cloud.task.name=" + TASK_NAME,
"--spring.main.web-environment=false",
@@ -112,8 +149,7 @@ public class TaskCoreTests {
output.contains(EXCEPTION_INVALID_TASK_EXECUTION_ID));
}
- @Configuration
- @EnableTask
+ @ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
public static class TaskConfiguration {
@Bean
@@ -126,8 +162,21 @@ public class TaskCoreTests {
}
}
- @Configuration
@EnableTask
+ @ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
+ public static class TaskConfigurationWithAnotation {
+
+ @Bean
+ public CommandLineRunner commandLineRunner() {
+ return new CommandLineRunner() {
+ @Override
+ public void run(String... strings) throws Exception {
+ }
+ };
+ }
+ }
+
+ @ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
public static class TaskExceptionConfiguration {
@Bean
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerDefaultTaskConfigurerTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerDefaultTaskConfigurerTests.java
index 3fcce0e7..8174e9a0 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerDefaultTaskConfigurerTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerDefaultTaskConfigurerTests.java
@@ -26,7 +26,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.TaskConfigurer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
@@ -42,7 +42,7 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
* @since 2.0.0
*/
@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = {SimpleTaskConfiguration.class,
+@ContextConfiguration(classes = {SimpleTaskAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class})
public class TaskRepositoryInitializerDefaultTaskConfigurerTests {
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerNoDataSourceTaskConfigurerTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerNoDataSourceTaskConfigurerTests.java
index 0705ba20..00ab42d8 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerNoDataSourceTaskConfigurerTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/TaskRepositoryInitializerNoDataSourceTaskConfigurerTests.java
@@ -27,7 +27,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
+import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import org.springframework.cloud.task.configuration.TaskConfigurer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
@@ -43,7 +44,7 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
* @since 2.0.0
*/
@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = {SimpleTaskConfiguration.class,
+@ContextConfiguration(classes = {SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class,
EmbeddedDataSourceConfiguration.class,
DefaultTaskConfigurer.class})
public class TaskRepositoryInitializerNoDataSourceTaskConfigurerTests {
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/configuration/TaskPropertiesTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/configuration/TaskPropertiesTests.java
index ed6495b8..b8b1aa72 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/configuration/TaskPropertiesTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/configuration/TaskPropertiesTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2017-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.configuration;
import org.junit.Test;
@@ -7,10 +23,6 @@ import org.junit.runners.Suite.SuiteClasses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.cloud.task.repository.TaskRepository;
-import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
-import org.springframework.cloud.task.repository.support.TaskExecutionDaoFactoryBean;
-import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
@@ -21,7 +33,7 @@ import static org.junit.Assert.assertThat;
@RunWith(Suite.class)
@SuiteClasses({
- TaskPropertiesTests.CloseContextEnabledTest.class,
+ TaskPropertiesTests.CloseContextEnabledTest.class
})
@@ -36,21 +48,15 @@ public class TaskPropertiesTests {
}
@RunWith(SpringRunner.class)
- @SpringBootTest(classes={TaskPropertiesTests.Config.class}, properties = { "spring.cloud.task.closecontextEnabled=false" })
+ @SpringBootTest(classes={TaskPropertiesTests.Config.class,
+ SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class},
+ properties = { "spring.cloud.task.closecontextEnabled=false" })
@DirtiesContext
public static class CloseContextEnabledTest extends TaskPropertiesTests {}
@Configuration
- @EnableTask
public static class Config {
- @Bean
- TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean() {
- return new TaskExecutionDaoFactoryBean();
- }
- @Bean
- public TaskRepository taskRepository(TaskExecutionDaoFactoryBean tefb) {
- return new SimpleTaskRepository(tefb);
- }
+
}
}
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskExecutionListenerTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskExecutionListenerTests.java
index a1f4d25c..3f78bcbe 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskExecutionListenerTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskExecutionListenerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -29,11 +29,9 @@ import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.task.listener.annotation.AfterTask;
import org.springframework.cloud.task.listener.annotation.BeforeTask;
import org.springframework.cloud.task.listener.annotation.FailedTask;
-import org.springframework.cloud.task.listener.annotation.TaskListenerExecutorFactoryBean;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.util.TestDefaultConfiguration;
import org.springframework.cloud.task.util.TestListener;
-import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -290,12 +288,6 @@ public class TaskExecutionListenerTests {
return new AnnotatedTaskListener();
}
- @Bean
- public TaskListenerExecutorFactoryBean taskListenerExecutor(ConfigurableApplicationContext context) throws Exception
- {
- return new TaskListenerExecutorFactoryBean(context);
- }
-
public static class AnnotatedTaskListener extends TestListener {
@BeforeTask
@@ -331,12 +323,6 @@ public class TaskExecutionListenerTests {
return new AnnotatedTaskListener();
}
- @Bean
- public TaskListenerExecutorFactoryBean taskListenerExecutor(ConfigurableApplicationContext context) throws Exception
- {
- return new TaskListenerExecutorFactoryBean(context);
- }
-
public static class AnnotatedTaskListener {
@BeforeTask
@@ -365,11 +351,6 @@ public class TaskExecutionListenerTests {
return new AnnotatedTaskListener();
}
- @Bean
- public TaskListenerExecutorFactoryBean taskListenerExecutor(ConfigurableApplicationContext context) throws Exception
- {
- return new TaskListenerExecutorFactoryBean(context);
- }
public static class AnnotatedTaskListener {
@@ -400,12 +381,6 @@ public class TaskExecutionListenerTests {
return new AnnotatedTaskListener();
}
- @Bean
- public TaskListenerExecutorFactoryBean taskListenerExecutor(ConfigurableApplicationContext context) throws Exception
- {
- return new TaskListenerExecutorFactoryBean(context);
- }
-
public static class AnnotatedTaskListener extends TestListener{
@BeforeTask
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskListenerExecutorObjectFactoryTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskListenerExecutorObjectFactoryTests.java
new file mode 100644
index 00000000..0fd11c0d
--- /dev/null
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskListenerExecutorObjectFactoryTests.java
@@ -0,0 +1,141 @@
+/*
+ * 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.listener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.task.listener.annotation.AfterTask;
+import org.springframework.cloud.task.listener.annotation.BeforeTask;
+import org.springframework.cloud.task.listener.annotation.FailedTask;
+import org.springframework.cloud.task.listener.annotation.TaskListenerExecutor;
+import org.springframework.cloud.task.repository.TaskExecution;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Verifies that the {@link TaskListenerExecutorObjectFactory} retrieves the
+ * {@link TaskListenerExecutor}.
+ *
+ * @author Glenn Renfro
+ * @since 2.1.0
+ */
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = { TaskListenerExecutorObjectFactoryTests.TaskExecutionListenerConfiguration.class })
+public class TaskListenerExecutorObjectFactoryTests {
+
+ public static final String BEFORE_LISTENER = "BEFORE LISTENER";
+
+ public static final String AFTER_LISTENER = "AFTER LISTENER";
+
+ public static final String FAIL_LISTENER = "FAIL LISTENER";
+
+ public static List taskExecutionListenerResults = new ArrayList<>(3);
+
+ @Autowired
+ private ConfigurableApplicationContext context;
+
+ private TaskListenerExecutor taskListenerExecutor;
+
+ private TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory;
+
+ @Before
+ public void setup() {
+ taskExecutionListenerResults.clear();
+ this.taskListenerExecutorObjectFactory = new TaskListenerExecutorObjectFactory(this.context);
+ this.taskListenerExecutor = this.taskListenerExecutorObjectFactory.getObject();
+ }
+
+ @Test
+ public void verifyTaskStartupListener() {
+ this.taskListenerExecutor.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
+ validateSingleEntry(BEFORE_LISTENER);
+ }
+
+ @Test
+ public void verifyTaskFailedListener() {
+ this.taskListenerExecutor.onTaskFailed(createSampleTaskExecution(FAIL_LISTENER),
+ new IllegalStateException("oops"));
+ validateSingleEntry(FAIL_LISTENER);
+ }
+
+ @Test
+ public void verifyTaskEndListener() {
+ this.taskListenerExecutor.onTaskEnd(createSampleTaskExecution(AFTER_LISTENER));
+ validateSingleEntry(AFTER_LISTENER);
+ }
+
+ @Test
+ public void verifyAllListener() {
+ this.taskListenerExecutor.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
+ this.taskListenerExecutor.onTaskFailed(createSampleTaskExecution(FAIL_LISTENER),
+ new IllegalStateException("oops"));
+ this.taskListenerExecutor.onTaskEnd(createSampleTaskExecution(AFTER_LISTENER));
+ assertThat(taskExecutionListenerResults.size()).isEqualTo(3);
+ assertThat(taskExecutionListenerResults.get(0).getTaskName()).isEqualTo(BEFORE_LISTENER);
+ assertThat(taskExecutionListenerResults.get(1).getTaskName()).isEqualTo(FAIL_LISTENER);
+ assertThat(taskExecutionListenerResults.get(2).getTaskName()).isEqualTo(AFTER_LISTENER);
+ }
+
+ private TaskExecution createSampleTaskExecution(String taskName) {
+ TaskExecution taskExecution = new TaskExecution();
+ taskExecution.setTaskName(taskName);
+ return taskExecution;
+ }
+
+ private void validateSingleEntry(String event) {
+ assertThat(taskExecutionListenerResults.size()).isEqualTo(1);
+ assertThat(taskExecutionListenerResults.get(0).getTaskName()).isEqualTo(event);
+ }
+
+ @Configuration
+ public static class TaskExecutionListenerConfiguration {
+
+ @Bean
+ public TaskRunComponent taskRunComponent() {
+ return new TaskRunComponent();
+ }
+ }
+
+ public static class TaskRunComponent {
+
+ @BeforeTask
+ public void initBeforeListener(TaskExecution taskExecution) {
+ TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
+ }
+
+ @AfterTask
+ public void initAfterListener(TaskExecution taskExecution) {
+ TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
+ }
+
+ @FailedTask
+ public void initFailedListener(TaskExecution taskExecution, Throwable exception) {
+ TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
+ }
+ }
+}
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskRepositoryJdbcTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskRepositoryJdbcTests.java
index caa30426..55506eef 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskRepositoryJdbcTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/SimpleTaskRepositoryJdbcTests.java
@@ -28,7 +28,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.cloud.task.repository.TaskRepository;
@@ -49,7 +49,7 @@ import static org.junit.Assert.assertEquals;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {EmbeddedDataSourceConfiguration.class,
- SimpleTaskConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class})
public class SimpleTaskRepositoryJdbcTests {
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/TaskDatabaseInitializerTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/TaskDatabaseInitializerTests.java
index b758ab6f..c0e7e324 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/TaskDatabaseInitializerTests.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/support/TaskDatabaseInitializerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2016 the original author or authors.
+ * Copyright 2015-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.
@@ -26,7 +26,7 @@ import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
-import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.TestConfiguration;
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -89,7 +89,7 @@ public class TaskDatabaseInitializerTests {
@Test(expected = BeanCreationException.class)
public void testMultipleDataSourcesContext() throws Exception {
this.context = new AnnotationConfigApplicationContext();
- this.context.register( SimpleTaskConfiguration.class,
+ this.context.register( SimpleTaskAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
DataSource dataSource = mock(DataSource.class);
diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/util/TestDefaultConfiguration.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/util/TestDefaultConfiguration.java
index a171a07b..7732c0e4 100644
--- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/util/TestDefaultConfiguration.java
+++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/util/TestDefaultConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2016 the original author or authors.
+ * Copyright 2015-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.
@@ -24,6 +24,7 @@ import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.task.configuration.TaskProperties;
import org.springframework.cloud.task.listener.TaskLifecycleListener;
+import org.springframework.cloud.task.listener.TaskListenerExecutorObjectFactory;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.cloud.task.repository.TaskNameResolver;
import org.springframework.cloud.task.repository.TaskRepository;
@@ -74,10 +75,15 @@ public class TestDefaultConfiguration implements InitializingBean {
return new SimpleTaskNameResolver();
}
+ @Bean
+ public TaskListenerExecutorObjectFactory taskListenerExecutorObjectProvider(ConfigurableApplicationContext context) {
+ return new TaskListenerExecutorObjectFactory(context);
+ }
+
@Bean
public TaskLifecycleListener taskHandler(TaskExplorer taskExplorer){
return new TaskLifecycleListener(taskRepository(), taskNameResolver(),
- applicationArguments, taskExplorer, taskProperties);
+ applicationArguments, taskExplorer, taskProperties, taskListenerExecutorObjectProvider(context));
}
@Override
diff --git a/spring-cloud-task-dependencies/pom.xml b/spring-cloud-task-dependencies/pom.xml
index 3a2fd0d2..3e3dede8 100644
--- a/spring-cloud-task-dependencies/pom.xml
+++ b/spring-cloud-task-dependencies/pom.xml
@@ -2,7 +2,7 @@
4.0.0
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
Spring Cloud Task Dependencies
Spring Cloud Task Dependencies
@@ -10,7 +10,7 @@
spring-cloud-dependencies-parent
org.springframework.cloud
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -19,22 +19,22 @@
org.springframework.cloud
spring-cloud-starter-task
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
org.springframework.cloud
spring-cloud-task-core
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
org.springframework.cloud
spring-cloud-task-batch
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
org.springframework.cloud
spring-cloud-task-stream
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
diff --git a/spring-cloud-task-docs/pom.xml b/spring-cloud-task-docs/pom.xml
index 0f4ef93b..8eaf32b3 100644
--- a/spring-cloud-task-docs/pom.xml
+++ b/spring-cloud-task-docs/pom.xml
@@ -4,7 +4,7 @@
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
spring-cloud-task-docs
Spring Cloud Task Docs
diff --git a/spring-cloud-task-docs/src/main/asciidoc/batch.adoc b/spring-cloud-task-docs/src/main/asciidoc/batch.adoc
index da5d6321..e1cd3825 100644
--- a/spring-cloud-task-docs/src/main/asciidoc/batch.adoc
+++ b/spring-cloud-task-docs/src/main/asciidoc/batch.adoc
@@ -217,7 +217,7 @@ Batch/Boot behavior. Keep in mind that a task is a boot application and that the
returned from the task is the same as a boot application.
To override this behavior and allow the task to return an exit code other than zero when a
batch job returns an
-https://docs.spring.io/spring-batch/4.0.x/reference/html/step.html#conditionalFlow[ExitStatus]
+https://docs.spring.io/spring-batch/4.0.x/reference/html/step.html#batchStatusVsExitStatus[BatchStatus]
of `FAILED`, set `spring.cloud.task.batch.fail-on-job-failure` to `true`. Then the exit code
can be 1 (the default) or be based on the
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-application-exit[specified
diff --git a/spring-cloud-task-docs/src/main/asciidoc/features.adoc b/spring-cloud-task-docs/src/main/asciidoc/features.adoc
index 743dd5cd..00b4cacd 100644
--- a/spring-cloud-task-docs/src/main/asciidoc/features.adoc
+++ b/spring-cloud-task-docs/src/main/asciidoc/features.adoc
@@ -33,8 +33,7 @@ processes, typified by most web applications, do not save their lifecycle events
tasks at the heart of Spring Cloud Task do.
The lifecycle consists of a single task execution. This is a physical execution of a
-Spring Boot application configured to be a task (that is, it has the `@EnableTask`
-annotation).
+Spring Boot application configured to be a task (that is, it has the Sprint Cloud Task dependencies).
At the beginning of a task, before any `CommandLineRunner` or `ApplicationRunner`
implementations have been run, an entry in the `TaskRepository` that records the start
@@ -367,3 +366,14 @@ application:
org.springframework.integration
spring-integration-jdbc
+
+=== Disabling Spring Cloud Task Auto Configuration
+
+In cases where Spring Cloud Task should not be auto configured for an implementation, you can disable Task's auto configuration.
+This can be done either by adding the following annotation to your Task application:
+```
+@EnableAutoConfiguration(exclude={SimpleTaskAutoConfiguration.class})
+```
+You may also disable Task auto configuration by setting the `spring.cloud.task.autoconfiguration.enabled` property to `false`.
+
+
diff --git a/spring-cloud-task-docs/src/main/asciidoc/getting-started.adoc b/spring-cloud-task-docs/src/main/asciidoc/getting-started.adoc
index d039d752..e5e877e2 100755
--- a/spring-cloud-task-docs/src/main/asciidoc/getting-started.adoc
+++ b/spring-cloud-task-docs/src/main/asciidoc/getting-started.adoc
@@ -77,12 +77,11 @@ package io.spring.demo.helloworld;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
-@EnableTask
public class HelloworldApplication {
+public class SampleTask {
@Bean
public CommandLineRunner commandLineRunner() {
@@ -124,13 +123,10 @@ spring.application.name=helloWorld
----
[[getting-started-at-task]]
-==== The @EnableTask annotation
+==== Task Auto Configuration
-The first non-boot annotation in our example is the `@EnableTask` annotation. This
-class-level annotation tells Spring Cloud Task to bootstrap it's functionality. By
-default, it imports an additional configuration class (`SimpleTaskConfiguration`). This
-additional configuration registers the `TaskRepository` and the infrastructure for its
-use.
+When including Spring Cloud Task Starter dependency, Task auto configures all beans to bootstrap it's functionality.
+Part of this configuration registers the `TaskRepository` and the infrastructure for its use.
In our demo, the `TaskRepository` uses an embedded H2 database to record the results
of a task. This H2 embedded database is not a practical solution for a production environment, since
diff --git a/spring-cloud-task-docs/src/main/asciidoc/stream.adoc b/spring-cloud-task-docs/src/main/asciidoc/stream.adoc
index f4a0d7d8..af473d66 100644
--- a/spring-cloud-task-docs/src/main/asciidoc/stream.adoc
+++ b/spring-cloud-task-docs/src/main/asciidoc/stream.adoc
@@ -93,7 +93,6 @@ event on the `task-events` channel (at both the start and the end of the task):
[source, java]
----
@SpringBootApplication
-@EnableTask
public class TaskEventsApplication {
public static void main(String[] args) {
diff --git a/spring-cloud-task-integration-tests/pom.xml b/spring-cloud-task-integration-tests/pom.xml
index 24202898..ead1a69d 100644
--- a/spring-cloud-task-integration-tests/pom.xml
+++ b/spring-cloud-task-integration-tests/pom.xml
@@ -3,7 +3,7 @@
spring-cloud-task-parent
org.springframework.cloud
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
4.0.0
Spring Cloud Task Integration Tests
@@ -16,7 +16,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -72,7 +72,7 @@
io.spring.cloud
partitioned-batch-job
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
test
diff --git a/spring-cloud-task-integration-tests/src/test/java/configuration/JobConfiguration.java b/spring-cloud-task-integration-tests/src/test/java/configuration/JobConfiguration.java
index d09c9d55..cc6591c2 100644
--- a/spring-cloud-task-integration-tests/src/test/java/configuration/JobConfiguration.java
+++ b/spring-cloud-task-integration-tests/src/test/java/configuration/JobConfiguration.java
@@ -32,7 +32,6 @@ import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -41,7 +40,6 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
@EnableBatchProcessing
-@EnableTask
public class JobConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
diff --git a/spring-cloud-task-integration-tests/src/test/java/configuration/JobSkipConfiguration.java b/spring-cloud-task-integration-tests/src/test/java/configuration/JobSkipConfiguration.java
index 0b33f572..dfa5e584 100644
--- a/spring-cloud-task-integration-tests/src/test/java/configuration/JobSkipConfiguration.java
+++ b/spring-cloud-task-integration-tests/src/test/java/configuration/JobSkipConfiguration.java
@@ -27,7 +27,6 @@ import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -36,7 +35,6 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
@EnableBatchProcessing
-@EnableTask
public class JobSkipConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
diff --git a/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/executionid/TaskStartApplication.java b/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/executionid/TaskStartApplication.java
index d07d5ca3..c09e3079 100644
--- a/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/executionid/TaskStartApplication.java
+++ b/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/executionid/TaskStartApplication.java
@@ -19,14 +19,12 @@ package org.springframework.cloud.task.executionid;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
/**
* @author Glenn Renfro
*/
@SpringBootApplication
-@EnableTask
public class TaskStartApplication {
public static void main(String[] args) {
diff --git a/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java b/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java
index f88b094b..ffad327e 100644
--- a/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java
+++ b/spring-cloud-task-integration-tests/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java
@@ -22,18 +22,22 @@ import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
-import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.binder.rabbit.config.RabbitServiceAutoConfiguration;
import org.springframework.cloud.stream.binder.test.junit.rabbit.RabbitTestSupport;
+import org.springframework.cloud.stream.config.BindingServiceConfiguration;
import org.springframework.cloud.stream.messaging.Sink;
-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.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.junit4.SpringRunner;
@@ -59,21 +63,26 @@ public class TaskEventTests {
@Test
public void testTaskEventListener() throws Exception {
- ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder().sources(new Class[] {TaskEventsConfiguration.class,
- TaskEventAutoConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class,
- RabbitServiceAutoConfiguration.class}).build().run("--spring.cloud.task.closecontext_enabled=false",
- "--spring.cloud.task.name=" + TASK_NAME,
- "--spring.main.web-environment=false",
- "--spring.cloud.stream.defaultBinder=rabbit",
- "--spring.cloud.stream.bindings.task-events.destination=test");
- assertNotNull(applicationContext.getBean("taskEventListener"));
- assertNotNull(applicationContext.getBean(TaskEventAutoConfiguration.TaskEventChannels.class));
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(TaskEventsConfiguration.class,
+ TaskEventAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class,
+ RabbitServiceAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ BindingServiceConfiguration.class))
+ .withPropertyValues("--spring.cloud.task.closecontext_enabled=false",
+ "--spring.cloud.task.name=" + TASK_NAME,
+ "--spring.main.web-environment=false",
+ "--spring.cloud.stream.defaultBinder=rabbit",
+ "--spring.cloud.stream.bindings.task-events.destination=test");
+ applicationContextRunner.run((context) -> {
+ assertNotNull(context.getBean("taskEventListener"));
+ assertNotNull(context.getBean(TaskEventAutoConfiguration.TaskEventChannels.class));
+ });
assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@Configuration
- @EnableTask
public static class TaskEventsConfiguration {
}
@@ -87,5 +96,15 @@ public class TaskEventTests {
assertTrue(String.format("Task name should be '%s'", TASK_NAME), execution.getTaskName().equals(TASK_NAME));
latch.countDown();
}
+
+ @Bean
+ public CommandLineRunner commandLineRunner(){
+ return new CommandLineRunner() {
+ @Override
+ public void run(String... args) throws Exception {
+ System.out.println("Hello World");
+ }
+ };
+ }
}
}
diff --git a/spring-cloud-task-samples/batch-events/pom.xml b/spring-cloud-task-samples/batch-events/pom.xml
index 53e77e63..e8e1b958 100644
--- a/spring-cloud-task-samples/batch-events/pom.xml
+++ b/spring-cloud-task-samples/batch-events/pom.xml
@@ -4,7 +4,7 @@
io.spring.cloud
batch-events
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
jar
Batch Events Sample Application
@@ -13,7 +13,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -47,19 +47,19 @@
org.springframework.cloud
spring-cloud-starter-stream-rabbit
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
compile
org.springframework.cloud
spring-cloud-stream-binder-rabbit-test-support
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
test
org.springframework.cloud
spring-cloud-stream-test-support-internal
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
test
@@ -70,6 +70,7 @@
org.hsqldb
hsqldb
+
diff --git a/spring-cloud-task-samples/batch-events/src/main/java/io/spring/cloud/BatchEventsApplication.java b/spring-cloud-task-samples/batch-events/src/main/java/io/spring/cloud/BatchEventsApplication.java
index cfee7c96..3a31a627 100644
--- a/spring-cloud-task-samples/batch-events/src/main/java/io/spring/cloud/BatchEventsApplication.java
+++ b/spring-cloud-task-samples/batch-events/src/main/java/io/spring/cloud/BatchEventsApplication.java
@@ -34,12 +34,10 @@ import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
-@EnableTask
@EnableBatchProcessing
public class BatchEventsApplication {
diff --git a/spring-cloud-task-samples/batch-events/src/test/java/io/spring/cloud/BatchEventsApplicationTests.java b/spring-cloud-task-samples/batch-events/src/test/java/io/spring/cloud/BatchEventsApplicationTests.java
index 8d4563e0..5c69aa2d 100644
--- a/spring-cloud-task-samples/batch-events/src/test/java/io/spring/cloud/BatchEventsApplicationTests.java
+++ b/spring-cloud-task-samples/batch-events/src/test/java/io/spring/cloud/BatchEventsApplicationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -50,12 +50,14 @@ public class BatchEventsApplicationTests {
context.close();
}
}
-
+
@Test
public void testExecution() throws Exception {
SpringApplication.run(JobExecutionListenerBinding.class, "--spring.main.web-environment=false");
SpringApplication.run(BatchEventsApplication.class, "--server.port=0",
- "--spring.cloud.stream.bindings.output.producer.requiredGroups=testgroup");
+ "--spring.cloud.stream.bindings.output.producer.requiredGroups=testgroup",
+ "--spring.jmx.default-domain=fakedomain",
+ "--spring.main.webEnvironment=false");
Assert.assertTrue("The latch did not count down to zero before timeout",
jobExecutionLatch.await(60, TimeUnit.SECONDS));
}
diff --git a/spring-cloud-task-samples/batch-job/pom.xml b/spring-cloud-task-samples/batch-job/pom.xml
index 39cc65cc..484f2853 100644
--- a/spring-cloud-task-samples/batch-job/pom.xml
+++ b/spring-cloud-task-samples/batch-job/pom.xml
@@ -5,7 +5,7 @@
io.spring.cloud
batch-job
jar
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
Spring Cloud Task Batch Example
Batch Job Sample Application
@@ -13,7 +13,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -53,6 +53,10 @@
spring-boot-starter-test
test
+
+ org.mariadb.jdbc
+ mariadb-java-client
+
diff --git a/spring-cloud-task-samples/batch-job/src/main/java/io/spring/BatchJobApplication.java b/spring-cloud-task-samples/batch-job/src/main/java/io/spring/BatchJobApplication.java
index b05f5579..d2237984 100644
--- a/spring-cloud-task-samples/batch-job/src/main/java/io/spring/BatchJobApplication.java
+++ b/spring-cloud-task-samples/batch-job/src/main/java/io/spring/BatchJobApplication.java
@@ -3,10 +3,8 @@ package io.spring;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
@SpringBootApplication
-@EnableTask
@EnableBatchProcessing
public class BatchJobApplication {
diff --git a/spring-cloud-task-samples/jpa-sample/pom.xml b/spring-cloud-task-samples/jpa-sample/pom.xml
index 54aa371d..5ee60343 100644
--- a/spring-cloud-task-samples/jpa-sample/pom.xml
+++ b/spring-cloud-task-samples/jpa-sample/pom.xml
@@ -19,7 +19,7 @@
io.spring.cloud
jpa-sample
jar
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
To show users how to enable a task with a JPA application.
Spring Cloud Task JPA Sample Application
@@ -27,7 +27,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -41,7 +41,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
diff --git a/spring-cloud-task-samples/jpa-sample/src/main/java/io/spring/JpaApplication.java b/spring-cloud-task-samples/jpa-sample/src/main/java/io/spring/JpaApplication.java
index 7675425b..46d76fe8 100644
--- a/spring-cloud-task-samples/jpa-sample/src/main/java/io/spring/JpaApplication.java
+++ b/spring-cloud-task-samples/jpa-sample/src/main/java/io/spring/JpaApplication.java
@@ -18,10 +18,8 @@ package io.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
@SpringBootApplication
-@EnableTask
public class JpaApplication {
public static void main(String[] args) {
diff --git a/spring-cloud-task-samples/jpa-sample/src/test/java/io/spring/JpaApplicationTests.java b/spring-cloud-task-samples/jpa-sample/src/test/java/io/spring/JpaApplicationTests.java
index 4b192bf0..67d64c29 100644
--- a/spring-cloud-task-samples/jpa-sample/src/test/java/io/spring/JpaApplicationTests.java
+++ b/spring-cloud-task-samples/jpa-sample/src/test/java/io/spring/JpaApplicationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-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.
@@ -101,7 +101,7 @@ public class JpaApplicationTests {
assertTrue("Unable to find the insert message: " + output, output.contains(INSERT_MESSAGE));
JdbcTemplate template = new JdbcTemplate(this.dataSource);
Map result = template.queryForMap("Select * from TASK_RUN_OUTPUT");
- assertThat((result.get("ID")), is(1L));
+ assertThat((Long)(result.get("ID")), is(1L));
assertThat(((String) result.get("OUTPUT")), containsString("Executed at"));
}
diff --git a/spring-cloud-task-samples/multiple-datasources/pom.xml b/spring-cloud-task-samples/multiple-datasources/pom.xml
index e5ab27f2..9daa1427 100644
--- a/spring-cloud-task-samples/multiple-datasources/pom.xml
+++ b/spring-cloud-task-samples/multiple-datasources/pom.xml
@@ -5,7 +5,7 @@
io.spring.cloud
multiple-datasources
jar
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
To show users how to enable a task with a multiple DataSources.
Spring Cloud Task Multiple DataSources Application
@@ -13,7 +13,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
diff --git a/spring-cloud-task-samples/multiple-datasources/src/main/java/io/spring/MultipleDataSourcesApplication.java b/spring-cloud-task-samples/multiple-datasources/src/main/java/io/spring/MultipleDataSourcesApplication.java
index 13311519..8d34fca5 100644
--- a/spring-cloud-task-samples/multiple-datasources/src/main/java/io/spring/MultipleDataSourcesApplication.java
+++ b/spring-cloud-task-samples/multiple-datasources/src/main/java/io/spring/MultipleDataSourcesApplication.java
@@ -18,14 +18,12 @@ package io.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
/**
* @author Michael Minella
*/
@SpringBootApplication
-@EnableTask
public class MultipleDataSourcesApplication {
public static void main(String[] args) {
diff --git a/spring-cloud-task-samples/partitioned-batch-job/pom.xml b/spring-cloud-task-samples/partitioned-batch-job/pom.xml
index 317625d9..2483fc15 100644
--- a/spring-cloud-task-samples/partitioned-batch-job/pom.xml
+++ b/spring-cloud-task-samples/partitioned-batch-job/pom.xml
@@ -6,13 +6,13 @@
partitioned-batch-job
jar
Partitioned Batch Job
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
Sample of using the DeployerPartitionHandler
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -26,7 +26,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
diff --git a/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/JobConfiguration.java b/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/JobConfiguration.java
index 113fc983..3e81dfc1 100644
--- a/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/JobConfiguration.java
+++ b/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/JobConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -81,15 +81,6 @@ public class JobConfiguration {
private static final int GRID_SIZE = 4;
- @Bean
- public JobExplorerFactoryBean jobExplorer() {
- JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
-
- jobExplorerFactoryBean.setDataSource(this.dataSource);
-
- return jobExplorerFactoryBean;
- }
-
@Bean
public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer) throws Exception {
Resource resource = resourceLoader.getResource("maven://io.spring.cloud:partitioned-batch-job:1.1.0.RELEASE");
diff --git a/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/PartitionedBatchJobApplication.java b/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/PartitionedBatchJobApplication.java
index 7a042cf1..692699aa 100644
--- a/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/PartitionedBatchJobApplication.java
+++ b/spring-cloud-task-samples/partitioned-batch-job/src/main/java/io/spring/PartitionedBatchJobApplication.java
@@ -3,11 +3,9 @@ package io.spring;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
@SpringBootApplication
@EnableBatchProcessing
-@EnableTask
public class PartitionedBatchJobApplication {
public static void main(String[] args) {
diff --git a/spring-cloud-task-samples/pom.xml b/spring-cloud-task-samples/pom.xml
index 77b592e5..5800d766 100644
--- a/spring-cloud-task-samples/pom.xml
+++ b/spring-cloud-task-samples/pom.xml
@@ -11,7 +11,7 @@
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
@@ -36,7 +36,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
diff --git a/spring-cloud-task-samples/task-events/pom.xml b/spring-cloud-task-samples/task-events/pom.xml
index 5529cbf3..90be4a6b 100644
--- a/spring-cloud-task-samples/task-events/pom.xml
+++ b/spring-cloud-task-samples/task-events/pom.xml
@@ -4,7 +4,7 @@
io.spring.cloud
task-events
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
jar
Task Events
@@ -13,7 +13,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -43,10 +43,9 @@
org.springframework.cloud
spring-cloud-starter-stream-rabbit
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
compile
-
org.springframework.boot
spring-boot-starter-test
diff --git a/spring-cloud-task-samples/task-events/src/main/java/io/spring/TaskEventsApplication.java b/spring-cloud-task-samples/task-events/src/main/java/io/spring/TaskEventsApplication.java
index ee7093b7..4858e200 100644
--- a/spring-cloud-task-samples/task-events/src/main/java/io/spring/TaskEventsApplication.java
+++ b/spring-cloud-task-samples/task-events/src/main/java/io/spring/TaskEventsApplication.java
@@ -18,12 +18,10 @@ package io.spring;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
-@EnableTask
public class TaskEventsApplication {
public static void main(String[] args) {
diff --git a/spring-cloud-task-samples/taskprocessor/pom.xml b/spring-cloud-task-samples/taskprocessor/pom.xml
index df29d82a..15f5f3e0 100644
--- a/spring-cloud-task-samples/taskprocessor/pom.xml
+++ b/spring-cloud-task-samples/taskprocessor/pom.xml
@@ -4,7 +4,7 @@
io.spring.cloud
taskprocessor
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
jar
Task Processor Sample Application
@@ -13,7 +13,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -42,7 +42,7 @@
org.springframework.cloud
spring-cloud-starter-stream-rabbit
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
compile
@@ -52,7 +52,7 @@
org.springframework.cloud
spring-cloud-stream-test-support
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
test
diff --git a/spring-cloud-task-samples/tasksink/pom.xml b/spring-cloud-task-samples/tasksink/pom.xml
index 0f966b54..f5ddabce 100644
--- a/spring-cloud-task-samples/tasksink/pom.xml
+++ b/spring-cloud-task-samples/tasksink/pom.xml
@@ -4,7 +4,7 @@
io.spring.cloud
tasksink
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
jar
Task Sink Sample Application
@@ -13,7 +13,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -42,13 +42,13 @@
org.springframework.cloud
spring-cloud-starter-stream-rabbit
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
compile
org.springframework.cloud
spring-cloud-stream-test-support
- 2.0.0.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
test
diff --git a/spring-cloud-task-samples/timestamp/pom.xml b/spring-cloud-task-samples/timestamp/pom.xml
index adf64e93..89e804c3 100644
--- a/spring-cloud-task-samples/timestamp/pom.xml
+++ b/spring-cloud-task-samples/timestamp/pom.xml
@@ -7,13 +7,13 @@
timestamp-task
jar
Timestamp Task
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
Spring Cloud Timestamp Task
org.springframework.boot
spring-boot-starter-parent
- 2.0.1.RELEASE
+ 2.1.0.BUILD-SNAPSHOT
@@ -27,7 +27,7 @@
org.springframework.cloud
spring-cloud-task-dependencies
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
pom
import
@@ -57,6 +57,10 @@
com.h2database
h2
+
+ org.mariadb.jdbc
+ mariadb-java-client
+
diff --git a/spring-cloud-task-samples/timestamp/src/main/java/org/springframework/cloud/task/timestamp/TaskApplication.java b/spring-cloud-task-samples/timestamp/src/main/java/org/springframework/cloud/task/timestamp/TaskApplication.java
index 22e0cb0d..3d9bd8d8 100644
--- a/spring-cloud-task-samples/timestamp/src/main/java/org/springframework/cloud/task/timestamp/TaskApplication.java
+++ b/spring-cloud-task-samples/timestamp/src/main/java/org/springframework/cloud/task/timestamp/TaskApplication.java
@@ -29,14 +29,12 @@ import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
/**
* Spring Boot Application that has tasks enabled.
*/
@SpringBootApplication
-@EnableTask
@EnableConfigurationProperties({ TimestampTaskProperties.class })
public class TaskApplication {
diff --git a/spring-cloud-task-stream/pom.xml b/spring-cloud-task-stream/pom.xml
index 44e0a2e2..5059753d 100644
--- a/spring-cloud-task-stream/pom.xml
+++ b/spring-cloud-task-stream/pom.xml
@@ -10,7 +10,7 @@
org.springframework.cloud
spring-cloud-task-parent
- 2.0.1.BUILD-SNAPSHOT
+ 2.1.0.BUILD-SNAPSHOT
diff --git a/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/batch/listener/BatchEventAutoConfiguration.java b/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/batch/listener/BatchEventAutoConfiguration.java
index 7c2707da..d28e5973 100644
--- a/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/batch/listener/BatchEventAutoConfiguration.java
+++ b/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/batch/listener/BatchEventAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -24,6 +24,7 @@ import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.SkipListener;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -33,6 +34,7 @@ import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.cloud.task.batch.listener.support.TaskBatchEventListenerBeanPostProcessor;
import org.springframework.cloud.task.batch.listener.support.TaskEventProperties;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.listener.TaskLifecycleListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -60,6 +62,7 @@ import org.springframework.messaging.MessageChannel;
@ConditionalOnClass(Job.class)
@ConditionalOnBean(value = { Job.class, TaskLifecycleListener.class })
@ConditionalOnProperty(prefix = "spring.cloud.task.batch.events", name = "enabled", havingValue = "true", matchIfMissing = true)
+@AutoConfigureAfter(SimpleTaskAutoConfiguration.class)
public class BatchEventAutoConfiguration {
public final static String JOB_EXECUTION_EVENTS_LISTENER = "jobExecutionEventsListener";
diff --git a/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/listener/TaskEventAutoConfiguration.java b/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/listener/TaskEventAutoConfiguration.java
index 36142271..a5de53e8 100644
--- a/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/listener/TaskEventAutoConfiguration.java
+++ b/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/listener/TaskEventAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-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.
@@ -15,12 +15,15 @@
*/
package org.springframework.cloud.task.listener;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Output;
+import org.springframework.cloud.stream.config.BindingServiceConfiguration;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@@ -36,21 +39,20 @@ import org.springframework.messaging.MessageChannel;
@ConditionalOnBean(TaskLifecycleListener.class)
@ConditionalOnProperty(prefix = "spring.cloud.task.events", name = "enabled", havingValue = "true", matchIfMissing = true)
@PropertySource("classpath:/org/springframework/cloud/task/application.properties")
+@AutoConfigureBefore(BindingServiceConfiguration.class)
+@AutoConfigureAfter(SimpleTaskAutoConfiguration.class)
public class TaskEventAutoConfiguration {
@Configuration
@EnableBinding(TaskEventChannels.class)
public static class ListenerConfiguration {
- @Autowired
- private TaskEventChannels taskEventChannels;
-
@Bean
public GatewayProxyFactoryBean taskEventListener() {
GatewayProxyFactoryBean factoryBean =
new GatewayProxyFactoryBean(TaskExecutionListener.class);
- factoryBean.setDefaultRequestChannel(taskEventChannels.taskEvents());
+ factoryBean.setDefaultRequestChannelName(TaskEventChannels.TASK_EVENTS);
return factoryBean;
}
diff --git a/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/batch/listener/JobExecutionEventTests.java b/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/batch/listener/JobExecutionEventTests.java
index e0770cb7..1e8088f9 100644
--- a/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/batch/listener/JobExecutionEventTests.java
+++ b/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/batch/listener/JobExecutionEventTests.java
@@ -34,15 +34,16 @@ import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
import org.springframework.cloud.task.batch.listener.support.JobExecutionEvent;
import org.springframework.cloud.task.batch.listener.support.JobInstanceEvent;
import org.springframework.cloud.task.batch.listener.support.StepExecutionEvent;
-import org.springframework.cloud.task.configuration.EnableTask;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
+import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -275,12 +276,15 @@ public class JobExecutionEventTests {
@Test
public void testOrderConfiguration() {
- ConfigurableApplicationContext applicationContext =
- SpringApplication.run(new Class[]{BatchEventAutoConfiguration.JobExecutionListenerConfiguration.class,
- EventJobExecutionConfiguration.class,
- PropertyPlaceholderAutoConfiguration.class,
- TestSupportBinderAutoConfiguration.class},
- new String[]{"--spring.cloud.task.closecontext_enabled=false",
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
+ EventJobExecutionConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class,
+ TestSupportBinderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withUserConfiguration(BatchEventAutoConfiguration.JobExecutionListenerConfiguration.class)
+ .withPropertyValues("--spring.cloud.task.closecontext_enabled=false",
"--spring.main.web-environment=false",
"--spring.cloud.task.batch.events.chunk-order=5",
"--spring.cloud.task.batch.events.item-process-order=5",
@@ -288,30 +292,35 @@ public class JobExecutionEventTests {
"--spring.cloud.task.batch.events.item-write-order=5",
"--spring.cloud.task.batch.events.job-execution-order=5",
"--spring.cloud.task.batch.events.skip-order=5",
- "--spring.cloud.task.batch.events.step-execution-order=5"
- });
+ "--spring.cloud.task.batch.events.step-execution-order=5");
+ applicationContextRunner.run((context) -> {
for (String beanName : LISTENER_BEAN_NAMES) {
- Ordered ordered = (Ordered)applicationContext.getBean(beanName);
+ Ordered ordered = (Ordered)context.getBean(beanName);
assertEquals("Expected order value of 5 for " + beanName,ordered.getOrder(),5);
}
+
+ });
}
private void testDisabledConfiguration(String property, String disabledListener) {
- boolean exceptionThrown = false;
String disabledPropertyArg = (property != null) ? "--" + property + "=false" : "";
- ConfigurableApplicationContext applicationContext =
- SpringApplication.run(new Class[]{BatchEventAutoConfiguration.JobExecutionListenerConfiguration.class,
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(
EventJobExecutionConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
- TestSupportBinderAutoConfiguration.class},
- new String[]{"--spring.cloud.task.closecontext_enabled=false",
- "--spring.main.web-environment=false",
- disabledPropertyArg});
-
+ TestSupportBinderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class))
+ .withUserConfiguration(BatchEventAutoConfiguration.JobExecutionListenerConfiguration.class)
+ .withPropertyValues("--spring.cloud.task.closecontext_enabled=false",
+ "--spring.main.web-environment=false",
+ disabledPropertyArg);
+ applicationContextRunner.run((context) -> {
+ boolean exceptionThrown = false;
for (String beanName : LISTENER_BEAN_NAMES) {
if (disabledListener != null && disabledListener.equals(beanName)) {
try {
- applicationContext.getBean(disabledListener);
+ context.getBean(disabledListener);
}
catch (NoSuchBeanDefinitionException nsbde) {
exceptionThrown = true;
@@ -319,15 +328,15 @@ public class JobExecutionEventTests {
assertTrue(String.format("Did not expect %s bean in context", beanName), exceptionThrown);
}
else {
- applicationContext.getBean(beanName);
+ context.getBean(beanName);
}
}
- applicationContext.getBean(BatchEventAutoConfiguration.BatchEventsChannels.class);
+ });
+
}
@Configuration
- @EnableTask
public static class EventJobExecutionConfiguration {
}
}
diff --git a/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java b/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java
index 6baaccb4..6c81adf1 100644
--- a/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java
+++ b/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java
@@ -17,13 +17,18 @@ package org.springframework.cloud.task.listener;
import org.junit.Test;
-import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.stream.config.BindingServiceConfiguration;
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
-import org.springframework.cloud.task.configuration.EnableTask;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
+import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.annotation.BridgeFrom;
+import org.springframework.integration.channel.NullChannel;
import static org.junit.Assert.assertNotNull;
@@ -38,20 +43,31 @@ public class TaskEventTests {
@Test
public void testDefaultConfiguration() {
- ConfigurableApplicationContext applicationContext =
- SpringApplication.run(new Class[]{PropertyPlaceholderAutoConfiguration.class,EmbeddedDataSourceConfiguration.class,TaskEventsConfiguration.class,
- TaskEventAutoConfiguration.class,
- TestSupportBinderAutoConfiguration.class},
- new String[]{ "--spring.cloud.task.closecontext_enabled=false",
- "--spring.main.web-environment=false"});
-
- assertNotNull(applicationContext.getBean("taskEventListener"));
- assertNotNull(applicationContext.getBean(TaskEventAutoConfiguration.TaskEventChannels.class));
+ ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
+ TaskEventAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class,
+ TestSupportBinderAutoConfiguration.class,
+ SimpleTaskAutoConfiguration.class,
+ SingleTaskConfiguration.class,
+ BindingServiceConfiguration.class))
+ .withUserConfiguration(TaskEventsConfiguration.class)
+ .withPropertyValues("spring.cloud.task.closecontext_enabled=false",
+ "spring.main.web-environment=false");
+ applicationContextRunner.run((context) -> {
+ assertNotNull(context.getBean("taskEventListener"));
+ assertNotNull(context.getBean(TaskEventAutoConfiguration.TaskEventChannels.class));
+ });
}
@Configuration
- @EnableTask
public static class TaskEventsConfiguration {
+
+ @Bean
+ @BridgeFrom(TaskEventAutoConfiguration.TaskEventChannels.TASK_EVENTS)
+ public NullChannel testEmptyChannel() {
+ return new NullChannel();
+ }
}
}