INT-3944: Async JMS Outbound Gateway
JIRA: https://jira.spring.io/browse/INT-3944 Polishing (PR comments) and Doc Polish Polishing - PR Comments Remove custom `async` boolean in favor of the now public setter. Add exception to `JmsException` hierarchy. INT-3944: Polishing * Rename `asyncReplySupported` just to `async`. As well as its getter and setter. Plus fix docs on the matter * Polishing for the `JmsOutboundGateway` according PR comments * Rework `JmsOutboundGateway` to return `AbstractIntegrationMessageBuilder` instead of `Message` since `AbstractMessageProducingHandler` rebuilds `Message` for a new one to copy headers from request * Add `getPayload()` and `getHeaders()` to the `AbstractIntegrationMessageBuilder` to make the `Routing Slip` users happy, when the `AbstractIntegrationMessageBuilder` is pushed to the `Routing Slip path` function * Fix race condition in the `ChatMessageListeningEndpointTests`: the `stanza` parsing is done in the different Thread. Doc Polishing (Routing Slip) Fix timing issue in the `LastModifiedFileListFilterTests`: `Thread.sleep()` not always reflects the reality. Switch to the "past simulation" via explicit `File.setLastModified()`
This commit is contained in:
committed by
Artem Bilan
parent
0fd72d2d18
commit
4bfcdb9dfa
@@ -915,8 +915,10 @@ public class AmqpJavaApplication {
|
||||
The gateway discussed in the previous section is synchronous, in that the sending thread is suspended until a
|
||||
reply is received (or a timeout occurs).
|
||||
Spring Integration _version 4.3_ added this asynchronous gateway, which uses the `AsyncRabbitTemplate` from Spring AMQP.
|
||||
When a message is sent, the thread returns immediately and the reply is sent on the template's listener container
|
||||
thread when it is received.
|
||||
When a message is sent, the thread returns immediately after the send completes, and the reply is sent on the template's
|
||||
listener container thread when it is received.
|
||||
This can be useful when the gateway is invoked on a poller thread; the thread is released and is available for other
|
||||
tasks in the framework.
|
||||
|
||||
Configuration for an AMQP Async Outbound Gateway is shown below.
|
||||
|
||||
|
||||
@@ -397,6 +397,23 @@ __NOT ALLOWED__
|
||||
User-supplied correlation ids are not permitted with a reply listener; the gateway will not initialize with this
|
||||
configuration.
|
||||
|
||||
[[jms-async-gateway]]
|
||||
==== Async Gateway
|
||||
|
||||
Starting with _version 4.3_, you can now specify `async="true"` (or `setAsync(true)`) when configuring the outbound
|
||||
gateway.
|
||||
|
||||
By default, when a request is sent to the gateway, the requesting thread is suspended until the reply is received and
|
||||
the flow then continues on that thread.
|
||||
If `async` is true, the requesting thread is released immediately after the send completes, and the reply is returned
|
||||
(and the flow continues) on the listener container thread.
|
||||
This can be useful when the gateway is invoked on a poller thread; the thread is released and is available for other
|
||||
tasks within the framework.
|
||||
|
||||
`async` requires a `<reply-listener/>` (or `setUseReplyContainer(true)` when using Java configuration); it also
|
||||
requires a `correlationKey` (usually `JMSCorrelationID`) to be specified.
|
||||
If either of these conditions are not met, `async` is ignored.
|
||||
|
||||
[[jms-og-attributes]]
|
||||
==== Attribute Reference
|
||||
|
||||
@@ -426,9 +443,10 @@ configuration.
|
||||
request-destination-name="" <21>
|
||||
request-pub-sub-domain="" <22>
|
||||
time-to-live="" <23>
|
||||
requires-reply=""> <24>
|
||||
idle-reply-listener-timeout <25>
|
||||
<int-jms:reply-listener /> <26>
|
||||
requires-reply="" <24>
|
||||
idle-reply-listener-timeout="" <25>
|
||||
async=""> <26>
|
||||
<int-jms:reply-listener /> <27>
|
||||
</int-jms:outbound-gateway>
|
||||
----
|
||||
|
||||
@@ -541,7 +559,9 @@ are outstanding).
|
||||
The container will be started again on the next request.
|
||||
The stop time is a minimum and may actually be up to 1.5x this value.
|
||||
|
||||
<26> When this element is included, replies are received by an asynchronous `MessageListenerContainer` rather than
|
||||
<26> See <<jms-async-gateway>>.
|
||||
|
||||
<27> When this element is included, replies are received by an asynchronous `MessageListenerContainer` rather than
|
||||
creating a consumer for each reply.
|
||||
This can be more efficient in many cases.
|
||||
|
||||
|
||||
@@ -28,16 +28,6 @@ In order to provide a quick overview, all available attributes are listed in the
|
||||
[cols="2,1,1,1,1,1,1", options="header"]
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| Attribute
|
||||
|
||||
|
||||
@@ -59,12 +49,6 @@ In order to provide a quick overview, all available attributes are listed in the
|
||||
| exception type router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| apply-sequence
|
||||
|
||||
|
||||
@@ -76,12 +60,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| default-output-channel
|
||||
|
||||
|
||||
@@ -93,12 +71,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| resolution-required
|
||||
|
||||
|
||||
@@ -110,12 +82,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| ignore-send-failures
|
||||
|
||||
|
||||
@@ -127,12 +93,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| timeout
|
||||
|
||||
|
||||
@@ -144,12 +104,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| id
|
||||
|
||||
|
||||
@@ -161,12 +115,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| auto-startup
|
||||
|
||||
|
||||
@@ -178,12 +126,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| input-channel
|
||||
|
||||
|
||||
@@ -195,12 +137,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| order
|
||||
|
||||
|
||||
@@ -212,12 +148,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| method
|
||||
|
||||
|
||||
@@ -229,12 +159,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| ref
|
||||
|
||||
|
||||
@@ -246,12 +170,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| expression
|
||||
|
||||
|
||||
@@ -263,12 +181,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| header-name
|
||||
|
||||
|
||||
@@ -280,12 +192,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| evaluate-as-string
|
||||
|
||||
|
||||
@@ -297,12 +203,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| xpath-expression-ref
|
||||
|
||||
|
||||
@@ -314,12 +214,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| converter
|
||||
|
||||
|
||||
@@ -331,10 +225,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
.Routers Inside of a Chain
|
||||
@@ -342,15 +232,6 @@ a| image::images/tickmark.png[]
|
||||
|===
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| Attribute
|
||||
|
||||
|
||||
@@ -372,12 +253,6 @@ a| image::images/tickmark.png[]
|
||||
| exception type router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| apply-sequence
|
||||
|
||||
|
||||
@@ -389,12 +264,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| default-output-channel
|
||||
|
||||
|
||||
@@ -406,12 +275,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| resolution-required
|
||||
|
||||
|
||||
@@ -423,12 +286,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| ignore-send-failures
|
||||
|
||||
|
||||
@@ -440,12 +297,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| timeout
|
||||
|
||||
|
||||
@@ -457,12 +308,6 @@ a| image::images/tickmark.png[]
|
||||
a| image::images/tickmark.png[]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| id
|
||||
|
||||
|
||||
@@ -474,12 +319,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| auto-startup
|
||||
|
||||
|
||||
@@ -491,12 +330,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| input-channel
|
||||
|
||||
|
||||
@@ -508,12 +341,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| order
|
||||
|
||||
|
||||
@@ -525,12 +352,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| method
|
||||
|
||||
|
||||
@@ -542,12 +363,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| ref
|
||||
|
||||
|
||||
@@ -559,12 +374,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| expression
|
||||
|
||||
|
||||
@@ -576,12 +385,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| header-name
|
||||
|
||||
|
||||
@@ -593,12 +396,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| evaluate-as-string
|
||||
|
||||
|
||||
@@ -610,12 +407,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| xpath-expression-ref
|
||||
|
||||
|
||||
@@ -627,12 +418,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| converter
|
||||
|
||||
|
||||
@@ -644,10 +429,6 @@ a| image::images/tickmark.png[]
|
||||
|
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|===
|
||||
|
||||
[IMPORTANT]
|
||||
@@ -1310,6 +1091,15 @@ This is to avoid the overhead of `EvaluationContext` creation for each `Expressi
|
||||
It is a simple Java Bean with two properties - `Message<?> request` and `Object reply`.
|
||||
With this expression implementation, we can specify Routing Slip `path` entries using SpEL (`@routingSlipRoutingPojo.get(request, reply)`, `request.headers[myRoutingSlipChannel]`) avoiding a bean definition for the `RoutingSlipRouteStrategy`.
|
||||
|
||||
NOTE: The `requestMessage` argument is always a `Message<?>`; depending on context, the reply object may be a
|
||||
`Message<?>`, an `AbstractIntegrationMessageBuilder` or an arbitrary application domain object (if, for example,
|
||||
it is returned by a POJO method invoked by a service activator).
|
||||
In the first two cases, the usual "message" properties are available (`payload` and `headers`) when using SpEL (or
|
||||
a Java implementation).
|
||||
When an arbitrary domain object, these properties are, obviously, not available.
|
||||
Care should be taken when using routing slips in conjunction with POJO methods if the result is used to determine the
|
||||
next path.
|
||||
|
||||
IMPORTANT: If a _Routing Slip_ is involved in a distributed environment - cross-JVM application, `request-reply` through a Message Broker (e.g.
|
||||
<<amqp>>, <<jms>>), or persistence `MessageStore` (<<message-store>>) is used in the integration flow, etc., - it is recommended to *not* use _inline_ expressions for the Routing Slip `path`.
|
||||
The framework (`RoutingSlipHeaderValueMessageProcessor`) converts them to `ExpressionEvaluatingRoutingSlipRouteStrategy` objects and they are used in the `routingSlip` message header.
|
||||
|
||||
@@ -114,7 +114,7 @@ The service activator is invoked by the calling thread; this would be some upstr
|
||||
`SubscribableChannel`, or a poller thread for a `PollableChannel`.
|
||||
If the service returns a `ListenableFuture<?>` the default action is to send that as the payload of the message sent
|
||||
to the output (or reply) channel.
|
||||
Starting with _version 4.3_, you can now set the `async` attribute to true (`setAsyncReplySupported(true)` when using
|
||||
Starting with _version 4.3_, you can now set the `async` attribute to true (`setAsync(true)` when using
|
||||
Java configuration).
|
||||
If the service returns a `ListenableFuture<?>` when this is true, the calling thread is released immediately, and the
|
||||
reply message is sent on the thread (from within your service) that completes the future.
|
||||
|
||||
@@ -48,10 +48,17 @@ See <<imap-seen>> for more information.
|
||||
|
||||
==== JMS Changes
|
||||
|
||||
===== Header Mapper
|
||||
|
||||
The `DefaultJmsHeaderMapper` now maps the standard `correlationId` header as a message property by invoking its
|
||||
`toString()` method.
|
||||
See <<jms-header-mapping>> for more information.
|
||||
|
||||
===== Async Gateway
|
||||
|
||||
The JMS Outbound gateway now has an `async` property.
|
||||
See <<jms-async-gateway>> for more information.
|
||||
|
||||
==== Aggregator Changes
|
||||
|
||||
There is a change in behavior when a POJO aggregator releases a collection of `Message<?>` objects; this is rare but if
|
||||
|
||||
Reference in New Issue
Block a user