Add Application Name to TaskLaunchRequest for launched task

resolves #238
This commit is contained in:
Glenn Renfro
2016-11-02 09:26:00 -04:00
committed by Michael Minella
parent cc1f971f3e
commit 4a1a2c3c88
11 changed files with 139 additions and 51 deletions

View File

@@ -13,8 +13,18 @@ covers the integration options for Spring Cloud Task and Spring Cloud Stream.
Allows a user to launch tasks from a stream. This is done by creating a sink that
listens for a message that contains a `TaskLaunchRequest` as its payload. The
TaskLaunchRequest contains the maven coordinates to the Task that is to be executed. It
also has a Map that contains the environment variables that will be used by the Task.
TaskLaunchRequest contains:
* uri - to the task artifact that is to be executed.
* applicationName - the name that will be associated with the task. If no
applicationName is set the TaskLaunchRequest will generate a task name
comprised of the following: `Task-<UUID>`
* commandLineArguments - a list containing the command line arguments for the
task.
* environmentProperties - a map containing the environment variables to be used
by the task
* deploymentProperties - a map containing the properties that will be used by
the deployer to deploy the task.
NOTE: If the payload is of a different type then the sink will throw an exception.

View File

@@ -62,7 +62,7 @@ import static org.junit.Assert.assertTrue;
public class TaskLauncherSinkTests {
private final static int WAIT_INTERVAL = 500;
private final static int MAX_WAIT_TIME = 5000;
private final static int MAX_WAIT_TIME = 10000;
private final static String URL = "maven://io.spring.cloud:"
+ "timestamp-task:jar:1.1.0.M2";
private final static String DATASOURCE_URL;
@@ -169,7 +169,8 @@ public class TaskLauncherSinkTests {
}
private void launchTask(String artifactURL) {
TaskLaunchRequest request = new TaskLaunchRequest(artifactURL, null, this.properties, null);
TaskLaunchRequest request = new TaskLaunchRequest(artifactURL, null,
this.properties, null, null);
GenericMessage<TaskLaunchRequest> message = new GenericMessage<>(request);
this.sink.input().send(message);
}

View File

@@ -58,7 +58,9 @@ public class TaskProcessor {
}
properties.put("payload", message);
TaskLaunchRequest request = new TaskLaunchRequest(processorProperties.getUri(), null, properties, null);
TaskLaunchRequest request = new TaskLaunchRequest(
processorProperties.getUri(), null, properties, null,
processorProperties.getApplicationName());
return new GenericMessage<TaskLaunchRequest>(request);
}

View File

