SCT-4 Added SimpleTaskConfiguration
* Added unit tests * Introduced @EnableTask * Readme updated to include @EnableTask * Removed warnings from build * Cleanup
This commit is contained in:
committed by
Michael Minella
parent
93e4698175
commit
ce8854b89e
25
README.adoc
25
README.adoc
@@ -20,13 +20,26 @@ $ mvn -s settings.xml clean install
|
||||
|
||||
[source,java,indent=2]
|
||||
----
|
||||
@Task("imSampleB")
|
||||
public class SampleB implements CommandLineRunner {
|
||||
@SpringBootApplication
|
||||
@EnableTask
|
||||
public class MyApp {
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
System.out.println("hello world");
|
||||
}
|
||||
@Bean
|
||||
public MyTask myTask() {
|
||||
return new MyTask();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MyApp.class);
|
||||
}
|
||||
|
||||
@Task("HelloWorldTask")
|
||||
public static class MyTask implements CommandLineRunner {
|
||||
|
||||
@Override
|
||||
public void run(String... strings) throws Exception {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
33
pom.xml
33
pom.xml
@@ -29,4 +29,37 @@
|
||||
<module>spring-cloud-task-samples</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.3</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -25,7 +25,38 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Enable Spring Task features and provide a base configuration for setting up
|
||||
* {@link Task} objects in an @Configuration class.
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableTask
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public MyCommandLineRunner myCommandLineRunner() {
|
||||
* return new MyCommandLineRunner()
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Note that only one of your configuration classes needs to have the <code>@EnableTask</code>
|
||||
* annotation. Once you have an <code>@EnableTask</code> class in your configuration
|
||||
* you will have an instance of {@link TaskConfigurer}. If one is not specified then the
|
||||
* {@link DefaultTaskConfigurer} will be used.
|
||||
* You will also be able to <code>@Autowired</code> some useful stuff into your context:
|
||||
*
|
||||
* <ul>
|
||||
* <li>a {@link TaskRepository} (bean name "taskRepository").</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Import(SimpleTaskConfiguration.class)
|
||||
public @interface EnableTask {
|
||||
}
|
||||
@@ -23,10 +23,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Annotation that identifies a class as a task. This annotation will serve as the
|
||||
* main “hook” to activate the various Spring Cloud Task features.
|
||||
@@ -37,12 +33,11 @@ import org.springframework.stereotype.Component;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Component
|
||||
@Import({ DefaultTaskConfigurer.class })
|
||||
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 "";
|
||||
|
||||
|
||||
@@ -16,28 +16,26 @@
|
||||
|
||||
package org.springframework.cloud.task.configuration;
|
||||
|
||||
import org.springframework.cloud.task.repository.support.LoggerTaskRepository;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.cloud.task.repository.support.LoggerTaskRepository;
|
||||
|
||||
/**
|
||||
* If no TaskConfigurer is present this configuration will be used.
|
||||
* If no {@link TaskConfigurer} is present, then this configuration will be used.
|
||||
* The following defaults will be used:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link LoggerTaskRepository} will be the default {@link TaskRepository}.</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@Configuration
|
||||
public class DefaultTaskConfigurer {
|
||||
public class DefaultTaskConfigurer implements TaskConfigurer{
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
public TaskHandler taskHandler() {
|
||||
return new TaskHandler();
|
||||
public DefaultTaskConfigurer(){
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public TaskRepository taskRepository() {
|
||||
public TaskRepository getTaskRepository() {
|
||||
return new LoggerTaskRepository();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.Collection;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
/**
|
||||
* Base {@code Configuration} class providing common structure for enabling and using
|
||||
* Spring Task. Customization is
|
||||
* available by implementing the {@link TaskConfigurer} interface.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@Configuration
|
||||
public class SimpleTaskConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private TaskRepository taskRepository;
|
||||
|
||||
private TaskConfigurer configurer;
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
public TaskHandler taskHandler() {
|
||||
return new TaskHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskRepository taskRepository(){
|
||||
return taskRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@PostConstruct
|
||||
private void initialize() {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
TaskConfigurer configurer = getConfigurer(context.getBeansOfType(TaskConfigurer.class).values());
|
||||
taskRepository = configurer.getTaskRepository();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private TaskConfigurer getConfigurer(Collection<TaskConfigurer> configurers) {
|
||||
if (this.configurer != null) {
|
||||
return this.configurer;
|
||||
}
|
||||
if (configurers == null || configurers.isEmpty()) {
|
||||
DefaultTaskConfigurer configurer = new DefaultTaskConfigurer();
|
||||
this.configurer = configurer;
|
||||
return configurer;
|
||||
}
|
||||
if (configurers.size() > 1) {
|
||||
throw new IllegalStateException(
|
||||
"To use a custom TaskConfigurer the context must contain precisely one, found "
|
||||
+ configurers.size());
|
||||
}
|
||||
this.configurer = configurers.iterator().next();
|
||||
return this.configurer;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,6 @@ public interface TaskConfigurer {
|
||||
*
|
||||
* @return A TaskRepository
|
||||
*/
|
||||
public TaskRepository taskRepository();
|
||||
public TaskRepository getTaskRepository();
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ 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;
|
||||
@@ -33,8 +35,9 @@ 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 applicationrunner
|
||||
* and commandlinerunner spring boot applications.
|
||||
* 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
|
||||
*/
|
||||
@@ -54,11 +57,12 @@ public class TaskHandler {
|
||||
private TaskExecution taskExecution;
|
||||
|
||||
/**
|
||||
* Looks for any CommandLineRunner.run method with its class annotated with @Task
|
||||
* 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
|
||||
* @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) {
|
||||
@@ -78,11 +82,12 @@ public class TaskHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for any CommandLineRunner.run method with its class annotated with @Task
|
||||
* 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
|
||||
* @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) {
|
||||
@@ -99,11 +104,12 @@ public class TaskHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for any CommandLineRunner. run method with its class annotated with @Task
|
||||
* 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
|
||||
* @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) {
|
||||
@@ -112,4 +118,7 @@ public class TaskHandler {
|
||||
repository.update(taskExecution);
|
||||
}
|
||||
|
||||
public TaskExecution getTaskExecution() {
|
||||
return taskExecution;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.cloud.task.repository;
|
||||
|
||||
/**
|
||||
* TaskRepository interface offers methods that create and update task execution
|
||||
* information. The interface will support the following methods:
|
||||
* information.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
|
||||
/**
|
||||
* {@link TaskRepository} implementation that will log the task execution information.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class LoggerTaskRepository implements TaskRepository {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 java.util.UUID;
|
||||
|
||||
import ch.qos.logback.core.Appender;
|
||||
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.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.cloud.task.util.LoggerTestUtils;
|
||||
import org.springframework.cloud.task.util.TestDefaultConfiguration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Verifies that the LoggerRepository has correct prefixes written to logs.
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = TestDefaultConfiguration.class)
|
||||
public class LoggerTaskRepositoryTests {
|
||||
|
||||
@Autowired
|
||||
private TaskRepository taskRepository;
|
||||
|
||||
private TaskExecution taskExecution;
|
||||
|
||||
private String uuId;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
taskExecution = new TaskExecution();
|
||||
uuId = UUID.randomUUID().toString();
|
||||
taskExecution.setExecutionId(uuId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTaskExecution() {
|
||||
final Appender mockAppender = LoggerTestUtils.getMockAppender();
|
||||
taskRepository.createTaskExecution(taskExecution);
|
||||
LoggerTestUtils.verifyLogEntryExists(mockAppender,
|
||||
"Creating: TaskExecution{executionId='" + uuId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTaskUpdate() {
|
||||
final Appender mockAppender = LoggerTestUtils.getMockAppender();
|
||||
taskRepository.update(taskExecution);
|
||||
LoggerTestUtils.verifyLogEntryExists(mockAppender,
|
||||
"Updating: TaskExecution{executionId='" + uuId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 junit.framework.TestCase.assertNotNull;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.task.configuration.SimpleTaskConfiguration;
|
||||
import org.springframework.cloud.task.repository.support.LoggerTaskRepository;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Verifies that the beans created by the SimpleTaskConfiguration.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = SimpleTaskConfiguration.class)
|
||||
public class SimpleTaskConfigurationTests {
|
||||
|
||||
@Autowired
|
||||
private TaskRepository taskRepository;
|
||||
|
||||
@Test
|
||||
public void testRepository() {
|
||||
assertNotNull("testRepository should not be null", taskRepository);
|
||||
assertThat(taskRepository, instanceOf(LoggerTaskRepository.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.cloud.task.configuration.TaskHandler;
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.util.LoggerTestUtils;
|
||||
import org.springframework.cloud.task.util.TestDefaultConfiguration;
|
||||
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)
|
||||
public class TaskHandlerDefaultTests {
|
||||
|
||||
@Autowired
|
||||
private TaskHandler taskHandler;
|
||||
|
||||
@Autowired
|
||||
private JoinPoint joinPoint;
|
||||
|
||||
@Test
|
||||
public void testTaskException() {
|
||||
taskHandler.beforeCommandLineRunner(joinPoint);
|
||||
final Appender mockAppender = LoggerTestUtils.getMockAppender();
|
||||
taskHandler.logExceptionCommandLineRunner(joinPoint);
|
||||
LoggerTestUtils.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 = LoggerTestUtils.getMockAppender();
|
||||
taskHandler.beforeCommandLineRunner(joinPoint);
|
||||
LoggerTestUtils.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 = LoggerTestUtils.getMockAppender();
|
||||
taskHandler.afterReturnCommandLineRunner(joinPoint);
|
||||
LoggerTestUtils.verifyLogEntryExists(mockAppender,
|
||||
"Updating: TaskExecution{executionId='" +
|
||||
taskHandler.getTaskExecution().getExecutionId());
|
||||
assertEquals("Update should report that exit code is zero",
|
||||
0, taskHandler.getTaskExecution().getExitCode());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
|
||||
public class NoOpTaskExplorerTest {
|
||||
public class NoOpTaskExplorerTests {
|
||||
|
||||
private TaskExplorer taskExplorer;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Offers utils to test the log results produced by the code being tested.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class LoggerTestUtils {
|
||||
|
||||
/**
|
||||
* Creates a mock {@link Appender} to be added to the root logger.
|
||||
* @return reference to the mock appender.
|
||||
*/
|
||||
public static Appender getMockAppender(){
|
||||
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
|
||||
final Appender mockAppender = mock(Appender.class);
|
||||
when(mockAppender.getName()).thenReturn("MOCK");
|
||||
root.addAppender(mockAppender);
|
||||
return mockAppender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the log sample is contained within the content that was written
|
||||
* to the mock appender.
|
||||
* @param mockAppender The appender that is associated with the test.
|
||||
* @param logSample The string to search for in the log entry.
|
||||
*/
|
||||
public static void verifyLogEntryExists(Appender mockAppender, final String logSample){
|
||||
verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
|
||||
@Override
|
||||
public boolean matches(final Object argument) {
|
||||
return ((LoggingEvent)argument).getFormattedMessage().contains(logSample);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.springframework.cloud.task.configuration.TaskHandler;
|
||||
import org.springframework.cloud.task.repository.support.LoggerTaskRepository;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Initializes the beans needed to test default task behavior.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@Configuration
|
||||
public class TestDefaultConfiguration {
|
||||
|
||||
@Bean
|
||||
public TaskRepository taskRepository(){
|
||||
return new LoggerTaskRepository();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskHandler taskHandler(){
|
||||
return new TaskHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JoinPoint joinPoint(){
|
||||
return new TestJoinPoint();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user