Refactor of Task API
This change removes the Spring Cloud Task dependency upon a CommandLineRunner from boot and moves the handling of the task lifecycle closer to the "edge" of a Spring Boot application. With this change, now a developer simply adds @EnableTask to their configuration somewhere and the task lifecycle will be recorded. Resolves spring-cloud/spring-cloud-task#39
This commit is contained in:
committed by
Glenn Renfro
parent
7be3a88826
commit
61d3cc3641
@@ -25,16 +25,15 @@ $ mvn -s settings.xml clean install
|
|||||||
public class MyApp {
|
public class MyApp {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MyTask myTask() {
|
public MyTaskApplication myTask() {
|
||||||
return new MyTask();
|
return new MyTaskApplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(MyApp.class);
|
SpringApplication.run(MyApp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Task("HelloWorldTask")
|
public static class MyTaskApplication implements CommandLineRunner {
|
||||||
public static class MyTask implements CommandLineRunner {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(String... strings) throws Exception {
|
public void run(String... strings) throws Exception {
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -8,7 +8,7 @@
|
|||||||
<!-- Import dependency management from Spring Boot -->
|
<!-- Import dependency management from Spring Boot -->
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
<version>1.3.0.RELEASE</version>
|
<version>1.3.2.BUILD-SNAPSHOT</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
@@ -39,18 +39,10 @@
|
|||||||
<groupId>ch.qos.logback</groupId>
|
<groupId>ch.qos.logback</groupId>
|
||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-aop</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-jdbc</artifactId>
|
<artifactId>spring-jdbc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjweaver</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
||||||
@@ -71,6 +63,10 @@
|
|||||||
<artifactId>tomcat-jdbc</artifactId>
|
<artifactId>tomcat-jdbc</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.batch</groupId>
|
||||||
|
<artifactId>spring-batch-infrastructure</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 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.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation that identifies a class as a task. This annotation will serve as the
|
|
||||||
* main “hook” to activate the various Spring Cloud Task features.
|
|
||||||
*
|
|
||||||
* @author Glenn Renfro
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
@Inherited
|
|
||||||
public @interface Task {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Establishes the name associated with the task. The default is empty.
|
|
||||||
* @return returns name associated with the task or an empty string.
|
|
||||||
*/
|
|
||||||
public String value() default "";
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Annotations for spring cloud task.
|
|
||||||
*/
|
|
||||||
package org.springframework.cloud.task.annotation;
|
|
||||||
@@ -20,6 +20,8 @@ import javax.sql.DataSource;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
||||||
@@ -29,6 +31,8 @@ import org.springframework.cloud.task.repository.support.JdbcTaskRepositoryFacto
|
|||||||
import org.springframework.cloud.task.repository.support.MapTaskExplorerFactoryBean;
|
import org.springframework.cloud.task.repository.support.MapTaskExplorerFactoryBean;
|
||||||
import org.springframework.cloud.task.repository.support.MapTaskRepositoryFactoryBean;
|
import org.springframework.cloud.task.repository.support.MapTaskRepositoryFactoryBean;
|
||||||
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
||||||
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the TaskConfigurer interface. If no {@link TaskConfigurer}
|
* Default implementation of the TaskConfigurer interface. If no {@link TaskConfigurer}
|
||||||
@@ -52,6 +56,8 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
|
|
||||||
private TaskExplorer taskExplorer;
|
private TaskExplorer taskExplorer;
|
||||||
|
|
||||||
|
private PlatformTransactionManager transactionManager;
|
||||||
|
|
||||||
public DefaultTaskConfigurer(){
|
public DefaultTaskConfigurer(){
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
@@ -61,14 +67,21 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public TaskRepository getTaskRepository() {
|
public TaskRepository getTaskRepository() {
|
||||||
return taskRepository;
|
return taskRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public TaskExplorer getTaskExplorer() {
|
public TaskExplorer getTaskExplorer() {
|
||||||
return taskExplorer;
|
return taskExplorer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformTransactionManager getTransactionManager() {
|
||||||
|
return this.transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
private void initialize(){
|
private void initialize(){
|
||||||
logger.debug("Initializing TaskRepository");
|
logger.debug("Initializing TaskRepository");
|
||||||
if (dataSource == null) {
|
if (dataSource == null) {
|
||||||
@@ -78,6 +91,7 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
MapTaskExplorerFactoryBean mapTaskExplorerFactoryBean =
|
MapTaskExplorerFactoryBean mapTaskExplorerFactoryBean =
|
||||||
new MapTaskExplorerFactoryBean();
|
new MapTaskExplorerFactoryBean();
|
||||||
taskExplorer = mapTaskExplorerFactoryBean.getObject();
|
taskExplorer = mapTaskExplorerFactoryBean.getObject();
|
||||||
|
transactionManager = new ResourcelessTransactionManager();
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -87,6 +101,7 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
JdbcTaskExplorerFactoryBean jdbcTaskExplorerFactoryBean =
|
JdbcTaskExplorerFactoryBean jdbcTaskExplorerFactoryBean =
|
||||||
new JdbcTaskExplorerFactoryBean(dataSource);
|
new JdbcTaskExplorerFactoryBean(dataSource);
|
||||||
taskExplorer = jdbcTaskExplorerFactoryBean.getObject();
|
taskExplorer = jdbcTaskExplorerFactoryBean.getObject();
|
||||||
|
transactionManager = new DataSourceTransactionManager(dataSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.annotation;
|
package org.springframework.cloud.task.configuration;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
@@ -24,16 +24,12 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
|
|
||||||
import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
|
|
||||||
import org.springframework.cloud.task.configuration.TaskConfigurer;
|
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Enable Spring Task features and provide a base configuration for setting up
|
* Enable Spring Task features.
|
||||||
* {@link Task} objects in an @Configuration class.
|
|
||||||
*
|
*
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
* @Configuration
|
* @Configuration
|
||||||
@@ -23,15 +23,17 @@ import javax.sql.DataSource;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.cloud.task.listener.TaskLifecycleListener;
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
import org.springframework.cloud.task.repository.support.TaskDatabaseInitializer;
|
import org.springframework.cloud.task.repository.support.TaskDatabaseInitializer;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,13 +43,12 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@EnableTransactionManagement
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
public class SimpleTaskConfiguration {
|
public class SimpleTaskConfiguration {
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(SimpleTaskConfiguration.class);
|
protected static final Log logger = LogFactory.getLog(SimpleTaskConfiguration.class);
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext context;
|
private ApplicationContext context;
|
||||||
|
|
||||||
@@ -66,17 +67,23 @@ public class SimpleTaskConfiguration {
|
|||||||
|
|
||||||
private TaskConfigurer configurer;
|
private TaskConfigurer configurer;
|
||||||
|
|
||||||
@Bean
|
private PlatformTransactionManager transactionManager;
|
||||||
@Scope("prototype")
|
|
||||||
public TaskHandler taskHandler() {
|
|
||||||
return new TaskHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskRepository taskRepository(){
|
public TaskRepository taskRepository(){
|
||||||
return taskRepository;
|
return taskRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TaskLifecycleListener taskLifecycleListener() {
|
||||||
|
return new TaskLifecycleListener(taskRepository());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PlatformTransactionManager transactionManager() {
|
||||||
|
return this.transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the basic components by extracting them from the {@link TaskConfigurer}, defaulting to some
|
* Sets up the basic components by extracting them from the {@link TaskConfigurer}, defaulting to some
|
||||||
* sensible values as long as a unique DataSource is available.
|
* sensible values as long as a unique DataSource is available.
|
||||||
@@ -93,6 +100,7 @@ public class SimpleTaskConfiguration {
|
|||||||
logger.debug(String.format("Using %s TaskConfigurer",
|
logger.debug(String.format("Using %s TaskConfigurer",
|
||||||
configurer.getClass().getName()));
|
configurer.getClass().getName()));
|
||||||
taskRepository = configurer.getTaskRepository();
|
taskRepository = configurer.getTaskRepository();
|
||||||
|
transactionManager = configurer.getTransactionManager();
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
|
|
||||||
|
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a strategy interface for providing configuration
|
* Provides a strategy interface for providing configuration
|
||||||
@@ -33,4 +35,7 @@ public interface TaskConfigurer {
|
|||||||
*/
|
*/
|
||||||
public TaskRepository getTaskRepository();
|
public TaskRepository getTaskRepository();
|
||||||
|
|
||||||
|
public PlatformTransactionManager getTransactionManager();
|
||||||
|
|
||||||
|
public TaskExplorer getTaskExplorer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 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 java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.AfterReturning;
|
|
||||||
import org.aspectj.lang.annotation.AfterThrowing;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.annotation.Before;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.ApplicationRunner;
|
|
||||||
import org.springframework.boot.CommandLineRunner;
|
|
||||||
import org.springframework.boot.ExitCodeGenerator;
|
|
||||||
import org.springframework.cloud.task.annotation.Task;
|
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Offers the advice on how to record tasks to the repository for both
|
|
||||||
* {@link org.springframework.boot.ApplicationRunner} and
|
|
||||||
* {@link org.springframework.boot.CommandLineRunner} spring boot applications.
|
|
||||||
*
|
|
||||||
* @author Glenn Renfro
|
|
||||||
*/
|
|
||||||
@Aspect
|
|
||||||
public class TaskHandler {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ApplicationContext context;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskRepository repository;
|
|
||||||
|
|
||||||
private String taskName;
|
|
||||||
|
|
||||||
private String executionId;
|
|
||||||
|
|
||||||
private TaskExecution taskExecution;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks for any {@link CommandLineRunner}.run method with its class annotated with @Task
|
|
||||||
* and calls the repository implementation to store the start of the task in the repo
|
|
||||||
* before the run starts.
|
|
||||||
*
|
|
||||||
* @param joinPoint the point where the run method in a {@link CommandLineRunner} or
|
|
||||||
* {@link ApplicationRunner} is executed
|
|
||||||
*/
|
|
||||||
@Before("within( @org.springframework.cloud.task.annotation.Task *) && (execution(* org.springframework.boot.CommandLineRunner.run(..)) || execution(* org.springframework.boot.ApplicationRunner.run(..)))")
|
|
||||||
public void beforeCommandLineRunner(JoinPoint joinPoint) {
|
|
||||||
executionId = UUID.randomUUID().toString();
|
|
||||||
taskExecution = new TaskExecution();
|
|
||||||
|
|
||||||
Task a = joinPoint.getTarget().getClass().getAnnotation(Task.class);
|
|
||||||
taskName = a.value();
|
|
||||||
if (taskName == null || taskName.length() == 0) {
|
|
||||||
taskName = joinPoint.getTarget().getClass().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
taskExecution.setTaskName(taskName);
|
|
||||||
taskExecution.setStartTime(new Date());
|
|
||||||
taskExecution.setExecutionId(executionId);
|
|
||||||
repository.createTaskExecution(taskExecution);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks for any {@link CommandLineRunner}.run method with its class annotated with @Task
|
|
||||||
* and calls repository implementation to store the exit of the task in the repo after
|
|
||||||
* run returns result.
|
|
||||||
*
|
|
||||||
* @param joinPoint the point where the run method in a {@link CommandLineRunner} or
|
|
||||||
* {@link ApplicationRunner} is executed
|
|
||||||
*/
|
|
||||||
@AfterReturning("within( @org.springframework.cloud.task.annotation.Task *) && (execution(* org.springframework.boot.CommandLineRunner.run(..)) || execution(* org.springframework.boot.ApplicationRunner.run(..)))")
|
|
||||||
public void afterReturnCommandLineRunner(JoinPoint joinPoint) {
|
|
||||||
int result = 0;
|
|
||||||
List<ExitCodeGenerator> generators = new ArrayList<ExitCodeGenerator>();
|
|
||||||
generators
|
|
||||||
.addAll(context.getBeansOfType(ExitCodeGenerator.class).values());
|
|
||||||
for (ExitCodeGenerator generator : generators) {
|
|
||||||
result = generator.getExitCode();
|
|
||||||
}
|
|
||||||
taskExecution.setEndTime(new Date());
|
|
||||||
taskExecution.setExitCode(result);
|
|
||||||
repository.update(taskExecution);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks for any {@link CommandLineRunner}.run method with its class annotated with @Task
|
|
||||||
* and calls the repository implementation to store the exitCode of 1
|
|
||||||
* for the task in the repo in the case of an exception.
|
|
||||||
*
|
|
||||||
* @param joinPoint the point where the run method in a {@link CommandLineRunner} or
|
|
||||||
* {@link ApplicationRunner} is executed
|
|
||||||
*/
|
|
||||||
@AfterThrowing("within( @org.springframework.cloud.task.annotation.Task *) && (execution(* org.springframework.boot.CommandLineRunner.run(..)) || execution(* org.springframework.boot.ApplicationRunner.run(..)))")
|
|
||||||
public void logExceptionCommandLineRunner(JoinPoint joinPoint) {
|
|
||||||
taskExecution.setEndTime(new Date());
|
|
||||||
taskExecution.setExitCode(1);
|
|
||||||
repository.update(taskExecution);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskExecution getTaskExecution() {
|
|
||||||
return taskExecution;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||||
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.event.ContextClosedEvent;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitors the lifecycle of a task. This listener will record both the start and end of
|
||||||
|
* a task in the registered {@link TaskRepository}.
|
||||||
|
*
|
||||||
|
* The following events are used to identify the start and end of a task:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link ContextRefreshedEvent} - Used to identify the start of a task. A task
|
||||||
|
* is expected to contain a single application context.</li>
|
||||||
|
* <li>{@link ContextClosedEvent} - Used to identify the successful end of a task.</li>
|
||||||
|
* <li>{@link ApplicationFailedEvent} - Used to identify the failure of a task.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <b>NOTE:</b> Multiple contexts (including parent/child relationships) will result in
|
||||||
|
* only the first context refresh that contains this instance being recorded.
|
||||||
|
*
|
||||||
|
* @author Michael Minella
|
||||||
|
*/
|
||||||
|
public class TaskLifecycleListener implements ApplicationListener<ApplicationEvent>,
|
||||||
|
ApplicationContextAware {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(TaskLifecycleListener.class);
|
||||||
|
|
||||||
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
private TaskExecution taskExecution;
|
||||||
|
|
||||||
|
private boolean started = false;
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param taskRepository The repository to record executions in.
|
||||||
|
*/
|
||||||
|
public TaskLifecycleListener(TaskRepository taskRepository) {
|
||||||
|
this.taskRepository = taskRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilizes {@link ApplicationEvent}s to determine the start, end, and failure of a
|
||||||
|
* task. Specifically:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link ContextRefreshedEvent} - Start of a task</li>
|
||||||
|
* <li>{@link ContextClosedEvent} - Successful end of a task</li>
|
||||||
|
* <li>{@link ApplicationFailedEvent} - Failure of a task</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param applicationEvent The application being listened for.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
||||||
|
if(applicationEvent instanceof ContextRefreshedEvent) {
|
||||||
|
doTaskStart();
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
else if(applicationEvent instanceof ContextClosedEvent) {
|
||||||
|
doTaskEnd();
|
||||||
|
}
|
||||||
|
else if(applicationEvent instanceof ApplicationFailedEvent) {
|
||||||
|
doTaskFailed(((ApplicationFailedEvent) applicationEvent).getException());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTaskFailed(Throwable exception) {
|
||||||
|
|
||||||
|
if(started) {
|
||||||
|
this.taskExecution.setEndTime(new Date());
|
||||||
|
//TODO: get exit code from new event thrown by Boot.
|
||||||
|
this.taskExecution.setExitCode(1);
|
||||||
|
this.taskExecution.setExitMessage(stackTraceToString(exception));
|
||||||
|
|
||||||
|
taskRepository.update(taskExecution);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.error("An event to fail a task has been received for a task that has " +
|
||||||
|
"not yet started.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stackTraceToString(Throwable exception) {
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
PrintWriter printWriter = new PrintWriter(writer);
|
||||||
|
|
||||||
|
exception.printStackTrace(printWriter);
|
||||||
|
|
||||||
|
return writer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTaskEnd() {
|
||||||
|
if(started) {
|
||||||
|
this.taskExecution.setEndTime(new Date());
|
||||||
|
//TODO: get exit code from new event thrown by Boot.
|
||||||
|
this.taskExecution.setExitCode(0);
|
||||||
|
|
||||||
|
taskRepository.update(taskExecution);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.error("An event to end a task has been received for a task that has " +
|
||||||
|
"not yet started.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTaskStart() {
|
||||||
|
|
||||||
|
if(!started) {
|
||||||
|
|
||||||
|
String executionId = UUID.randomUUID().toString();
|
||||||
|
this.taskExecution = new TaskExecution();
|
||||||
|
|
||||||
|
this.taskExecution.setTaskName(applicationContext.getId());
|
||||||
|
this.taskExecution.setStartTime(new Date());
|
||||||
|
this.taskExecution.setExecutionId(executionId);
|
||||||
|
this.taskRepository.createTaskExecution(this.taskExecution);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.error("Multiple start events have been received. The first one was " +
|
||||||
|
"recorded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for testing purposes
|
||||||
|
* @return the current {@link TaskExecution}
|
||||||
|
*/
|
||||||
|
TaskExecution getTaskExecution() {
|
||||||
|
return this.taskExecution;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext)
|
||||||
|
throws BeansException {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 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 static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import ch.qos.logback.core.Appender;
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
|
||||||
import org.springframework.cloud.task.configuration.TaskHandler;
|
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
|
||||||
import org.springframework.cloud.task.util.TestDefaultConfiguration;
|
|
||||||
import org.springframework.cloud.task.util.TestVerifierUtils;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies that the TaskHandler Methods record the appropriate log header entries and
|
|
||||||
* result codes.
|
|
||||||
*
|
|
||||||
* @author Glenn Renfro
|
|
||||||
*/
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
|
||||||
@ContextConfiguration(classes = {TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
|
|
||||||
public class TaskHandlerDefaultTests {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskHandler taskHandler;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private JoinPoint joinPoint;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTaskException() {
|
|
||||||
taskHandler.beforeCommandLineRunner(joinPoint);
|
|
||||||
final Appender mockAppender = TestVerifierUtils.getMockAppender();
|
|
||||||
taskHandler.logExceptionCommandLineRunner(joinPoint);
|
|
||||||
TestVerifierUtils.verifyLogEntryExists(mockAppender,
|
|
||||||
"Updating: TaskExecution{executionId='" +
|
|
||||||
taskHandler.getTaskExecution().getExecutionId());
|
|
||||||
TaskExecution taskExecution = taskHandler.getTaskExecution();
|
|
||||||
assertEquals("exit code for exception should be 1", taskExecution.getExitCode(),
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTaskCreate() {
|
|
||||||
final Appender mockAppender = TestVerifierUtils.getMockAppender();
|
|
||||||
taskHandler.beforeCommandLineRunner(joinPoint);
|
|
||||||
TestVerifierUtils.verifyLogEntryExists(mockAppender,
|
|
||||||
"Creating: TaskExecution{executionId='" +
|
|
||||||
taskHandler.getTaskExecution().getExecutionId());
|
|
||||||
assertEquals("Create should report that exit code is zero",
|
|
||||||
0, taskHandler.getTaskExecution().getExitCode());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTaskUpdate() {
|
|
||||||
taskHandler.beforeCommandLineRunner(joinPoint);
|
|
||||||
final Appender mockAppender = TestVerifierUtils.getMockAppender();
|
|
||||||
taskHandler.afterReturnCommandLineRunner(joinPoint);
|
|
||||||
TestVerifierUtils.verifyLogEntryExists(mockAppender,
|
|
||||||
"Updating: TaskExecution{executionId='" +
|
|
||||||
taskHandler.getTaskExecution().getExecutionId());
|
|
||||||
assertEquals("Update should report that exit code is zero",
|
|
||||||
0, taskHandler.getTaskExecution().getExitCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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 javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||||
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
|
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
||||||
|
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||||
|
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
||||||
|
import org.springframework.cloud.task.repository.support.SimpleTaskExplorer;
|
||||||
|
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
||||||
|
import org.springframework.cloud.task.repository.support.TaskDatabaseInitializer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Michael Minella
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class TestConfiguration {
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private ResourceLoader resourceLoader;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TaskRepository taskRepository(TaskExecutionDao taskExecutionDao){
|
||||||
|
return new SimpleTaskRepository(taskExecutionDao);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PlatformTransactionManager transactionManager() {
|
||||||
|
if(dataSource == null) {
|
||||||
|
return new ResourcelessTransactionManager();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TaskDatabaseInitializer.initializeDatabase(dataSource, this.resourceLoader);
|
||||||
|
|
||||||
|
return new DataSourceTransactionManager(dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TaskExplorer taskExplorer(TaskExecutionDao taskExecutionDao) {
|
||||||
|
return new SimpleTaskExplorer(taskExecutionDao);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TaskExecutionDao taskExecutionDao() {
|
||||||
|
if(dataSource != null) {
|
||||||
|
return new JdbcTaskExecutionDao(dataSource);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new MapTaskExecutionDao();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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 static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import ch.qos.logback.core.Appender;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
|
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||||
|
import org.springframework.cloud.task.util.TestDefaultConfiguration;
|
||||||
|
import org.springframework.cloud.task.util.TestVerifierUtils;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.event.ContextClosedEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that the TaskLifecycleListener Methods record the appropriate log header entries and
|
||||||
|
* result codes.
|
||||||
|
*
|
||||||
|
* @author Glenn Renfro
|
||||||
|
* @author Michael Minella
|
||||||
|
*/
|
||||||
|
public class TaskLifecycleListenerTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TaskLifecycleListener listener;
|
||||||
|
|
||||||
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
context = new AnnotationConfigApplicationContext();
|
||||||
|
context.register(TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTaskCreate() {
|
||||||
|
final Appender mockAppender = TestVerifierUtils.getMockAppender();
|
||||||
|
context.refresh();
|
||||||
|
this.listener = context.getBean(TaskLifecycleListener.class);
|
||||||
|
TestVerifierUtils.verifyLogEntryExists(mockAppender,
|
||||||
|
"Creating: TaskExecution{executionId='" +
|
||||||
|
listener.getTaskExecution().getExecutionId());
|
||||||
|
assertEquals("Create should report that exit code is zero",
|
||||||
|
0, listener.getTaskExecution().getExitCode());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTaskUpdate() {
|
||||||
|
context.refresh();
|
||||||
|
final Appender mockAppender = TestVerifierUtils.getMockAppender();
|
||||||
|
this.listener = context.getBean(TaskLifecycleListener.class);
|
||||||
|
this.listener.onApplicationEvent(new ContextClosedEvent(context));
|
||||||
|
TestVerifierUtils.verifyLogEntryExists(mockAppender,
|
||||||
|
"Updating: TaskExecution{executionId='" +
|
||||||
|
listener.getTaskExecution().getExecutionId());
|
||||||
|
assertEquals("Update should report that exit code is zero",
|
||||||
|
0, listener.getTaskExecution().getExitCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTaskFailedUpdate() {
|
||||||
|
context.refresh();
|
||||||
|
final Appender mockAppender = TestVerifierUtils.getMockAppender();
|
||||||
|
this.listener = context.getBean(TaskLifecycleListener.class);
|
||||||
|
listener.onApplicationEvent(new ApplicationFailedEvent(new SpringApplication(), new String[]{}, context, new RuntimeException("This was expected")));
|
||||||
|
TestVerifierUtils.verifyLogEntryExists(mockAppender,
|
||||||
|
"Updating: TaskExecution{executionId='" +
|
||||||
|
listener.getTaskExecution().getExecutionId());
|
||||||
|
assertEquals("Update should report that exit code is one",
|
||||||
|
1, listener.getTaskExecution().getExitCode());
|
||||||
|
assertTrue("Stack trace missing from exit message", listener.getTaskExecution().getExitMessage().startsWith("java.lang.RuntimeException: This was expected"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,47 +18,37 @@ package org.springframework.cloud.task.repository.dao;
|
|||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.cloud.task.annotation.EnableTask;
|
import org.springframework.cloud.task.configuration.TestConfiguration;
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
import org.springframework.cloud.task.util.TestDBUtils;
|
import org.springframework.cloud.task.util.TestDBUtils;
|
||||||
import org.springframework.cloud.task.util.TestVerifierUtils;
|
import org.springframework.cloud.task.util.TestVerifierUtils;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes unit tests on JdbcTaskExecutionDao.
|
* Executes unit tests on JdbcTaskExecutionDao.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = {TestConfiguration.class,
|
||||||
|
EmbeddedDataSourceConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class})
|
||||||
public class JdbcTaskExecutionDaoTests {
|
public class JdbcTaskExecutionDaoTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
private AnnotationConfigApplicationContext context;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
|
||||||
this.context.register(TestConfiguration.class,
|
|
||||||
EmbeddedDataSourceConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
dataSource = this.context.getBean(DataSource.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void close() {
|
|
||||||
if (this.context != null) {
|
|
||||||
this.context.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@DirtiesContext
|
||||||
public void saveTaskExecution() {
|
public void saveTaskExecution() {
|
||||||
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
||||||
@@ -69,6 +59,7 @@ public class JdbcTaskExecutionDaoTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DuplicateKeyException.class)
|
@Test(expected = DuplicateKeyException.class)
|
||||||
|
@DirtiesContext
|
||||||
public void duplicateSaveTaskExecution() {
|
public void duplicateSaveTaskExecution() {
|
||||||
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
||||||
@@ -77,6 +68,7 @@ public class JdbcTaskExecutionDaoTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@DirtiesContext
|
||||||
public void updateTaskExecution() {
|
public void updateTaskExecution() {
|
||||||
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
||||||
|
|
||||||
@@ -88,14 +80,11 @@ public class JdbcTaskExecutionDaoTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test(expected = IllegalStateException.class)
|
||||||
|
@DirtiesContext
|
||||||
public void updateTaskExecutionWithNoCreate() {
|
public void updateTaskExecutionWithNoCreate() {
|
||||||
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
||||||
|
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoParam();
|
||||||
dao.updateTaskExecution(expectedTaskExecution);
|
dao.updateTaskExecution(expectedTaskExecution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
|
||||||
protected static class TestConfiguration {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,16 +40,18 @@ import org.junit.Test;
|
|||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.cloud.task.annotation.EnableTask;
|
import org.springframework.cloud.task.configuration.TestConfiguration;
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||||
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
|
|
||||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
|
||||||
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
||||||
import org.springframework.cloud.task.util.TestVerifierUtils;
|
import org.springframework.cloud.task.util.TestVerifierUtils;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
@@ -59,12 +61,18 @@ public class SimpleTaskExplorerTests {
|
|||||||
|
|
||||||
private AnnotationConfigApplicationContext context;
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private TaskExecutionDao dao;
|
private TaskExecutionDao dao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private TaskExplorer taskExplorer;
|
private TaskExplorer taskExplorer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResourceLoader resourceLoader;
|
||||||
|
|
||||||
private DaoType testType;
|
private DaoType testType;
|
||||||
|
|
||||||
@Parameterized.Parameters
|
@Parameterized.Parameters
|
||||||
@@ -84,9 +92,11 @@ public class SimpleTaskExplorerTests {
|
|||||||
|
|
||||||
if(testType == DaoType.jdbc){
|
if(testType == DaoType.jdbc){
|
||||||
initializeJdbcExplorerTest();
|
initializeJdbcExplorerTest();
|
||||||
}else{
|
}
|
||||||
|
else{
|
||||||
initializeMapExplorerTest();
|
initializeMapExplorerTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
taskExplorer = new SimpleTaskExplorer(dao);
|
taskExplorer = new SimpleTaskExplorer(dao);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,23 +252,27 @@ public class SimpleTaskExplorerTests {
|
|||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
|
||||||
protected static class TestConfiguration {
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeJdbcExplorerTest(){
|
private void initializeJdbcExplorerTest(){
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(TestConfiguration.class,
|
this.context.register(TestConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class,
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
dataSource = this.context.getBean(DataSource.class);
|
|
||||||
dao = new JdbcTaskExecutionDao(dataSource);
|
context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
|
||||||
|
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeMapExplorerTest(){
|
private void initializeMapExplorerTest() {
|
||||||
dao = new MapTaskExecutionDao();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
|
this.context.register(TestConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
|
||||||
|
context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
|
||||||
|
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private enum DaoType{jdbc, map}
|
private enum DaoType{jdbc, map}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ import javax.sql.DataSource;
|
|||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.cloud.task.annotation.EnableTask;
|
import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
import org.springframework.cloud.task.util.TaskExecutionCreator;
|
import org.springframework.cloud.task.util.TaskExecutionCreator;
|
||||||
@@ -47,7 +48,7 @@ public class SimpleTaskRepositoryJdbcTests {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register(TestConfiguration.class,
|
this.context.register(SimpleTaskConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class,
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
@@ -92,10 +93,5 @@ public class SimpleTaskRepositoryJdbcTests {
|
|||||||
dataSource, expectedTaskExecution.getExecutionId());
|
dataSource, expectedTaskExecution.getExecutionId());
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
|
||||||
protected static class TestConfiguration {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ import org.junit.After;
|
|||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.cloud.task.annotation.EnableTask;
|
import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
|
||||||
import org.springframework.cloud.task.configuration.TaskConfigurer;
|
import org.springframework.cloud.task.configuration.TestConfiguration;
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
|
||||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -88,7 +88,7 @@ public class TaskDatabaseInitializerTests {
|
|||||||
@Test(expected = BeanCreationException.class)
|
@Test(expected = BeanCreationException.class)
|
||||||
public void testMultipleDataSourcesContext() throws Exception {
|
public void testMultipleDataSourcesContext() throws Exception {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
this.context.register( TestConfiguration.class,
|
this.context.register( SimpleTaskConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class,
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
DataSource dataSource = mock(DataSource.class);
|
DataSource dataSource = mock(DataSource.class);
|
||||||
@@ -96,19 +96,6 @@ public class TaskDatabaseInitializerTests {
|
|||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
|
||||||
protected static class TestConfiguration {
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableTask
|
|
||||||
protected static class TestCustomConfiguration implements TaskConfigurer {
|
|
||||||
@Override
|
|
||||||
public TaskRepository getTaskRepository() {
|
|
||||||
return new SimpleTaskRepository(new MapTaskExecutionDao());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
protected static class EmptyConfiguration {
|
public static class EmptyConfiguration {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 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.util;
|
|
||||||
|
|
||||||
import org.springframework.boot.CommandLineRunner;
|
|
||||||
import org.springframework.cloud.task.annotation.Task;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic {@link CommandLineRunner} implementation, with task annotation.
|
|
||||||
* @author Glenn Renfro
|
|
||||||
*/
|
|
||||||
@Task
|
|
||||||
@Component
|
|
||||||
public class TaskBasic implements CommandLineRunner{
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(String... args) {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.task.util;
|
package org.springframework.cloud.task.util;
|
||||||
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.springframework.cloud.task.listener.TaskLifecycleListener;
|
||||||
import org.springframework.cloud.task.configuration.TaskHandler;
|
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
import org.springframework.cloud.task.repository.TaskRepository;
|
||||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||||
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
||||||
@@ -38,14 +37,7 @@ public class TestDefaultConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskHandler taskHandler(){
|
public TaskLifecycleListener taskHandler(){
|
||||||
return new TaskHandler();
|
return new TaskLifecycleListener(taskRepository());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public JoinPoint joinPoint(){
|
|
||||||
return new TestJoinPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 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.util;
|
|
||||||
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.Signature;
|
|
||||||
import org.aspectj.lang.reflect.SourceLocation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stubbed out join point for testing purposes.
|
|
||||||
*
|
|
||||||
* @author Glenn Renfro
|
|
||||||
*/
|
|
||||||
public class TestJoinPoint implements JoinPoint {
|
|
||||||
public String toShortString() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toLongString() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getThis() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getTarget() {
|
|
||||||
return new TaskBasic();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object[] getArgs() {
|
|
||||||
return new Object[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Signature getSignature() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceLocation getSourceLocation() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKind() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StaticPart getStaticPart() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,13 +22,13 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.cloud.task.annotation.EnableTask;
|
import org.springframework.cloud.task.configuration.EnableTask;
|
||||||
import org.springframework.cloud.task.annotation.Task;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,9 +49,8 @@ public class TaskApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A commandline runner that prints a timestamp and is annotated with @Task.
|
* A commandline runner that prints a timestamp.
|
||||||
*/
|
*/
|
||||||
@Task("Demo Timestamp Task")
|
|
||||||
public class TimestampTask implements CommandLineRunner {
|
public class TimestampTask implements CommandLineRunner {
|
||||||
private final org.slf4j.Logger logger = LoggerFactory.getLogger(TimestampTask.class);
|
private final org.slf4j.Logger logger = LoggerFactory.getLogger(TimestampTask.class);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
spring.application.name=Demo Timestamp Task
|
||||||
Reference in New Issue
Block a user