diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/README.adoc b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/README.adoc
deleted file mode 100644
index 3e026aa9..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/README.adoc
+++ /dev/null
@@ -1,52 +0,0 @@
-=== `Data Flow Task Launch Request Support` Common Module
-
-This artifact contains a Spring Boot auto-configuration providing components to produce a Task Launch Request payload.
-In theory any message source can be used to launch a Task. The task launch request is compatible with the
-task-launcher-dataflow sink.
-
-
-==== Data Flow Task Launch Request
-
-Data Flow Task Launch Request requests require a Data Flow server with an existing task definition.
-The task launch request contains the name of the task to launch. This must the name of a defined task in Data Flow.
-You may optionally provide command line arguments and deployment properties.
-
-===== Task Name
-
-The task name is a required field. This may be statically configured by setting `task.launch.request.task-name`,
-extracted from the Message by setting `task.launch.request.task-name-expression`.
-You may also override the default implementation of the `TaskNameMessageMapper` bean to enable more complex runtime task name mappings.
-
-
-===== Task Command Line Arguments
-
-The launched task often requires additional data which may be passed as command line arguments.
-The `task.launch.request.args` property accepts a comma delimited string of key-value pairs, for example
-`key1=val1,key2=val2`. In addition, a `task.launch.request.arg-expressions` allows you to use SpEL expressions to evaluate
-message contents to provide command line arguments.
-For example, `task.launch.request.arg-expressions=foo=payload.toUpperCase(),bar=payload.substring(0,2)`.
-
-You may also provide override implementation of the `CommandLineArgumentsMessageMapper` bean to implement more complex logic.
-
-===== Task Deployment Properties
-
-Deployment properties are platform-specific configuration used by the `TaskLauncher` and are always statically configured by
-setting `task.launch.request.deployment-properties` and apply to every task launch request.
-
-=== Configuration
-To enable any stream app to transform its output to a Task Launch Request, include a dependency on this module
-
-[source,xml]
-----
-
- org.springframework.cloud.stream.app
- app-starters-task-launch-request-common
-
-----
-
-Setting the application property `spring.cloud.stream.function.definition=taskLaunchRequest` is required to execute the transformation.
-You may safely add the above dependency to applications which optionally produce a task launch request.
-
-
-`TaskLaunchRequestIntegrationTests` provides some configuration examples.
-
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/pom.xml b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/pom.xml
deleted file mode 100644
index c3a2db18..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
- stream-applications-core
- org.springframework.cloud.stream.app
- 3.0.0-SNAPSHOT
- ../..
-
- 4.0.0
-
- stream-applications-task-launch-request-common
- stream-applications-task-launch-request-common
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-stream
- test-jar
- test
- test-binder
-
-
- org.springframework.cloud
- spring-cloud-stream
-
-
-
- org.springframework.cloud
- spring-cloud-stream-test-support
- test
-
-
-
-
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequestAutoConfiguration.java b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequestAutoConfiguration.java
deleted file mode 100644
index d3147597..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequestAutoConfiguration.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2018-2020 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
- *
- * https://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.stream.app.tasklaunchrequest;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.CommandLineArgumentsMessageMapper;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskLaunchRequestSupplier;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.Expression;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.integration.expression.ExpressionUtils;
-import org.springframework.messaging.Message;
-import org.springframework.util.StringUtils;
-
-
-/**
- * @author David Turanski
- **/
-@Configuration
-@EnableConfigurationProperties(DataflowTaskLaunchRequestProperties.class)
-public class DataFlowTaskLaunchRequestAutoConfiguration {
-
- /**
- * Task launch request function name.
- */
- public final static String TASK_LAUNCH_REQUEST_FUNCTION_NAME = "taskLaunchRequest";
-
- @Autowired
- private BeanFactory beanFactory;
-
- private EvaluationContext evaluationContext;
-
- /**
- * A {@link java.util.function.Function} to transform a {@link Message} payload to a {@link DataFlowTaskLaunchRequest}.
- *
- * @param taskLaunchRequestMessageProcessor a {@link TaskLaunchRequestMessageProcessor}.
- * @return a {code DataFlowTaskLaunchRequest} Message.
- */
- @Bean(name = TASK_LAUNCH_REQUEST_FUNCTION_NAME)
- @ConditionalOnMissingBean(TaskLaunchRequestFunction.class)
- public TaskLaunchRequestFunction taskLaunchRequest(TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor) {
- return message -> taskLaunchRequestMessageProcessor.postProcessMessage(message);
- }
-
- @Bean
- @ConditionalOnMissingBean(TaskNameMessageMapper.class)
- public TaskNameMessageMapper taskNameMessageMapper(DataflowTaskLaunchRequestProperties taskLaunchRequestProperties) {
- if (StringUtils.hasText(taskLaunchRequestProperties.getTaskNameExpression())) {
- SpelExpressionParser expressionParser = new SpelExpressionParser();
- Expression taskNameExpression = expressionParser.parseExpression(taskLaunchRequestProperties.getTaskNameExpression());
- return new ExpressionEvaluatingTaskNameMessageMapper(taskNameExpression, this.evaluationContext);
- }
-
- return message -> taskLaunchRequestProperties.getTaskName();
- }
-
- @Bean
- @ConditionalOnMissingBean(CommandLineArgumentsMessageMapper.class)
- public CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper(
- DataflowTaskLaunchRequestProperties dataflowTaskLaunchRequestProperties) {
-
- return new ExpressionEvaluatingCommandLineArgsMapper(dataflowTaskLaunchRequestProperties.getArgExpressions(),
- this.evaluationContext);
- }
-
- @Bean
- public TaskLaunchRequestSupplier taskLaunchRequestInitializer(
- DataflowTaskLaunchRequestProperties taskLaunchRequestProperties) {
- return new DataflowTaskLaunchRequestPropertiesInitializer(taskLaunchRequestProperties);
- }
-
- @Bean
- public TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor(
- TaskLaunchRequestSupplier taskLaunchRequestInitializer,
- TaskNameMessageMapper taskNameMessageMapper,
- CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper) {
-
- return new TaskLaunchRequestMessageProcessor(taskLaunchRequestInitializer,
- taskNameMessageMapper,
- commandLineArgumentsMessageMapper);
- }
-
- @PostConstruct
- public void createEvaluationContext() {
- this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
- }
-
- static class DataflowTaskLaunchRequestPropertiesInitializer extends TaskLaunchRequestSupplier {
- DataflowTaskLaunchRequestPropertiesInitializer(
- DataflowTaskLaunchRequestProperties taskLaunchRequestProperties) {
-
- this.commandLineArgumentSupplier(
- () -> new ArrayList<>(taskLaunchRequestProperties.getArgs())
- );
-
- this.deploymentPropertiesSupplier(
- () -> KeyValueListParser.parseCommaDelimitedKeyValuePairs(
- taskLaunchRequestProperties.getDeploymentProperties())
- );
-
- this.taskNameSupplier(() -> taskLaunchRequestProperties.getTaskName());
- }
- }
-
- static class ExpressionEvaluatingCommandLineArgsMapper implements CommandLineArgumentsMessageMapper {
- private final Map argExpressionsMap;
- private final EvaluationContext evaluationContext;
-
- ExpressionEvaluatingCommandLineArgsMapper(String argExpressions, EvaluationContext evaluationContext) {
- this.evaluationContext = evaluationContext;
- this.argExpressionsMap = new HashMap<>();
- if (StringUtils.hasText(argExpressions)) {
- SpelExpressionParser expressionParser = new SpelExpressionParser();
-
- KeyValueListParser.parseCommaDelimitedKeyValuePairs(argExpressions).forEach(
- (k, v) -> argExpressionsMap.put(k, expressionParser.parseExpression(v)));
- }
-
- }
-
- @Override
- public Collection processMessage(Message> message) {
- return evaluateArgExpressions(message);
- }
-
- private Collection evaluateArgExpressions(Message> message) {
- List results = new LinkedList<>();
- this.argExpressionsMap.forEach((k, expression) ->
- results.add(String.format("%s=%s", k, expression.getValue(this.evaluationContext, message))));
- return results;
- }
- }
-
-}
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/ExpressionEvaluatingTaskNameMessageMapper.java b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/ExpressionEvaluatingTaskNameMessageMapper.java
deleted file mode 100644
index 1664391c..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/ExpressionEvaluatingTaskNameMessageMapper.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2019-2020 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
- *
- * https://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.stream.app.tasklaunchrequest;
-
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.Expression;
-import org.springframework.messaging.Message;
-
-public class ExpressionEvaluatingTaskNameMessageMapper implements TaskNameMessageMapper {
-
- private final Expression expression;
- private final EvaluationContext evaluationContext;
-
- public ExpressionEvaluatingTaskNameMessageMapper(Expression expression, EvaluationContext evaluationContext) {
- this.evaluationContext = evaluationContext;
- this.expression = expression;
- }
-
- @Override
- public String processMessage(Message> message) {
- return expression.getValue(evaluationContext, message).toString();
- }
-}
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/resources/META-INF/spring-configuration-metadata-whitelist.properties b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/resources/META-INF/spring-configuration-metadata-whitelist.properties
deleted file mode 100644
index 0fbbde32..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/resources/META-INF/spring-configuration-metadata-whitelist.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-configuration-properties.classes=\
- org.springframework.cloud.stream.app.tasklaunchrequest.DataflowTaskLaunchRequestProperties
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/resources/META-INF/spring.factories b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 3e0260f2..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,2 +0,0 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- org.springframework.cloud.stream.app.tasklaunchrequest.DataFlowTaskLaunchRequestAutoConfiguration
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParserTests.java b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParserTests.java
deleted file mode 100644
index 16c5c51e..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParserTests.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2020-2020 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
- *
- * https://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.stream.app.tasklaunchrequest;
-
-import java.util.Map;
-
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- * @author Chris Schaefer
- * @author David Turanski
- */
-public class KeyValueListParserTests {
-
- @Test
- public void testParseSimpleDeploymentProperty() {
- Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs(
- "app.sftp.param=value");
-
- assertThat(deploymentProperties.size()).isEqualTo(1);
- assertThat(deploymentProperties.containsKey("app.sftp.param")).isTrue();
- assertThat(deploymentProperties.get("app.sftp.param")).isEqualTo("value");
- }
-
- @Test
- public void testParseSimpleDeploymentPropertyMultipleValues() {
- Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs(
- "app.sftp.param=value1,value2,value3");
-
- assertThat(deploymentProperties.size()).isEqualTo(1);
- assertThat(deploymentProperties.containsKey("app.sftp.param")).isTrue();
- assertThat(deploymentProperties.get("app.sftp.param")).isEqualTo("value1,value2,value3");
- }
-
- @Test
- public void testParseSpelExpressionMultipleValues() {
- Map argExpressions = KeyValueListParser.parseCommaDelimitedKeyValuePairs(
- "arg1=payload.substr(0,2),arg2=headers['foo'],arg3=headers['bar']==false");
-
-
- assertThat(argExpressions.size()).isEqualTo(3);
- assertThat(argExpressions.containsKey("arg1")).isTrue();
- assertThat(argExpressions.get("arg1")).isEqualTo("payload.substr(0,2)");
- assertThat(argExpressions.containsKey("arg2")).isTrue();
- assertThat(argExpressions.get("arg2")).isEqualTo("headers['foo']");
- }
-
- @Test
- public void testParseMultipleDeploymentPropertiesSingleValue() {
- Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs(
- "app.sftp.param=value1,app.sftp.other.param=value2");
-
- assertThat(deploymentProperties.size()).isEqualTo(2);
- assertThat(deploymentProperties.containsKey("app.sftp.param")).isTrue();
- assertThat(deploymentProperties.get("app.sftp.param")).isEqualTo("value1");
- assertThat(deploymentProperties.containsKey("app.sftp.other.param")).isTrue();
- assertThat(deploymentProperties.get("app.sftp.other.param")).isEqualTo("value2");
- }
-
- @Test
- public void testParseMultipleDeploymentPropertiesMultipleValues() {
- DataflowTaskLaunchRequestProperties taskLaunchRequestProperties = new DataflowTaskLaunchRequestProperties();
-
- Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs(
- "app.sftp.param=value1,value2,app.sftp.other.param=other1,other2");
-
- assertThat(deploymentProperties.size()).isEqualTo(2);
- assertThat(deploymentProperties.containsKey("app.sftp.param")).isTrue();
- assertThat(deploymentProperties.get("app.sftp.param")).isEqualTo("value1,value2");
- assertThat(deploymentProperties.get("app.sftp.other.param")).isEqualTo("other1,other2");
- }
-}
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestIntegrationTests.java b/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestIntegrationTests.java
deleted file mode 100644
index 45b746f2..00000000
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestIntegrationTests.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright 2018-2020 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
- *
- * https://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.stream.app.tasklaunchrequest;
-
-import java.io.IOException;
-import java.util.Collections;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.Before;
-import org.junit.Test;
-
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.test.context.runner.ApplicationContextRunner;
-import org.springframework.cloud.stream.annotation.EnableBinding;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.CommandLineArgumentsMessageMapper;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper;
-import org.springframework.cloud.stream.binder.test.OutputDestination;
-import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration;
-import org.springframework.cloud.stream.messaging.Processor;
-import org.springframework.cloud.stream.test.binder.MessageCollectorAutoConfiguration;
-import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.integration.dsl.IntegrationFlow;
-import org.springframework.integration.dsl.IntegrationFlows;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageChannel;
-import org.springframework.messaging.support.MessageBuilder;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-
-/**
- * @author David Turanski
- **/
-public class TaskLaunchRequestIntegrationTests {
-
- private ApplicationContextRunner applicationContextRunner;
-
- @Before
- public void setUp() {
- applicationContextRunner =
- new ApplicationContextRunner().withUserConfiguration(TestChannelBinderConfiguration.class, TestApp.class);
- }
-
- @Test
- public void noTaskLaunchRequestPropertiesAreRequired() {
-
- applicationContextRunner.withPropertyValues("spring.jmx.enabled=false")
- .run(context -> {
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- Message message =
- MessageBuilder.withPayload("hello".getBytes()).build();
- input.send(message);
-
- Message response = target.receive(1000);
- assertThat(response.getPayload()).isEqualTo(message.getPayload());
- });
- }
-
- @Test
- public void simpleDataflowTaskLaunchRequest() {
-
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false",
- "spring.cloud.stream.function.definition=taskLaunchRequest",
- "task.launch.request.task-name=foo")
- .run(context -> {
- DataFlowTaskLaunchRequest dataFlowTaskLaunchRequest = verifyAndreceiveDataFlowTaskLaunchRequest(context);
-
- assertThat(dataFlowTaskLaunchRequest.getTaskName()).isEqualTo("foo");
- assertThat(dataFlowTaskLaunchRequest.getCommandlineArguments()).hasSize(0);
- assertThat(dataFlowTaskLaunchRequest.getDeploymentProperties()).hasSize(0);
- });
- }
-
- @Test
- public void dataflowTaskLaunchRequestWithArgsAndDeploymentProperties() {
-
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false", "spring.cloud.stream.function.definition=taskLaunchRequest",
- "task.launch.request.task-name=foo", "task.launch.request.args=foo=bar,baz=boo",
- "task.launch.request.deploymentProperties=count=3")
- .run(context -> {
- DataFlowTaskLaunchRequest dataFlowTaskLaunchRequest = verifyAndreceiveDataFlowTaskLaunchRequest(context);
-
- assertThat(dataFlowTaskLaunchRequest.getTaskName()).isEqualTo("foo");
- assertThat(dataFlowTaskLaunchRequest.getCommandlineArguments()).containsExactlyInAnyOrder("foo=bar",
- "baz=boo");
- assertThat(dataFlowTaskLaunchRequest.getDeploymentProperties()).containsOnly(entry("count", "3"));
- });
- }
-
- @Test
- public void dataflowTaskLaunchRequestWithCommandLineArgsMessageMapper() {
-
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false", "spring.cloud.stream.function.definition=taskLaunchRequest",
- "task.launch.request.task-name=foo", "enhanceTLRArgs=true")
- .run(context -> {
-
- DataFlowTaskLaunchRequest dataFlowTaskLaunchRequest = verifyAndreceiveDataFlowTaskLaunchRequest(context);
-
- assertThat(dataFlowTaskLaunchRequest.getTaskName()).isEqualTo("foo");
- assertThat(dataFlowTaskLaunchRequest.getCommandlineArguments()).hasSize(1);
- assertThat(dataFlowTaskLaunchRequest.getCommandlineArguments()).containsExactly("runtimeArg");
- });
- }
-
- @Test
- public void taskLaunchRequestWithArgExpressions() {
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false",
- "spring.cloud.stream.function.definition=taskLaunchRequest",
- "task.launch.request.task-name=foo",
- "task.launch.request.arg-expressions=foo=payload.toUpperCase(),bar=payload.substring(0,2)")
- .run(context -> {
-
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- Message message = MessageBuilder.withPayload("hello").build();
-
- input.send(message);
-
- ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
-
- Message response = target.receive(1000);
-
- assertThat(response).isNotNull();
-
- DataFlowTaskLaunchRequest request = objectMapper.readValue(response.getPayload(),
- DataFlowTaskLaunchRequest.class);
-
- assertThat(request.getCommandlineArguments()).containsExactlyInAnyOrder("foo=HELLO", "bar=he");
-
- });
- }
-
- @Test
- public void taskLaunchRequestWithIntPayload() {
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false", "spring.cloud.stream.function.definition=taskLaunchRequest",
- "task.launch.request.task-name=foo",
- "task.launch.request.arg-expressions=i=payload")
- .run(context -> {
-
- ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
-
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- Message message =
- MessageBuilder.withPayload(123).build();
-
- input.send(message);
-
- Message response = target.receive(1000);
-
- assertThat(response).isNotNull();
-
- DataFlowTaskLaunchRequest request = objectMapper.readValue(response.getPayload(),
- DataFlowTaskLaunchRequest.class);
-
- assertThat(request.getCommandlineArguments()).containsExactly("i=123");
-
- });
- }
-
- @Test
- public void taskNameExpression() {
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false", "spring.cloud.stream.function.definition=taskLaunchRequest",
- "task.launch.request.task-name-expression=payload+'_task'")
- .run(context -> {
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
-
- Message message = MessageBuilder.withPayload("foo").build();
- input.send(message);
-
- Message response = target.receive(1000);
- assertThat(response).isNotNull();
-
- DataFlowTaskLaunchRequest request = objectMapper.readValue(response.getPayload(),
- DataFlowTaskLaunchRequest.class);
-
- assertThat(request.getTaskName()).isEqualTo("foo_task");
- });
- }
-
- @Test
- public void customTaskNameExtractor() {
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false", "spring.cloud.stream.function.definition=taskLaunchRequest",
- "customTaskNameExtractor=true")
- .run(context -> {
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
-
- Message message = MessageBuilder.withPayload("foo").build();
- input.send(message);
-
- Message response = target.receive(1000);
- assertThat(response).isNotNull();
-
- DataFlowTaskLaunchRequest request = objectMapper.readValue(response.getPayload(),
- DataFlowTaskLaunchRequest.class);
-
- assertThat(request.getTaskName()).isEqualTo("fooTask");
- });
- //TODO: Workaround for https://github.com/spring-cloud/spring-cloud-stream/issues/1876
- applicationContextRunner.withPropertyValues(
- "spring.jmx.enabled=false", "spring.cloud.stream.function.definition=taskLaunchRequest",
- "customTaskNameExtractor=true")
- .run(context -> {
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
-
- Message message = MessageBuilder.withPayload("bar").build();
- input.send(message);
-
- Message response = target.receive(1000);
- assertThat(response).isNotNull();
-
- DataFlowTaskLaunchRequest request = objectMapper.readValue(response.getPayload(),
- DataFlowTaskLaunchRequest.class);
-
- assertThat(request.getTaskName()).isEqualTo("defaultTask");
- });
- }
-
- private DataFlowTaskLaunchRequest verifyAndreceiveDataFlowTaskLaunchRequest(ApplicationContext context)
- throws IOException {
- MessageChannel input = context.getBean("input", MessageChannel.class);
-
- OutputDestination target = context.getBean(OutputDestination.class);
-
- MessageBuilder builder = MessageBuilder.withPayload(new byte[]{});
-
- ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
-
- input.send(builder.build());
-
- Message message = target.receive(1000);
-
- assertThat(message).isNotNull();
-
- return objectMapper.readValue(message.getPayload(),
- DataFlowTaskLaunchRequest.class);
- }
-
- @EnableAutoConfiguration(exclude = {TestSupportBinderAutoConfiguration.class,
- MessageCollectorAutoConfiguration.class})
- @EnableBinding(Processor.class)
- static class TestApp {
-
- @Bean
- ObjectMapper objectMapper() {
- return new ObjectMapper();
- }
-
- @Bean
- @ConditionalOnProperty("customTaskNameExtractor")
- TaskNameMessageMapper taskNameExtractor() {
- return message -> ((String) (message.getPayload())).equalsIgnoreCase("foo") ?
- "fooTask" :
- "defaultTask";
- }
-
- @Bean
- @ConditionalOnProperty("enhanceTLRArgs")
- CommandLineArgumentsMessageMapper commandLineArgumentsProvider() {
- return message -> Collections.singletonList("runtimeArg");
- }
-
- @Bean
- public IntegrationFlow flow() {
-
- return IntegrationFlows.from(Processor.INPUT)
- .channel(Processor.OUTPUT).get();
- }
- }
-}
diff --git a/applications/stream-applications-core/pom.xml b/applications/stream-applications-core/pom.xml
index 38db85d4..6c4bc301 100644
--- a/applications/stream-applications-core/pom.xml
+++ b/applications/stream-applications-core/pom.xml
@@ -56,7 +56,6 @@
common/stream-applications-test-support
common/stream-applications-postprocessor-common
common/stream-applications-micrometer-common
- common/stream-applications-task-launch-request-common
common/stream-applications-security-common
diff --git a/functions/function/task-launch-request-function/README.adoc b/functions/function/task-launch-request-function/README.adoc
new file mode 100644
index 00000000..c3e8b65e
--- /dev/null
+++ b/functions/function/task-launch-request-function/README.adoc
@@ -0,0 +1,22 @@
+# Task Launch Request Function
+
+This module provides a function that can be reused and composed in other applications to transform the output to a link:src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequest.java[TaskLaunchRequest]
+that can be used as input to the Tasklauncher function to launch a task.
+
+## Beans for injection
+
+You can import the `TaskLaunchRequestFunctionConfiguration` in a Spring Boot application and then inject the following bean.
+
+`taskLaunchRequestFunction` as a link:src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunction.java[TaskLaunchRequestFunction].
+
+You can use `taskLaunchRequestFunction` as a qualifier when injecting.
+
+Once injected, you can use the `apply` method of the `Function` to invoke it and get the result.
+
+## Configuration Options
+
+For more information on the various options available, please see link:src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionProperties.java[TaskLaunchRequestFunctionProperties.java]
+
+## Examples
+
+See this link:src/test/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionApplicationTests.java[test suite] for examples of how this function is used.
diff --git a/functions/function/task-launch-request-function/pom.xml b/functions/function/task-launch-request-function/pom.xml
new file mode 100644
index 00000000..2ce59d34
--- /dev/null
+++ b/functions/function/task-launch-request-function/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ org.springframework.cloud.fn
+ spring-functions-parent
+ 1.0.0-SNAPSHOT
+ ../../spring-functions-parent
+
+
+ 4.0.0
+
+ task-launch-request-function
+ task-launch-request-function
+
+
+
+ org.springframework.integration
+ spring-integration-core
+
+
+ org.springframework.boot
+ spring-boot-starter-json
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/CommandLineArgumentsMessageMapper.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/CommandLineArgumentsMessageMapper.java
similarity index 85%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/CommandLineArgumentsMessageMapper.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/CommandLineArgumentsMessageMapper.java
index f1bdfe4d..8cac1b0f 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/CommandLineArgumentsMessageMapper.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/CommandLineArgumentsMessageMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest.support;
+package org.springframework.cloud.fn.task.launch.request;
import java.util.Collection;
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParser.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/KeyValueListParser.java
similarity index 93%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParser.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/KeyValueListParser.java
index b9e1b20b..48f01f0e 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParser.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/KeyValueListParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest;
+package org.springframework.cloud.fn.task.launch.request;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequest.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequest.java
similarity index 87%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequest.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequest.java
index 1650e440..3644499b 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequest.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest;
+package org.springframework.cloud.fn.task.launch.request;
import java.util.ArrayList;
import java.util.Collection;
@@ -24,7 +24,7 @@ import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
-public class DataFlowTaskLaunchRequest {
+public class TaskLaunchRequest {
@JsonProperty("args")
private List commandlineArguments = new ArrayList<>();
@@ -34,31 +34,31 @@ public class DataFlowTaskLaunchRequest {
@JsonProperty("name")
private String taskName;
- public List getCommandlineArguments() {
- return this.commandlineArguments;
- }
-
public void setCommandlineArguments(List commandlineArguments) {
this.commandlineArguments = new ArrayList<>(commandlineArguments);
}
- public Map getDeploymentProperties() {
- return this.deploymentProperties;
+ public List getCommandlineArguments() {
+ return this.commandlineArguments;
}
public void setDeploymentProperties(Map deploymentProperties) {
this.deploymentProperties = deploymentProperties;
}
- public String getTaskName() {
- return this.taskName;
+ public Map getDeploymentProperties() {
+ return this.deploymentProperties;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
- public DataFlowTaskLaunchRequest addCommmandLineArguments(Collection args) {
+ public String getTaskName() {
+ return this.taskName;
+ }
+
+ public TaskLaunchRequest addCommmandLineArguments(Collection args) {
this.commandlineArguments.addAll(args);
return this;
}
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestFunction.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunction.java
similarity index 83%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestFunction.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunction.java
index 181923b9..8497b395 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestFunction.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest;
+package org.springframework.cloud.fn.task.launch.request;
import java.util.function.Function;
@@ -26,6 +26,6 @@ import org.springframework.messaging.Message;
* @author David Turanski
**/
@FunctionalInterface
-public interface TaskLaunchRequestFunction extends Function, Message> {
+public interface TaskLaunchRequestFunction extends Function, Message> {
}
diff --git a/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionConfiguration.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionConfiguration.java
new file mode 100644
index 00000000..a341e484
--- /dev/null
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionConfiguration.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2020-2020 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
+ *
+ * https://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.fn.task.launch.request;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.integration.expression.ExpressionUtils;
+import org.springframework.lang.Nullable;
+import org.springframework.messaging.Message;
+import org.springframework.util.StringUtils;
+
+/**
+ * Configuration for a {@link TaskLaunchRequestFunction}, provided as a common function that can be composed with other Suppliers or
+ * Functions to transform any {@link Message} to a {@link TaskLaunchRequest} which may be used as input to the {@code TaskLauncherFunction} to launch a task.
+ *
+ * Command line arguments used by the task, as well as the task name itself may be statically configured or extracted from
+ * the message contents, using SpEL. See {@link TaskLaunchRequestFunctionProperties} for details.
+ *
+ * It is also possible to provide your own implementations of {@link CommandLineArgumentsMessageMapper} and {@link TaskNameMessageMapper}.
+ *
+ * @author David Turanski
+ **/
+@Configuration
+@EnableConfigurationProperties(TaskLaunchRequestFunctionProperties.class)
+public class TaskLaunchRequestFunctionConfiguration {
+
+ /**
+ * The function name.
+ */
+ public final static String TASK_LAUNCH_REQUEST_FUNCTION_NAME = "taskLaunchRequestFunction";
+
+ /**
+ * A {@link java.util.function.Function} to transform a {@link Message} payload to a
+ * {@link TaskLaunchRequest}.
+ *
+ * @param taskLaunchRequestMessageProcessor a {@link TaskLaunchRequestMessageProcessor}.
+ *
+ * @return a {@code TaskLaunchRequest} Message.
+ */
+ @Bean(name = TASK_LAUNCH_REQUEST_FUNCTION_NAME)
+ public TaskLaunchRequestFunction taskLaunchRequest(
+ TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor) {
+ return message -> taskLaunchRequestMessageProcessor.postProcessMessage(message);
+ }
+
+ @Bean
+ public TaskLaunchRequestSupplier taskLaunchRequestInitializer(
+ TaskLaunchRequestFunctionProperties taskLaunchRequestProperties) {
+ return new TaskLaunchRequestPropertiesInitializer(taskLaunchRequestProperties);
+ }
+
+ @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
+ @Bean
+ public TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor(
+ TaskLaunchRequestSupplier taskLaunchRequestInitializer,
+ TaskLaunchRequestFunctionProperties properties,
+ EvaluationContext evaluationContext,
+ @Nullable TaskNameMessageMapper taskNameMessageMapper,
+ @Nullable CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper) {
+
+ if (taskNameMessageMapper == null) {
+ taskNameMessageMapper = taskNameMessageMapper(properties, evaluationContext);
+ }
+
+ if (commandLineArgumentsMessageMapper == null) {
+ commandLineArgumentsMessageMapper = commandLineArgumentsMessageMapper(properties, evaluationContext);
+ }
+
+ return new TaskLaunchRequestMessageProcessor(taskLaunchRequestInitializer,
+ taskNameMessageMapper,
+ commandLineArgumentsMessageMapper);
+ }
+
+ @Bean
+ public EvaluationContext evaluationContext(BeanFactory beanFactory) {
+ return ExpressionUtils.createStandardEvaluationContext(beanFactory);
+ }
+
+ private TaskNameMessageMapper taskNameMessageMapper(TaskLaunchRequestFunctionProperties taskLaunchRequestProperties,
+ EvaluationContext evaluationContext) {
+ if (StringUtils.hasText(taskLaunchRequestProperties.getTaskNameExpression())) {
+ SpelExpressionParser expressionParser = new SpelExpressionParser();
+ Expression taskNameExpression = expressionParser
+ .parseExpression(taskLaunchRequestProperties.getTaskNameExpression());
+ return new ExpressionEvaluatingTaskNameMessageMapper(taskNameExpression, evaluationContext);
+ }
+
+ return message -> taskLaunchRequestProperties.getTaskName();
+ }
+
+ private CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper(
+ TaskLaunchRequestFunctionProperties taskLaunchRequestFunctionProperties,
+ EvaluationContext evaluationContext) {
+ return new ExpressionEvaluatingCommandLineArgsMapper(taskLaunchRequestFunctionProperties.getArgExpressions(),
+ evaluationContext);
+ }
+
+ private static class TaskLaunchRequestPropertiesInitializer extends TaskLaunchRequestSupplier {
+ TaskLaunchRequestPropertiesInitializer(
+ TaskLaunchRequestFunctionProperties taskLaunchRequestProperties) {
+
+ this.commandLineArgumentSupplier(
+ () -> new ArrayList<>(taskLaunchRequestProperties.getArgs()));
+
+ this.deploymentPropertiesSupplier(
+ () -> KeyValueListParser.parseCommaDelimitedKeyValuePairs(
+ taskLaunchRequestProperties.getDeploymentProperties()));
+
+ this.taskNameSupplier(() -> taskLaunchRequestProperties.getTaskName());
+ }
+ }
+
+ private static class ExpressionEvaluatingTaskNameMessageMapper implements TaskNameMessageMapper {
+
+ private final Expression expression;
+ private final EvaluationContext evaluationContext;
+
+ ExpressionEvaluatingTaskNameMessageMapper(Expression expression, EvaluationContext evaluationContext) {
+ this.evaluationContext = evaluationContext;
+ this.expression = expression;
+ }
+
+ @Override
+ public String processMessage(Message> message) {
+ return expression.getValue(evaluationContext, message).toString();
+ }
+ }
+
+ private static class ExpressionEvaluatingCommandLineArgsMapper implements CommandLineArgumentsMessageMapper {
+ private final Map argExpressionsMap;
+
+ private final EvaluationContext evaluationContext;
+
+ ExpressionEvaluatingCommandLineArgsMapper(String argExpressions, EvaluationContext evaluationContext) {
+ this.evaluationContext = evaluationContext;
+ this.argExpressionsMap = new HashMap<>();
+ if (StringUtils.hasText(argExpressions)) {
+ SpelExpressionParser expressionParser = new SpelExpressionParser();
+
+ KeyValueListParser.parseCommaDelimitedKeyValuePairs(argExpressions).forEach(
+ (k, v) -> argExpressionsMap.put(k, expressionParser.parseExpression(v)));
+ }
+ }
+
+ @Override
+ public Collection processMessage(Message> message) {
+ return evaluateArgExpressions(message);
+ }
+
+ private Collection evaluateArgExpressions(Message> message) {
+ List results = new LinkedList<>();
+ this.argExpressionsMap.forEach((k, expression) -> results
+ .add(String.format("%s=%s", k, expression.getValue(this.evaluationContext, message))));
+ return results;
+ }
+ }
+
+}
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataflowTaskLaunchRequestProperties.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionProperties.java
similarity index 92%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataflowTaskLaunchRequestProperties.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionProperties.java
index 95ad6ce8..bdde0504 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataflowTaskLaunchRequestProperties.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunctionProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest;
+package org.springframework.cloud.fn.task.launch.request;
import java.util.ArrayList;
import java.util.List;
@@ -27,14 +27,14 @@ import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
/**
- * Base Properties to create a {@link DataFlowTaskLaunchRequest}.
+ * Base Properties to create a {@link TaskLaunchRequest}.
*
* @author Chris Schaefer
* @author David Turanski
*/
@Validated
@ConfigurationProperties("task.launch.request")
-public class DataflowTaskLaunchRequestProperties {
+public class TaskLaunchRequestFunctionProperties {
/**
* Comma separated list of optional args in key=value format.
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestMessageProcessor.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestMessageProcessor.java
similarity index 57%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestMessageProcessor.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestMessageProcessor.java
index 2fb84361..1bbea190 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestMessageProcessor.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestMessageProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,11 +14,8 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest;
+package org.springframework.cloud.fn.task.launch.request;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.CommandLineArgumentsMessageMapper;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskLaunchRequestSupplier;
-import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.core.MessagePostProcessor;
@@ -27,15 +24,17 @@ import org.springframework.util.Assert;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StringUtils;
-public class TaskLaunchRequestMessageProcessor implements MessagePostProcessor {
+class TaskLaunchRequestMessageProcessor implements MessagePostProcessor {
private final TaskNameMessageMapper taskNameMessageMapper;
+
private final CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper;
+
private final TaskLaunchRequestSupplier taskLaunchRequestInitializer;
- public TaskLaunchRequestMessageProcessor(TaskLaunchRequestSupplier taskLaunchRequestInitializer,
- TaskNameMessageMapper taskNameMessageMapper,
- CommandLineArgumentsMessageMapper commandLIneArgumentsMessageMapper) {
+ TaskLaunchRequestMessageProcessor(TaskLaunchRequestSupplier taskLaunchRequestInitializer,
+ TaskNameMessageMapper taskNameMessageMapper,
+ CommandLineArgumentsMessageMapper commandLIneArgumentsMessageMapper) {
this.taskLaunchRequestInitializer = taskLaunchRequestInitializer;
@@ -46,24 +45,23 @@ public class TaskLaunchRequestMessageProcessor implements MessagePostProcessor {
}
@Override
- public Message postProcessMessage(Message> message) {
- DataFlowTaskLaunchRequest taskLaunchRequest = taskLaunchRequestInitializer.get();
+ public Message postProcessMessage(Message> message) {
+ TaskLaunchRequest taskLaunchRequest = taskLaunchRequestInitializer.get();
if (!StringUtils.hasText(taskLaunchRequest.getTaskName())) {
taskLaunchRequest.setTaskName(taskNameMessageMapper.processMessage(message));
- Assert.hasText(taskLaunchRequest.getTaskName(), () ->
- "'taskName' is required in " + DataFlowTaskLaunchRequest.class.getName());
+ Assert.hasText(taskLaunchRequest.getTaskName(),
+ () -> "'taskName' is required in " + TaskLaunchRequest.class.getName());
}
taskLaunchRequest.addCommmandLineArguments(commandLineArgumentsMessageMapper.processMessage(message));
- MessageBuilder builder
- = MessageBuilder.withPayload(taskLaunchRequest).copyHeaders(message.getHeaders());
+ MessageBuilder builder = MessageBuilder.withPayload(taskLaunchRequest)
+ .copyHeaders(message.getHeaders());
return adjustHeaders(builder).build();
}
-
- private MessageBuilder adjustHeaders(MessageBuilder builder) {
+ private MessageBuilder adjustHeaders(MessageBuilder builder) {
builder.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
return builder;
}
diff --git a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/TaskLaunchRequestSupplier.java b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestSupplier.java
similarity index 63%
rename from applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/TaskLaunchRequestSupplier.java
rename to functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestSupplier.java
index dfc22fc2..1d6bb373 100644
--- a/applications/stream-applications-core/common/stream-applications-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/TaskLaunchRequestSupplier.java
+++ b/functions/function/task-launch-request-function/src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestSupplier.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the original author or authors.
+ * Copyright 2020-2020 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.
@@ -14,21 +14,21 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.app.tasklaunchrequest.support;
+package org.springframework.cloud.fn.task.launch.request;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
-import org.springframework.cloud.stream.app.tasklaunchrequest.DataFlowTaskLaunchRequest;
import org.springframework.util.Assert;
-public class TaskLaunchRequestSupplier implements Supplier {
+class TaskLaunchRequestSupplier implements Supplier {
private Supplier taskNameSupplier;
- private Supplier> commandLineArgumentsSupplier;
- private Supplier