diff --git a/build.gradle b/build.gradle
index e542a1b147..409eb79138 100644
--- a/build.gradle
+++ b/build.gradle
@@ -101,7 +101,8 @@ subprojects { subproject ->
openJpaVersion = '2.3.0'
pahoMqttClientVersion = '0.4.0'
postgresVersion = '9.1-901-1.jdbc4'
- reactorVersion = '1.1.2.RELEASE'
+ reactorVersion = '1.1.4.RELEASE'
+ reactorSpringVersion = '1.1.3.RELEASE'
romeToolsVersion = '1.5.0'
romeVersion = '1.0.0'
saajApiVersion = '1.3.5'
@@ -243,6 +244,7 @@ project('spring-integration-core') {
compile "org.springframework:spring-tx:$springVersion"
compile "org.springframework.retry:spring-retry:$springRetryVersion"
compile "org.projectreactor:reactor-core:$reactorVersion"
+ compile("org.projectreactor.spring:reactor-spring-context:$reactorSpringVersion", optional)
compile("org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion", optional)
compile("com.fasterxml.jackson.core:jackson-databind:$jackson2Version", optional)
compile("com.jayway.jsonpath:json-path:$jsonpathVersion", optional)
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/annotation/MessagingGateway.java b/spring-integration-core/src/main/java/org/springframework/integration/annotation/MessagingGateway.java
index 3287d89c0e..5b60e1b8bc 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/annotation/MessagingGateway.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/annotation/MessagingGateway.java
@@ -36,14 +36,12 @@ public @interface MessagingGateway {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
- *
* @return the suggested component name, if any
*/
String name() default "";
/**
* Identifies default channel the messages will be sent to upon invocation of methods of the gateway proxy.
- *
* @return the suggested channel name, if any
*/
String defaultRequestChannel() default "";
@@ -51,7 +49,6 @@ public @interface MessagingGateway {
/**
* Identifies default channel the gateway proxy will subscribe to to receive reply {@code Message}s, which will then be
* converted to the return type of the method signature.
- *
* @return the suggested channel name, if any
*/
String defaultReplyChannel() default "";
@@ -61,7 +58,6 @@ public @interface MessagingGateway {
* gateway's proxy invocation. If no {@code errorChannel} reference is provided, the gateway will
* propagate {@code Exception}s to the caller. To completely suppress {@code Exception}s, provide a
* reference to the {@code nullChannel} here.
- *
* @return the suggested channel name, if any
*/
String errorChannel() default "";
@@ -70,7 +66,6 @@ public @interface MessagingGateway {
* Provides the amount of time dispatcher would wait to send a {@code Message}.
* This timeout would only apply if there is a potential to block in the send call.
* For example if this gateway is hooked up to a {@code QueueChannel}.
- *
* @return the suggested timeout in milliseconds, if any
*/
long defaultRequestTimeout() default Long.MIN_VALUE;
@@ -79,7 +74,6 @@ public @interface MessagingGateway {
* Allows to specify how long this gateway will wait for the reply {@code Message}
* before returning. By default it will wait indefinitely. {@code null} is returned
if the gateway times out.
- *
* @return the suggested timeout in milliseconds, if any
*/
long defaultReplyTimeout() default Long.MIN_VALUE;
@@ -89,7 +83,6 @@ public @interface MessagingGateway {
* to use for any of the interface methods that have a {@link java.util.concurrent.Future} return type.
* This {@code Executor} will only be used for those async methods; the sync methods
* will be invoked in the caller's thread.
- *
* @return the suggested executor bean name, if any
*/
String asyncExecutor() default "";
@@ -99,7 +92,6 @@ public @interface MessagingGateway {
* unless explicitly overridden by a method declaration. Variables include {@code #args}, {@code #methodName},
* {@code #methodString} and {@code #methodObject};
* a bean resolver is also available, enabling expressions like {@code @someBean(#args)}.
- *
* @return the suggested payload expression, if any
*/
String defaultPayloadExpression() default "";
@@ -107,7 +99,6 @@ public @interface MessagingGateway {
/**
* Provides custom message headers. These default headers are created for
* all methods on the service-interface (unless overridden by a specific method).
- *
* @return the suggested payload expression, if any
*/
GatewayHeader[] defaultHeaders() default {};
@@ -117,9 +108,19 @@ public @interface MessagingGateway {
* to map the method arguments to a {@link org.springframework.messaging.Message}. When this
* is provided, no {@code payload-expression}s or {@code header}s are allowed; the custom mapper is
* responsible for creating the message.
- *
* @return the suggested mapper bean name, if any
*/
String mapper() default "";
+ /**
+ * Provide a reference to an {@link reactor.core.Environment}
+ * to use for any of the interface methods that have a {@link reactor.core.composable.Promise} return type.
+ * This {@code reactor.core.Environment} will only be used for those async methods; the sync methods
+ * will be invoked in the caller's thread.
+ *
This attribute is required in case of {@link reactor.core.composable.Promise} usage.
+ * @return the suggested reactor Environment bean name.
+ * @since 4.1
+ */
+ String reactorEnvironment() default "";
+
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java b/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java
index 15479975e8..0e645efa20 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java
@@ -83,6 +83,7 @@ public class MessagingGatewayRegistrar implements ImportBeanDefinitionRegistrar
String defaultReplyChannel = (String) gatewayAttributes.get("defaultReplyChannel");
String errorChannel = (String) gatewayAttributes.get("errorChannel");
String asyncExecutor = (String) gatewayAttributes.get("asyncExecutor");
+ String reactorEnvironment = (String) gatewayAttributes.get("reactorEnvironment");
String mapper = (String) gatewayAttributes.get("mapper");
boolean hasMapper = StringUtils.hasText(mapper);
@@ -135,6 +136,9 @@ public class MessagingGatewayRegistrar implements ImportBeanDefinitionRegistrar
if (StringUtils.hasText(asyncExecutor)) {
gatewayProxyBuilder.addPropertyReference("asyncExecutor", asyncExecutor);
}
+ if (StringUtils.hasText(reactorEnvironment)) {
+ gatewayProxyBuilder.addPropertyReference("reactorEnvironment", reactorEnvironment);
+ }
if (StringUtils.hasText(mapper)) {
gatewayProxyBuilder.addPropertyReference("mapper", mapper);
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java
index 8656978ace..de705b1e0a 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GatewayParser.java
@@ -63,6 +63,7 @@ public class GatewayParser implements BeanDefinitionParser {
gatewayAttributes.put("errorChannel", element.getAttribute("error-channel"));
gatewayAttributes.put("asyncExecutor", element.getAttribute("async-executor"));
gatewayAttributes.put("mapper", element.getAttribute("mapper"));
+ gatewayAttributes.put("reactorEnvironment", element.getAttribute("reactor-environment"));
gatewayAttributes.put("defaultReplyTimeout", element.getAttribute(isNested ? "reply-timeout" : "default-reply-timeout"));
gatewayAttributes.put("defaultRequestTimeout", element.getAttribute(isNested ? "request-timeout" : "default-request-timeout"));
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java
index 44c971eb1a..9414c2426b 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java
@@ -62,6 +62,11 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
+import reactor.core.Environment;
+import reactor.core.composable.Promise;
+import reactor.core.composable.spec.Promises;
+import reactor.function.Functions;
+
/**
* Generates a proxy for the provided service interface to enable interaction
* with messaging components without application code being aware of them allowing
@@ -75,7 +80,8 @@ import org.springframework.util.StringUtils;
* @author Gary Russell
* @author Artem Bilan
*/
-public class GatewayProxyFactoryBean extends AbstractEndpoint implements TrackableComponent, FactoryBean