Stores the command line arguements within the task repository
Resolves spring-cloud/spring-cloud-task#62 Code Review Polishing
This commit is contained in:
committed by
Glenn Renfro
parent
1a7cd94721
commit
846eb3fad9
@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.cloud.task.listener.TaskLifecycleListener;
|
||||
import org.springframework.cloud.task.repository.TaskNameResolver;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
@@ -60,6 +61,9 @@ public class SimpleTaskConfiguration {
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ApplicationArguments applicationArguments;
|
||||
|
||||
@Value("${spring.class.initialize.enable:true}")
|
||||
private boolean taskInitializationEnable;
|
||||
|
||||
@@ -78,7 +82,7 @@ public class SimpleTaskConfiguration {
|
||||
|
||||
@Bean
|
||||
public TaskLifecycleListener taskLifecycleListener() {
|
||||
return new TaskLifecycleListener(taskRepository(), taskNameResolver());
|
||||
return new TaskLifecycleListener(taskRepository(), taskNameResolver(), this.applicationArguments);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -18,11 +18,14 @@ package org.springframework.cloud.task.listener;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.repository.TaskNameResolver;
|
||||
@@ -63,16 +66,20 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
|
||||
private TaskNameResolver taskNameResolver;
|
||||
|
||||
private ApplicationArguments applicationArguments;
|
||||
|
||||
/**
|
||||
* @param taskRepository The repository to record executions in.
|
||||
*/
|
||||
public TaskLifecycleListener(TaskRepository taskRepository,
|
||||
TaskNameResolver taskNameResolver) {
|
||||
TaskNameResolver taskNameResolver,
|
||||
ApplicationArguments applicationArguments) {
|
||||
Assert.notNull(taskRepository, "A taskRepository is required");
|
||||
Assert.notNull(taskNameResolver, "A taskNameResolver is required");
|
||||
|
||||
this.taskRepository = taskRepository;
|
||||
this.taskNameResolver = taskNameResolver;
|
||||
this.applicationArguments = applicationArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,9 +149,15 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
private void doTaskStart() {
|
||||
|
||||
if(!started) {
|
||||
List<String> args = new ArrayList<>(0);
|
||||
|
||||
if(this.applicationArguments != null) {
|
||||
args = Arrays.asList(this.applicationArguments.getSourceArgs());
|
||||
}
|
||||
|
||||
this.taskExecution = new TaskExecution(this.taskRepository.getNextExecutionId(),
|
||||
0, this.taskNameResolver.getTaskName(), new Date(), null, null, null,
|
||||
new ArrayList<String>(0), null);
|
||||
args, null);
|
||||
|
||||
this.taskRepository.createTaskExecution(this.taskExecution);
|
||||
}
|
||||
|
||||
@@ -17,21 +17,35 @@
|
||||
package org.springframework.cloud.task.listener;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import ch.qos.logback.core.Appender;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
import org.springframework.cloud.task.util.TestDefaultConfiguration;
|
||||
import org.springframework.cloud.task.util.TestVerifierUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextClosedEvent;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
/**
|
||||
* Verifies that the TaskLifecycleListener Methods record the appropriate log header entries and
|
||||
@@ -42,14 +56,14 @@ import org.springframework.context.event.ContextClosedEvent;
|
||||
*/
|
||||
public class TaskLifecycleListenerTests {
|
||||
|
||||
@Autowired
|
||||
private TaskLifecycleListener listener;
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
private TaskExplorer taskExplorer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
context.setId("testTask");
|
||||
context.register(TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@@ -60,41 +74,131 @@ public class TaskLifecycleListenerTests {
|
||||
|
||||
@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());
|
||||
verifyTaskExecution(0, false, 0, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTaskCreateWithArgs() {
|
||||
context.register(ArgsConfiguration.class);
|
||||
context.refresh();
|
||||
verifyTaskExecution(2, false, 0, null);
|
||||
}
|
||||
|
||||
@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());
|
||||
|
||||
context.publishEvent(new ContextClosedEvent(context));
|
||||
|
||||
verifyTaskExecution(0, true, 0, null);
|
||||
}
|
||||
|
||||
@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"));
|
||||
RuntimeException exception = new RuntimeException("This was expected");
|
||||
context.publishEvent(new ApplicationFailedEvent(new SpringApplication(), new String[0], context, exception));
|
||||
|
||||
verifyTaskExecution(0, true, 1, exception);
|
||||
}
|
||||
|
||||
private static String stackTraceToString(Throwable exception) {
|
||||
StringWriter writer = new StringWriter();
|
||||
PrintWriter printWriter = new PrintWriter(writer);
|
||||
|
||||
exception.printStackTrace(printWriter);
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
private void verifyTaskExecution(int numberOfParams, boolean update, int exitCode, Throwable exception) {
|
||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
||||
|
||||
Sort sort = new Sort("id");
|
||||
|
||||
PageRequest request = new PageRequest(0, Integer.MAX_VALUE, sort);
|
||||
|
||||
Page<TaskExecution> taskExecutionsByName = this.taskExplorer.findTaskExecutionsByName("testTask",
|
||||
request);
|
||||
assertTrue(taskExecutionsByName.iterator().hasNext());
|
||||
TaskExecution taskExecution = taskExecutionsByName.iterator().next();
|
||||
|
||||
assertEquals(numberOfParams, taskExecution.getParameters().size());
|
||||
assertEquals(exitCode, taskExecution.getExitCode());
|
||||
|
||||
if(exception != null) {
|
||||
assertTrue(taskExecution.getExitMessage().length() > exception.getStackTrace().length);
|
||||
}
|
||||
else {
|
||||
assertNull(taskExecution.getExitMessage());
|
||||
}
|
||||
|
||||
if(update) {
|
||||
assertTrue(taskExecution.getEndTime().getTime() >= taskExecution.getStartTime().getTime());
|
||||
}
|
||||
else {
|
||||
assertNull(taskExecution.getEndTime());
|
||||
}
|
||||
|
||||
assertNull(taskExecution.getExternalExecutionID());
|
||||
assertNull(taskExecution.getStatusCode());
|
||||
assertEquals("testTask", taskExecution.getTaskName());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class ArgsConfiguration {
|
||||
|
||||
@Bean
|
||||
public ApplicationArguments args() {
|
||||
Map<String, String> args = new HashMap<>(2);
|
||||
|
||||
args.put("foo", "bar");
|
||||
args.put("baz", "qux");
|
||||
|
||||
return new SimpleApplicationArgs(args);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SimpleApplicationArgs implements ApplicationArguments {
|
||||
|
||||
private Map<String, String> args;
|
||||
|
||||
public SimpleApplicationArgs(Map<String, String> args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSourceArgs() {
|
||||
String [] sourceArgs = new String[this.args.size()];
|
||||
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> stringStringEntry : args.entrySet()) {
|
||||
sourceArgs[i] = "--" + stringStringEntry.getKey() + "=" + stringStringEntry.getValue();
|
||||
i++;
|
||||
}
|
||||
|
||||
return sourceArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getOptionNames() {
|
||||
return this.args.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsOption(String s) {
|
||||
return this.args.containsKey(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getOptionValues(String s) {
|
||||
return Arrays.asList(this.args.get(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonOptionArgs() {
|
||||
throw new UnsupportedOperationException("Not supported at this time.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.springframework.cloud.task.util;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.cloud.task.listener.TaskLifecycleListener;
|
||||
import org.springframework.cloud.task.repository.TaskExplorer;
|
||||
import org.springframework.cloud.task.repository.TaskNameResolver;
|
||||
import org.springframework.cloud.task.repository.TaskRepository;
|
||||
import org.springframework.cloud.task.repository.dao.MapTaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.support.SimpleTaskExplorer;
|
||||
import org.springframework.cloud.task.repository.support.SimpleTaskNameResolver;
|
||||
import org.springframework.cloud.task.repository.support.SimpleTaskRepository;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -33,9 +37,18 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class TestDefaultConfiguration {
|
||||
|
||||
private MapTaskExecutionDao dao;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ApplicationArguments applicationArguments;
|
||||
|
||||
public TestDefaultConfiguration() {
|
||||
this.dao = new MapTaskExecutionDao();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskRepository taskRepository(){
|
||||
return new SimpleTaskRepository(new MapTaskExecutionDao());
|
||||
return new SimpleTaskRepository(this.dao);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -45,6 +58,11 @@ public class TestDefaultConfiguration {
|
||||
|
||||
@Bean
|
||||
public TaskLifecycleListener taskHandler(){
|
||||
return new TaskLifecycleListener(taskRepository(), taskNameResolver());
|
||||
return new TaskLifecycleListener(taskRepository(), taskNameResolver(), applicationArguments);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskExplorer taskExplorer() {
|
||||
return new SimpleTaskExplorer(this.dao);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user