@@ -38,6 +38,8 @@ public class TaskProcessorProperties {
private String dataSourcePassword;
private String applicationName;
public String getDataSourceUrl() {
@@ -79,4 +81,12 @@ public class TaskProcessorProperties {
public void setUri(String uri) {
this.uri = uri;
}
public String getApplicationName() {
return applicationName;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
}

View File

@@ -58,8 +58,10 @@ public class TaskProcessorApplicationTests {
channels.input().send(new GenericMessage<Object>(DEFAULT_PAYLOAD));
Map<String, String> properties = new HashMap();
properties.put("payload", DEFAULT_PAYLOAD);
TaskLaunchRequest expectedRequest = new TaskLaunchRequest("maven://org.springframework.cloud.task.app:"
+ "timestamp-task:jar:1.0.1.RELEASE", null, properties, null);
TaskLaunchRequest expectedRequest = new TaskLaunchRequest(
"maven://org.springframework.cloud.task.app:"
+ "timestamp-task:jar:1.0.1.RELEASE", null, properties,
null, null);
assertThat(collector.forChannel(channels.output()), receivesPayloadThat(is(expectedRequest)));
}

View File

@@ -62,8 +62,10 @@ public class TaskSinkApplicationTests {
Map<String, String> properties = new HashMap();
properties.put("server.port", "0");
TaskLaunchRequest request = new TaskLaunchRequest("maven://org.springframework.cloud.task.app:"
+ "timestamp-task:jar:1.0.1.RELEASE", null, properties, null);
TaskLaunchRequest request = new TaskLaunchRequest(
"maven://org.springframework.cloud.task.app:"
+ "timestamp-task:jar:1.0.1.RELEASE", null, properties,
null, null);
GenericMessage<TaskLaunchRequest> message = new GenericMessage<TaskLaunchRequest>(request);
this.sink.input().send(message);
assertEquals(LaunchState.complete, testTaskLauncher.status("TESTSTATUS").getState());

View File

@@ -23,8 +23,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Request that contains the maven repository and property information required by the
@@ -39,6 +41,7 @@ public class TaskLaunchRequest implements Serializable{
private List<String> commandlineArguments;
private Map<String, String> environmentProperties;
private Map<String, String> deploymentProperties;
private String applicationName;
/**
* Constructor for the TaskLaunchRequest;
@@ -46,16 +49,21 @@ public class TaskLaunchRequest implements Serializable{
* @param commandlineArguments list of commandlineArguments to be used by the task
* @param environmentProperties are the environment variables for this task.
* @param deploymentProperties are the variables used to setup task on the platform.
* @param applicationName name to be applied to the launched task. If set
* to null then the launched task name will be "Task-<hash code of the
* TaskLaunchRequest>.
*/
public TaskLaunchRequest(String uri, List<String> commandlineArguments,
Map<String, String> environmentProperties,
Map<String, String> deploymentProperties) {
Map<String, String> environmentProperties,
Map<String, String> deploymentProperties,
String applicationName) {
Assert.hasText(uri, "uri must not be empty nor null.");
this.uri = uri;
this.commandlineArguments = (commandlineArguments == null) ? new ArrayList<String>() : commandlineArguments;
this.environmentProperties = environmentProperties == null ? new HashMap<String, String>() : environmentProperties;
this.deploymentProperties = deploymentProperties == null ? new HashMap<String, String>() : deploymentProperties;
setApplicationName(applicationName);
}
/**
@@ -90,6 +98,26 @@ public class TaskLaunchRequest implements Serializable{
return deploymentProperties;
}
/**
* Returns the name that will be associated with the launched task.
*
* @return string containing the application name.
*/
public String getApplicationName() {
return applicationName;
}
/**
* Sets the name to be applied to the launched task. If set
* to null then the launched task name will be "Task-<unique id>".
*
* @param applicationName the name to be
*/
public void setApplicationName(String applicationName) {
this.applicationName = !StringUtils.hasText(applicationName) ? "Task-" +
UUID.randomUUID().toString() : applicationName;
}
@Override
public String toString() {
return "TaskLaunchRequest{" +

View File

@@ -62,7 +62,7 @@ public class TaskLauncherSink {
Assert.notNull(this.taskLauncher, "TaskLauncher has not been initialized");
logger.info("Launching Task for the following resource " + taskLaunchRequest);
Resource resource = this.resourceLoader.getResource(taskLaunchRequest.getUri());
AppDefinition definition = new AppDefinition("Task-" + taskLaunchRequest.hashCode(), taskLaunchRequest.getEnvironmentProperties());
AppDefinition definition = new AppDefinition(taskLaunchRequest.getApplicationName(), taskLaunchRequest.getEnvironmentProperties());
AppDeploymentRequest request = new AppDeploymentRequest(definition, resource, taskLaunchRequest.getDeploymentProperties(), taskLaunchRequest.getCommandlineArguments());
this.taskLauncher.launch(request);
}

View File

@@ -34,6 +34,8 @@ import static org.junit.Assert.assertTrue;
public class TaskLaunchRequestTests {
public static final String URI = "http://myURI";
public static final String APP_NAME = "MY_APP_NAME";
@Test
public void testEquals() {
List<String> args = new ArrayList<>();
@@ -42,46 +44,50 @@ public class TaskLaunchRequestTests {
map.put("bar", "baz");
TaskLaunchRequest request = new TaskLaunchRequest(URI,
Collections.EMPTY_LIST,
Collections.EMPTY_MAP,
Collections.EMPTY_MAP);
Collections.EMPTY_LIST, Collections.EMPTY_MAP,
Collections.EMPTY_MAP, null);
TaskLaunchRequest request2 = new TaskLaunchRequest(URI,
Collections.EMPTY_LIST,
Collections.EMPTY_MAP,
Collections.EMPTY_MAP);
Collections.EMPTY_LIST, Collections.EMPTY_MAP,
Collections.EMPTY_MAP, null);
assertFalse(request.equals(null));
assertFalse(request.equals("nope"));
assertTrue(request.equals(request));
assertTrue(request.equals(request2));
TaskLaunchRequest requestDiff = new TaskLaunchRequest("http://oops",
Collections.EMPTY_LIST,
Collections.EMPTY_MAP,
Collections.EMPTY_MAP);
Collections.EMPTY_LIST, Collections.EMPTY_MAP,
Collections.EMPTY_MAP, null);
assertFalse(request.equals(requestDiff));
requestDiff = new TaskLaunchRequest(URI, args, Collections.EMPTY_MAP,
Collections.EMPTY_MAP, null);
assertFalse(request.equals(requestDiff));
requestDiff = new TaskLaunchRequest(URI,
args,
Collections.EMPTY_MAP,
Collections.EMPTY_MAP);
assertFalse(request.equals(requestDiff));
requestDiff = new TaskLaunchRequest(URI,
null, null, null);
null, null, null, null);
assertTrue(request.equals(requestDiff));
requestDiff = new TaskLaunchRequest(URI,
Collections.EMPTY_LIST,
map,
Collections.EMPTY_MAP);
requestDiff = new TaskLaunchRequest(URI, Collections.EMPTY_LIST, map,
Collections.EMPTY_MAP, null);
assertFalse(request.equals(requestDiff));
requestDiff = new TaskLaunchRequest(URI,
Collections.EMPTY_LIST,
Collections.EMPTY_MAP,
map);
requestDiff = new TaskLaunchRequest(URI, Collections.EMPTY_LIST,
Collections.EMPTY_MAP, map, null);
assertFalse(request.equals(requestDiff));
assertEquals(request.hashCode(), request.hashCode());
}
@Test
public void testApplicationName() {
TaskLaunchRequest request = new TaskLaunchRequest(URI,
Collections.EMPTY_LIST, Collections.EMPTY_MAP,
Collections.EMPTY_MAP, null);
assertTrue(request.getApplicationName().startsWith("Task-"));
request = new TaskLaunchRequest(URI,
Collections.EMPTY_LIST, Collections.EMPTY_MAP,
Collections.EMPTY_MAP, APP_NAME);
assertEquals(APP_NAME, request.getApplicationName());
}
}

View File

@@ -26,23 +26,27 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.deployer.spi.task.LaunchState;
import org.springframework.cloud.stream.annotation.Bindings;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.cloud.task.launcher.configuration.TaskConfiguration;
import org.springframework.cloud.task.launcher.util.TaskLauncherSinkApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {TaskLauncherSinkApplication.class, TaskConfiguration.class} )
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {TaskLauncherSinkApplication.class, TaskConfiguration.class} )
public class TaskLauncherSinkTests {
private final static String TASK_NAME_PREFIX = "Task-";
private final static String APP_NAME = "MY_APP_NAME";
private final static String PARAM1 = "FOO";
private final static String PARAM2 = "BAR";
@@ -61,7 +65,6 @@ public class TaskLauncherSinkTests {
private ApplicationContext context;
@Autowired
@Bindings(TaskLauncherSink.class)
private Sink sink;
@Before
@@ -72,29 +75,43 @@ public class TaskLauncherSinkTests {
@Test
public void testSuccessWithParams() {
List<String> commandLineArgs = new ArrayList<>();
commandLineArgs.add(PARAM1);
commandLineArgs.add(PARAM2);
TaskConfiguration.TestTaskLauncher testTaskLauncher = launchTask(VALID_URL, commandLineArgs);
TaskConfiguration.TestTaskLauncher testTaskLauncher =
launchTask(VALID_URL, commandLineArgs, null);
assertEquals(LaunchState.complete, testTaskLauncher.status(DEFAULT_STATUS).getState());
assertEquals(2, testTaskLauncher.getCommandlineArguments().size());
assertEquals(testTaskLauncher.getCommandlineArguments().get(0), PARAM1);
assertEquals(testTaskLauncher.getCommandlineArguments().get(1), PARAM2);
assertEquals(PARAM1, testTaskLauncher.getCommandlineArguments().get(0));
assertEquals(PARAM2, testTaskLauncher.getCommandlineArguments().get(1));
assertTrue(testTaskLauncher.getApplicationName().startsWith(TASK_NAME_PREFIX));
}
@Test
public void testSuccessWithAppName() {
TaskConfiguration.TestTaskLauncher testTaskLauncher =
launchTask(VALID_URL, null, APP_NAME);
assertEquals(LaunchState.complete, testTaskLauncher.status(DEFAULT_STATUS).getState());
assertEquals(0, testTaskLauncher.getCommandlineArguments().size());
assertEquals(APP_NAME, testTaskLauncher.getApplicationName());
}
@Test
public void testSuccessNoParams() {
TaskConfiguration.TestTaskLauncher testTaskLauncher = launchTask(VALID_URL, null);
TaskConfiguration.TestTaskLauncher testTaskLauncher =
launchTask(VALID_URL, null, null);
assertEquals(LaunchState.complete, testTaskLauncher.status(DEFAULT_STATUS).getState());
assertEquals(0, testTaskLauncher.getCommandlineArguments().size());
assertTrue(testTaskLauncher.getApplicationName().startsWith(TASK_NAME_PREFIX));
}
@Test(expected = MessageHandlingException.class)
public void testInvalidJar() {
TaskConfiguration.TestTaskLauncher testTaskLauncher = launchTask(INVALID_URL, null);
TaskConfiguration.TestTaskLauncher testTaskLauncher = launchTask(
INVALID_URL, null, null);
}
@Test
@@ -108,14 +125,17 @@ public class TaskLauncherSinkTests {
@Test(expected = IllegalArgumentException.class)
public void testNoTaskLauncher() {
TaskLauncherSink sink = new TaskLauncherSink();
sink.taskLauncherSink(new TaskLaunchRequest(VALID_URL, null, properties, null));
sink.taskLauncherSink(new TaskLaunchRequest(VALID_URL, null, properties,
null, null));
}
private TaskConfiguration.TestTaskLauncher launchTask(String artifactURL, List<String> commandLineArgs) {
private TaskConfiguration.TestTaskLauncher launchTask(String artifactURL,
List<String> commandLineArgs, String applicationName) {
TaskConfiguration.TestTaskLauncher testTaskLauncher =
context.getBean(TaskConfiguration.TestTaskLauncher.class);
TaskLaunchRequest request = new TaskLaunchRequest(artifactURL, commandLineArgs, properties, null);
TaskLaunchRequest request = new TaskLaunchRequest(artifactURL,
commandLineArgs, properties, null, applicationName);
GenericMessage<TaskLaunchRequest> message = new GenericMessage<>(request);
this.sink.input().send(message);
return testTaskLauncher;

View File

@@ -45,10 +45,13 @@ public class TaskConfiguration {
private List<String> commandlineArguments;
private String applicationName;
@Override
public String launch(AppDeploymentRequest request) {
state = LaunchState.complete;
this.commandlineArguments = request.getCommandlineArguments();
this.applicationName = request.getDefinition().getName();
return null;
}
@@ -65,5 +68,9 @@ public class TaskConfiguration {
public List<String> getCommandlineArguments() {
return commandlineArguments;
}
public String getApplicationName() {
return applicationName;
}
}
}