<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2357504012170207916</id><updated>2012-02-09T14:12:30.458-08:00</updated><category term='recovery'/><category term='integration'/><category term='input-channel'/><category term='configuration'/><category term='spring'/><category term='backout'/><category term='splitter'/><category term='JUnit'/><category term='Spring Integration'/><category term='aggregator'/><category term='Java'/><category term='svn'/><category term='claim-check'/><category term='subversion'/><title type='text'>TechiQuest by Matt Vickery</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-7310765468201181054</id><published>2012-02-08T06:50:00.000-08:00</published><updated>2012-02-08T08:00:36.126-08:00</updated><title type='text'>Spring Integration Gateways - Null Handling &amp; Timeouts</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Spring Integration (SI) Gateways&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Spring Integration Gateways (&lt;i&gt;&amp;lt;int:gateway&amp;gt;&lt;/i&gt;) provide a semantically rich interface to message sub-systems. Gateways are specified using namespace constructs, these reference a specific Java interface (&lt;i&gt;&amp;lt;service-interface&amp;gt;&lt;/i&gt;) that is backed by an object dynamically implemented at run-time by the Spring Integration framework. Furthermore, these Java interfaces can, if you so wish, be defined entirely independent of any Spring artefacts - that's both code and configuration.&lt;br /&gt;&lt;br /&gt;One of the primary advantages of using the SI gateway as an interface to message sub-systems is that it's possible to automatically adopt the benefit of rich, default and customisable,&amp;nbsp;gateway configuration. One such configuration attribute deserves further scrutiny and discussion primarily because it's easy to misunderstand and misconfigure around - &lt;i&gt;default-reply-timeout&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Primary Motivator for Gateway Analysis&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;During recent consulting engagements, I've encountered a number of deployments that use Spring Integration &lt;i&gt;Gateway&lt;/i&gt; specifications that may, in some circumstances, lead to production operational instability. This has often been in high-pressure environments or those where technology support is not backed by adequate training, testing, review or technology mentoring.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;How do gateways behave in Spring Integration (R2.0.5)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;One of the key sections, regarding gateways, in the Spring Integration manual clearly &lt;a href="http://static.springsource.org/spring-integration/docs/2.0.5.RELEASE/reference/htmlsingle/#gateway"&gt;explains&lt;/a&gt; gateway semantics.&amp;nbsp;Below is a 2-dimensional table of possible non-standard gateway returns for each of the scenarios that the SI Manual (r2.0.5) refers to.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;Gateway Non-standard Responses&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="3" style="background-color: #ffff99;"&gt; &lt;tbody&gt;&lt;tr&gt;  &lt;td&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;Runtime Events&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;b&gt;default-reply-timeout=x&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Single-threaded&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;b&gt;default-reply-timeout=x&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Multi-threaded&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;b&gt;default-reply-timeout=null&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Single-threaded&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;b&gt;default-reply-timeout=null&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Multi-threaded&lt;/b&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;b&gt;1. Long Running&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Process&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: orange;"&gt;null returned&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;b&gt;2. Null Returned&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Downstream&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: orange;"&gt;&lt;b&gt;null returned&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: orange;"&gt;&lt;b&gt;null returned&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;b&gt;3. void method &lt;/b&gt;&lt;br /&gt;&lt;b&gt;Downstream&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: orange;"&gt;&lt;b&gt;null returned&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: orange;"&gt;&lt;b&gt;null returned&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;Thread Parked&lt;/b&gt;&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;b&gt;4. Runtime&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Exception&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;Error handler invoked or&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;exception thrown.&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;Error handler invoked or&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;exception thrown.&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;Error handler invoked or&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;exception thrown.&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;  &lt;td&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;Error handler invoked or&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;exception thrown.&lt;/b&gt;&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div&gt;The key parts of this table are the conditions that lead to invoking threads being parked (noted in red), nulls returned (noted in orange) and exceptions (noted in green). Each contributor consists of configuration that is under the developers control, deployed code that is under developers control and conditions that are usually not under developers control.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Clearly, the column headings in the table above are divided into two sections; two gateway configuration attributes. The &lt;i&gt;default-reply-timeout &lt;/i&gt;is set by the SI configured and is the amount of time that a client call is wiling to wait for a response from the gateway. Secondly, synchronous flows are represented by Single-threaded flows, asynchronous by Multi-threaded flows.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A synchronous, or single-threaded flow, is one such as the following:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration/spring-integration-2.1.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;import&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;resource="common-beans.xml"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:gateway&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="enrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #4070a0;"&gt;service-interface="com.l8mdv.sample.EnrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #4070a0;"&gt;default-request-channel="gateway-request-channel"&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #4070a0;"&gt;default-reply-channel="gateway-response-channel"&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #4070a0;"&gt;default-reply-timeout="6000"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="sleeperService"&lt;/span&gt; &lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;input-channel="gateway-request-channel"&lt;/span&gt;&lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;output-channel="gateway-response-channel"&lt;/span&gt; &lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;ref="sleeper"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The implicit input channel (&lt;i&gt;gateway-request-channel&lt;/i&gt;) has no associated dispatcher configured. An asynchronous, or multi-threaded flow, is one such as the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration/spring-integration-2.1.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;import&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;resource="common-beans.xml"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:gateway&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="enrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;service-interface="com.l8mdv.sample.EnrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;default-request-channel="gateway-request-channel"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;default-reply-channel="gateway-response-channel"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;default-reply-timeout="6000"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="gateway-request-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:dispatcher&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;task-executor="taskExecutor"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:channel&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="sleeperService"&lt;/span&gt; &lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;input-channel="gateway-request-channel"&lt;/span&gt;&lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;output-channel="gateway-response-channel"&lt;/span&gt; &lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;ref="sleeper"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The explicit input channel has a dispatcher configured ("&lt;i&gt;taskExecutor&lt;/i&gt;"). This task executor specifies a thread pool that supplies threads for execution and whose configuration as above marks a thread boundary. Note: This is not the only way of making channels asynchronous&lt;br /&gt;&lt;br /&gt;The other configuration attribute referenced is &lt;i&gt;default-reply-timeout&lt;/i&gt;, this is set on the gateway namespace configuration such as the example above. Note that both of these runtime aspects are set by the configurer during SI flow design and implementation. They are entirely under developer control.&lt;br /&gt;&lt;br /&gt;The 'Runtime Events' column indicates gateway relevant runtime events that have to be considered during gateway configuration - these are obviously not under developer control. Trigger conditions for these events are not as unusual as one may hope.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Long Running Processes&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;It's not uncommon for thread pools to become exhausted because &lt;i&gt;all&lt;/i&gt; pooled threads are waiting for an external resource accessed through a socket, this may be a long running database query, a firewall keeping a connection open despite the server terminating etc. There is significant potential for these types of trigger. Some long-running processes terminate naturally, sometimes they never completed - an application restart is required.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Null returned downstream&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;A null may be returned from a downstream SI construct such as a Transformer, Service Activator or Gateway. A Gateway may return null in some circumstances such as following a gateway timeout event.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Void method downstream&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Any custom code invoked during an SI flow may use a void method signature. This can also be caused by configuration in circumstances where flows are determined dynamically at runtime.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Runtime Exception&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;RuntimeException's can be triggered during normal operation and are generally handled by catching them at the gateway or allowing them to propagate through. The reason that they are coloured green in the table above is that they are generally much easier to handle than timeouts.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Gateway Timeout Handling Strategies&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There are four possible outcomes from invoking a gateway with a request message, all of these as a result of specific runtime events: a) an ordinary message response, b) an exception message, c) a null or d) no-response.&lt;br /&gt;&lt;br /&gt;Ordinary business responses and exceptions are straight forward to understand and will not be covered further in this article. The two significant outcomes that will be explored further are strategies for dealing with nulls and no-response.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Generally speaking, long running processes either terminate or not. Long running processes that terminate &lt;i&gt;may&lt;/i&gt; eventually return a message through the invoked gateway or timeout depending on timeout configuration, in which case a null &lt;i&gt;may&lt;/i&gt; be returned. The severity of this as a problem depends on throughput volume, length of long running process and system resources (thread-pool size).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Configuration exists for &lt;i&gt;default-reply-timeout&amp;nbsp;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In the case where a long running process event is underway and a &lt;i&gt;default-reply-timeout&lt;/i&gt;&amp;nbsp;has been set, as long as the long running process completes before the &lt;i&gt;default-reply-timeout&lt;/i&gt;&amp;nbsp;expires, there is no problem to deal with. However, if the long running process does not complete before that timeout expires one of three outcomes will apply.&lt;br /&gt;&lt;br /&gt;Firstly, if the long running process terminates subsequent to the reply timeout expiry, the gateway will have already returned null to the invoker so the null response needs handling by the invoker. The thread handling the long-running process will be returned to the pool.&lt;br /&gt;&lt;br /&gt;Secondly, if the long running process does not terminate and a reply timeout has been set, the gateway will return null to the gateway invoker but the thread executing the long-running process will not get returned to the pool.&lt;br /&gt;&lt;br /&gt;Thirdly, and most significantly, if a &lt;i&gt;default-reply-timeout&lt;/i&gt; has been configured but the long running process is running on the same thread as the invoker, i.e. synchronous channels supply messages to that process, the thread will not return, the &lt;i&gt;default-reply-timeout&lt;/i&gt; has no affect.&lt;br /&gt;&lt;br /&gt;Assuming the most common processing scenario, a long running process completes either before or after the reply timeout expiry. When a null is returned by the gateway, the invoker is forced to deal with a null response. It's often unacceptable to force gateway consumers to deal with null responses and is not necessary as with a little additional configuration, this can be avoided.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Absent Configuration for &lt;i&gt;default-reply-timeout&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;The most significant danger exists around gateways that have no &lt;i&gt;default-reply-timeout &lt;/i&gt;configuration set.&lt;br /&gt;&lt;br /&gt;A long running process or a null returned from downstream will mean that the invoking thread is parked. This is true for both synchronous and asynchronous flows and may ultimately force an application to be restarted because the invoker thread pool is likely to start on a depletion course if this continues to occur.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Spring Integration Timeout Handling Design Strategies&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;For those Spring Integration configuration designers that are comfortable with gateway invokers dealing with null responses, exceptions and set &lt;i&gt;default-reply-timeouts&lt;/i&gt; on gateways, there's no need to read further. However, if you wish to provide clients of your gateway a more predictable response, a couple of strategies exist for handling null responses from gateways in order that invokers are protected from having to deal with them.&lt;br /&gt;&lt;br /&gt;Firstly, the simpliest solution is to wrap the gateway with a service activator. The gateway must have the &lt;i&gt;default-reply-timeout&lt;/i&gt;&amp;nbsp;attribute value set in order to avoid unnecessary parking of threads. In order to avoid the consequence of long-running threads it's also very prudent to use a dispatcher soon after entry to the gateway - this breaks the thread boundary.&lt;br /&gt;&lt;br /&gt;Whilst this is a valid technical approach, the impact is that we have forced a different entry point to our message sub-system. Entry is now via a &lt;i&gt;Service Activator&lt;/i&gt; rather than a &lt;i&gt;Gateway&lt;/i&gt;. A side affect of this change is that the testing entry point changes. Integration tests that would normally reference a gateway to send a message now have to locate the backing implementation for the Service Activator, not ideal.&lt;br /&gt;&lt;br /&gt;An alternative approach toward solving this problem would be to configure two gateways with a &lt;i&gt;Service Activator&lt;/i&gt; between them. Only one of the gateways would be exposed to invokers, the outer one. Both Gateways would reference the same service interface.&amp;nbsp;The outer gateway specification would not specify the default-reply-timeout but would specify the input and output channels in the same way that a single gateway would. The Service Activator between the Gateways would handle null gateway responses and possibly any exceptions if preferred to the gateway error handler approach.&lt;br /&gt;&lt;br /&gt;An example is as follows:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www...org/schema/integration/spring-integration-2.1.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;import&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;resource="common-beans.xml"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:gateway&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="enrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;service-interface="com.l8mdv.sample.EnrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;default-request-channel="gateway-request-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- This service activator has the adapted gateway injected as a bean and&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #60a0b0; font-style: italic;"&gt;    calls the adapted gateway from within the service method directly. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="enrollmentServiceGatewayHandler"&lt;/span&gt;&lt;br /&gt;                           &lt;span style="color: #4070a0;"&gt;input-channel="gateway-request-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sample.EnrollmentServiceGatewayHandler"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="enrollmentServiceAdaptedGateway"&lt;/span&gt;&lt;br /&gt;                             &lt;span style="color: #4070a0;"&gt;ref="enrollmentServiceAdaptedGateway"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:service-activator&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:gateway&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="enrollmentServiceAdaptedGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;service-interface="com.l8mdv.sample.EnrollmentServiceGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;default-request-channel="adapted-gateway-request-channel"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;default-reply-timeout="6000"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="adapted-gateway-request-channel"&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #4070a0;"&gt;                 datatype="java.lang.String"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:dispatcher&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;task-executor="taskExecutor"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:channel&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The Service Activator bean (&lt;i&gt;enrollmentServiceGatewayHandler&lt;/i&gt;) deals with both null and exception responses from the adapted gateway (&lt;i&gt;enrollmentServiceAdaptedGateway&lt;/i&gt;), in the situation where these are generated a business response detailing the error is generated.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Spring Integration R2.1 Changes&lt;/b&gt;&lt;/div&gt;&lt;div&gt;async-executor on gateway spec&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-7310765468201181054?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/7310765468201181054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/02/spring-integration-gateways-nulls-reply.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/7310765468201181054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/7310765468201181054'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/02/spring-integration-gateways-nulls-reply.html' title='Spring Integration Gateways - Null Handling &amp; Timeouts'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-3955822677094144538</id><published>2012-01-30T11:12:00.000-08:00</published><updated>2012-02-08T07:38:12.953-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='input-channel'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='splitter'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='aggregator'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><title type='text'>Spring Integration - Splitter-Aggregator</title><content type='html'>Within Spring Integration, one form of EIP&amp;nbsp;&lt;i&gt;scatter-gather&lt;/i&gt; is provided by the &lt;i&gt;splitter &lt;/i&gt;and&lt;i&gt; aggregator&lt;/i&gt;&amp;nbsp;constructs. Semantics for both of these are pretty straight forward to understand, the splitter receives an input message and returns a list of objects that are each turned into first-class messages. Those messages get routed to message handlers following which they are aggregated as a list of input messages by an aggregator.&amp;nbsp;This pattern can be used successfully with fairly simple configuration.&lt;br /&gt;&lt;br /&gt;The following example works with trivial message processing taking place. It uses simple &lt;i&gt;one-fail-all-fail&lt;/i&gt; error handling semantics. This means that any errors occurring in one or both services will result in an exception being thrown back to the invoker.&lt;br /&gt;&lt;br /&gt;Having worked on projects that require a far more robust solution following partial failure, I've written another post that includes details regarding a design strategy to support that - A Robust Splitter Aggregator Strategy &amp;lt;URL&amp;gt;.&lt;br /&gt;&lt;br /&gt;Let's explore how this context configuration is working and what happens in circumstances where and exception is thrown by one of the services.&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt; 1&lt;br /&gt; 2&lt;br /&gt; 3&lt;br /&gt; 4&lt;br /&gt; 5&lt;br /&gt; 6&lt;br /&gt; 7&lt;br /&gt; 8&lt;br /&gt; 9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;br /&gt;33&lt;br /&gt;34&lt;br /&gt;35&lt;br /&gt;36&lt;br /&gt;37&lt;br /&gt;38&lt;br /&gt;39&lt;br /&gt;40&lt;br /&gt;41&lt;br /&gt;42&lt;br /&gt;43&lt;br /&gt;44&lt;br /&gt;45&lt;br /&gt;46&lt;br /&gt;47&lt;br /&gt;48&lt;br /&gt;49&lt;br /&gt;50&lt;br /&gt;51&lt;br /&gt;52&lt;br /&gt;53&lt;br /&gt;54&lt;br /&gt;55&lt;br /&gt;56&lt;br /&gt;57&lt;br /&gt;58&lt;br /&gt;59&lt;br /&gt;60&lt;br /&gt;61&lt;br /&gt;62&lt;br /&gt;63&lt;br /&gt;64&lt;br /&gt;65&lt;br /&gt;66&lt;br /&gt;67&lt;br /&gt;68&lt;br /&gt;69&lt;br /&gt;70&lt;br /&gt;71&lt;br /&gt;72&lt;br /&gt;73&lt;br /&gt;74&lt;br /&gt;75&lt;br /&gt;76&lt;br /&gt;77&lt;br /&gt;78&lt;br /&gt;79&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration/spring-integration-2.1.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Bean specifications.  --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;import&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;resource="bean-refs.xml"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Gateway specification. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:gateway&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;service-interface="com.l8mdv.sample.gateway.BrokerRequestGateway"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="broker-request-channel"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;datatype="com.l8mdv.sa.BrokerRequestMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Request message splitter. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:splitter&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="broker-request-channel"&lt;/span&gt;&lt;br /&gt;                  &lt;span style="color: #4070a0;"&gt;output-channel="broker-router-channel"&lt;/span&gt;&lt;br /&gt;                  &lt;br /&gt;                  &lt;span style="color: #4070a0;"&gt;ref="brokerQuoteRequestSplitter"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Request message routing. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="broker-router-channel"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;datatype="com.l8mdv.sa.BrokerQuoteRequestMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:recipient-list-router&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="broker-router-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:recipient&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;channel="openex-broker-channel"&lt;/span&gt;&lt;br /&gt;                       &lt;span style="color: #4070a0;"&gt;selector-expression="payload.BrokerName.equals('openex')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:recipient&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;channel="yahoo-broker-channel"&lt;/span&gt;&lt;br /&gt;                       &lt;span style="color: #4070a0;"&gt;selector-expression="payload.BrokerName.equals('yahoo')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:recipient-list-router&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Request message routing to OpenEx. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="openex-broker-channel"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;datatype="com.l8mdv.sa.BrokerQuoteRequestMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="openex-broker-channel"&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #4070a0;"&gt;output-channel="aggregator-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="OpenExServiceFaker"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sample.ServiceFaker"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="response"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;ref="OpenExFakeResponseData"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:service-activator&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Request message routing to Yahoo. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="yahoo-broker-channel"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;datatype="com.l8mdv.sa.BrokerQuoteRequestMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="yahoo-broker-channel"&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #4070a0;"&gt;output-channel="aggregator-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="YahooServiceFaker"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sample.ServiceFaker"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="response"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;ref="YahooFakeResponseData"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:service-activator&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- Response message handling, return the best --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!-- quote to the invoker. --&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #60a0b0; font-style: italic;"&gt;&amp;lt;!--##############################################--&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="aggregator-channel"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;datatype="com.l8mdv.sa.BrokerQuoteResponseMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="aggregator-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:aggregator/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:transformer&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;ref="aggregationToBrokerQuoteResponseTransformer"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;Regarding the &lt;i&gt;splitter&lt;/i&gt; and &lt;i&gt;aggregator&lt;/i&gt;, the interesting configuration starts at line 25 with the &lt;i&gt;splitter&lt;/i&gt; specification. The construct has been customised with &lt;i&gt;input-channel&lt;/i&gt;, &lt;i&gt;output-channel&lt;/i&gt;&amp;nbsp;and &lt;i&gt;ref&lt;/i&gt; attributes. The channel configuration for this construct is obvious, the other attribute allows association of a bean reference that is able to perform the split function. It's generally true that a splitter bean with appropriate arguments and return types will be invoked if it's unambiguous.&lt;br /&gt;&lt;br /&gt;The next stop for messages is the router that's defined on line 35, the recipient list router. This message endpoint is able to forward route messages into appropriate channels given an expression to invoke on the payload of the message. This router will examine the payload and route each message to one of two services - these are located on lines 48 and 62. The service(s) that are invoked are entirely dependent on what is returned from the splitter. Either or both of these services may be invoked for a given splitter input message.&lt;br /&gt;&lt;br /&gt;Finally, results of one or two service invocations are routed towards the aggregator, the configuration starts for this at the &lt;i&gt;chain&lt;/i&gt; defined at line 74. Finally the result of the aggregation is input to a transformer where some further processing takes place. Notice that there is no output channel on this chain, the implicitly created default output channel is relied upon here - it goes back through the gateway to the gateway invoker.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;There are some interesting aspects to this service:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If the &lt;i&gt;splitter&lt;/i&gt; at line 25 receives a message but does not generate a list of one or more response messages, then an empty list will result on the router not getting called. This can be overridden by using the &lt;i&gt;requires-reply&lt;/i&gt; attribute in which case an empty list will result in a message handling exception being thrown.&lt;/li&gt;&lt;li&gt;Strong typing has been used on the data channels in an attempt to enforce strict processing rules and make the configuration easier to follow and understand.&lt;/li&gt;&lt;li&gt;The &lt;i&gt;chain&lt;/i&gt; construct has been used in an attempt to keep configuration compact where useful. It should be noticed that chain definition and strong typing are often two sides of the same coin. By grouping the aggregator and transformer in a chain I have been unable to control and hence document message type input to the transformer endpoint.&lt;/li&gt;&lt;li&gt;Spring beans referenced from within this context have been loaded from an external file. Whilst they could have been component-scanned or defined in the same file I have chosen to keep them distinct in order that they are not loaded if not necessary for operation - I'd usually create mock and spy objects around these message endpoints.&lt;/li&gt;&lt;li&gt;Any exception in Service Activator invocation at lines 48 and 62 would result in aggregation not completing. In this example, I have not created an error handler on the gateway in line 18 and so any exceptions thrown by SAs would result in an exception being thrown to the invoker of the gateway. A more robust solution, in the face of exception handling, would require a different design approach.&lt;/li&gt;&lt;li&gt;I have documented, albeit briefly, intent for each section of the configuration specifically in order to help readers understand intentions of my design.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;In the case that they're useful, Spring bean definitions are as follows:&lt;/div&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:util="http://www.springframework.org/schema/util"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="brokerQuoteRequestSplitter"&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sample.service.BrokerQuoteRequestSplitter"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="brokerRawResponseTransformer"&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sample.service.impl.BrokerRawResponseTransformer"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="aggregationToBrokerQuoteResponseTransformer"&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sample.service.impl.AggregationToBrokerQuoteResponseTransformer"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="YahooFakeResponseData"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sa.BrokerResponseMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="brokerName"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;value="Yahoo"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="value"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;value="2"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="brokerRequestType"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;value="#{T(com.l8mdv.sa.BrokerRequestType).QUOTE}"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="OpenExFakeResponseData"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;class="com.l8mdv.sa.BrokerResponseMessage"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="brokerName"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;value="OpenEx"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="value"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;value="5"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;property&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;name="brokerRequestType"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;value="#{T(com.l8mdv.sa.BrokerRequestType).QUOTE}"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The splitter code:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;service&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerQuoteRequestMessage&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerRequest&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerRequestMessage&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.QuoteRequestSortPolicy&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.util.Assert&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;java.util.ArrayList&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;java.util.List&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;BrokerQuoteRequestSplitter&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; List&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;BrokerQuoteRequestMessage&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; split&lt;span style="color: #666666;"&gt;(&lt;/span&gt;BrokerRequestMessage message&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        Assert&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;notNull&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;message&lt;span style="color: #666666;"&gt;,&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"Mandatory argument missing."&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;        List requests &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;new&lt;/span&gt; ArrayList&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #666666;"&gt;(&lt;/span&gt;BrokerRequest &lt;span style="color: #002070; font-weight: bold;"&gt;brokerRequest:&lt;/span&gt;&lt;br /&gt;                message&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getBrokerRequest&lt;/span&gt;&lt;span style="color: #666666;"&gt;())&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;            BrokerQuoteRequestMessage brokerQuoteRequestMessage&lt;br /&gt;                    &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;new&lt;/span&gt; BrokerQuoteRequestMessage&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;            brokerQuoteRequestMessage&lt;br /&gt;                    &lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;setBrokerName&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;brokerRequest&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getBrokerName&lt;/span&gt;&lt;span style="color: #666666;"&gt;());&lt;/span&gt;&lt;br /&gt;            brokerQuoteRequestMessage&lt;br /&gt;                    &lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;setQuoteRequestSortPolicy&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;QuoteRequestSortPolicy&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;BUY_LOWEST&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;            requests&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;add&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;brokerQuoteRequestMessage&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold;"&gt;return&lt;/span&gt; requests&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The transformer:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;service&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;impl&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerQuoteResponseMessage&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.util.Assert&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;java.util.List&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;AggregationToBrokerQuoteResponseTransformer&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; BrokerQuoteResponseMessage&lt;br /&gt;    &lt;span style="color: #06287e;"&gt;transform&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;List&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;BrokerQuoteResponseMessage&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; serviceResponses&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        Assert&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;notNull&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;serviceResponses&lt;span style="color: #666666;"&gt;,&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"Mandatory argument missing."&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        BrokerQuoteResponseMessage bestQuote &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #666666;"&gt;(&lt;/span&gt;BrokerQuoteResponseMessage &lt;br /&gt;                &lt;span style="color: #002070; font-weight: bold;"&gt;brokerQuoteResponseMessage:&lt;/span&gt; serviceResponses&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #666666;"&gt;(&lt;/span&gt;bestQuote &lt;span style="color: #666666;"&gt;==&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;                bestQuote &lt;span style="color: #666666;"&gt;=&lt;/span&gt; brokerQuoteResponseMessage&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #007020; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #666666;"&gt;(&lt;/span&gt;brokerQuoteResponseMessage&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getSellPrice&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt;&lt;br /&gt;                        &lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;compareTo&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;bestQuote&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getSellPrice&lt;/span&gt;&lt;span style="color: #666666;"&gt;())&lt;/span&gt; &lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;                    bestQuote &lt;span style="color: #666666;"&gt;=&lt;/span&gt; brokerQuoteResponseMessage&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold;"&gt;return&lt;/span&gt; bestQuote&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;and the integration test:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerQuoteResponseMessage&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerRequest&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerRequestMessage&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sa.BrokerRequestType&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;com.l8mdv.sample.gateway.BrokerRequestGateway&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.Assert&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.Test&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.runner.RunWith&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.test.context.ContextConfiguration&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.test.context.junit4.SpringJUnit4ClassRunner&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #555555; font-weight: bold;"&gt;@RunWith&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;SpringJUnit4ClassRunner&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;class&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #555555; font-weight: bold;"&gt;@ContextConfiguration&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;br /&gt;    locations &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;"classpath:META-INF/spring/simple-splitter-aggregator.xml"&lt;/span&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;SimpleSplitterAggregatorIntegrationTest&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Autowired&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; BrokerRequestGateway brokerRequestGateway&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Test&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #902000;"&gt;void&lt;/span&gt; &lt;span style="color: #06287e;"&gt;run&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;throws&lt;/span&gt; Exception &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        BrokerRequestMessage requestMessage &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;new&lt;/span&gt; BrokerRequestMessage&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        BrokerRequest yahooRequest &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;new&lt;/span&gt; BrokerRequest&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;        yahooRequest&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;setBrokerName&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;"yahoo"&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;        yahooRequest&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;setBrokerRequestType&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;BrokerRequestType&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;QUOTE&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;        requestMessage&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getBrokerRequest&lt;/span&gt;&lt;span style="color: #666666;"&gt;().&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;add&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;yahooRequest&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        BrokerRequest oxRequest &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;new&lt;/span&gt; BrokerRequest&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;        oxRequest&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;setBrokerName&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;"openex"&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;        oxRequest&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;setBrokerRequestType&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;BrokerRequestType&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;QUOTE&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;        requestMessage&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getBrokerRequest&lt;/span&gt;&lt;span style="color: #666666;"&gt;().&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;add&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;oxRequest&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        BrokerQuoteResponseMessage response &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;br /&gt;           brokerRequestGateway&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;send&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;requestMessage&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Resources:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://static.springsource.org/spring-integration/reference/html/overview.html#overview-endpoints-splitter"&gt;Spring Integration Reference Manual - Splitter Overview&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-3955822677094144538?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/3955822677094144538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-splitter-aggregator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/3955822677094144538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/3955822677094144538'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-splitter-aggregator.html' title='Spring Integration - Splitter-Aggregator'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-339189380013165700</id><published>2012-01-23T21:50:00.000-08:00</published><updated>2012-01-30T02:09:54.369-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='input-channel'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Spring Integration - Input Channel Definition</title><content type='html'>In a pipes and filters architecture, pipes are connectors or channels. Although at first sight trivial, channels are fairly rich semantically - they allow typing, synchronous and asynchronous input, direct and multicast notifications, send and wait (rendezvous) as well as queued input and wrapping by adapters.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;To define or not to define?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Explicit specification or definition of the Spring Integration &lt;i&gt;input-channel&lt;/i&gt;&amp;nbsp;is not mandatory for SI constructs to operate. The framework will create input channels automatically if they are not explicitly defined in configuration, but what are the pros and cons of this aproach?&lt;br /&gt;&lt;br /&gt;Take the following chain as an example:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="processing-channel"&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: #4070a0;"&gt;output-channel="claim-check-out-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;expression="new String('different string')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The &lt;i&gt;input-channel&lt;/i&gt; named "processing-channel" will get created automatically as it's not explicitly defined here. In a trivial configuration such as this one there's very little difference between including the channel explicitly or using the frameworks implicit creation. In larger configurations the extra lines taken by a dozen or more channel definitions may start to make the context appear a little cluttered. In this case it's then possible to consider decomposing the configuration but sometimes you just can't decompose those flows into distinct contexts, all of the constructs naturally belong together in a single context.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Channel Typing&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;One of the features of Spring Integration channels is that they can be strongly type matched with payload object types. It's worth considering adopting a convention for specifying the payload type on the channel because not only does this provide strong payload typing but improved better confidence that whomever is reading the flow after its built can readily see which type of objects are traversing the flows.&lt;br /&gt;&lt;br /&gt;Of course channels can't always be strongly typed but in many cases they can. Here's an example of one that can:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="processing-channel"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;datatype="java.util.UUID"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="processing-channel"&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: #4070a0;"&gt;output-channel="claim-check-out-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;expression="new String('different string')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;You can see that on the first line of this Spring Integration configuration the contract for operation specifies that a java.util.UUID type object is expected on the input channel. In this case the payload contained a &lt;i&gt;claim-check&lt;/i&gt; identifier and is to be replaced with an arbitrary string for the example.&lt;br /&gt;&lt;br /&gt;In the case where a channel is strongly typed and the contract broken an exception will be thrown, here's an example of what you'll see:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;org&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;springframework&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;integration&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;MessageDeliveryException&lt;/span&gt;&lt;span style="color: #666666;"&gt;:&lt;/span&gt; &lt;br /&gt;Channel &lt;span style="border-bottom-color: rgb(255, 0, 0); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 0, 0); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 0, 0); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(255, 0, 0); border-top-style: solid; border-top-width: 1px;"&gt;'&lt;/span&gt;processing&lt;span style="color: #666666;"&gt;-&lt;/span&gt;channel&lt;span style="border-bottom-color: rgb(255, 0, 0); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(255, 0, 0); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 0, 0); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(255, 0, 0); border-top-style: solid; border-top-width: 1px;"&gt;'&lt;/span&gt; expected one of the following datataypes &lt;br /&gt;&lt;span style="color: #666666;"&gt;[&lt;/span&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;interface&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;java&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;util&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;Map&lt;/span&gt;&lt;span style="color: #666666;"&gt;],&lt;/span&gt; &lt;br /&gt;but received &lt;span style="color: #666666;"&gt;[&lt;/span&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;java&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;util&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;UUID&lt;/span&gt;&lt;span style="color: #666666;"&gt;]&lt;/span&gt;&lt;br /&gt; at org&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;springframework&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;integration&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;channel&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;AbstractMessageChannel&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;convertPayloadIfNecessary&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;AbstractMessageChannel&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;java&lt;/span&gt;&lt;span style="color: #666666;"&gt;:&lt;/span&gt;&lt;span style="color: #40a070;"&gt;187&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In this example I changed the datatype to java.util.Map and ran a test with a payload that's actually a java.util.UUID. That was the start of the stack trace that was generated when the exception was thrown.&lt;br /&gt;&lt;br /&gt;It's possible to provide a collection of message types for channel specification. Any messages entering the channel must conform to at least one of the specified types otherwise a &lt;i&gt;MessageDeliveryException&lt;/i&gt; is generated. The following example shows a change that will prevent the exception above. The configuration now allows for two types of message payload, &lt;i&gt;java.util.Map&lt;/i&gt; and &lt;i&gt;java.util.UUID &lt;/i&gt;to enter the channel.&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:channel&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="processing-channel"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;datatype="java.util.UUID, java.util.Map"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="processing-channel"&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #4070a0;"&gt;output-channel="claim-check-out-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;expression="new String('different string')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Sources&lt;/b&gt;&lt;br /&gt;&lt;a href="http://static.springsource.org/spring-integration/reference/html/overview.html#overview-components-channel"&gt;Spring Integration Reference Manual - Message Channels&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-339189380013165700?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/339189380013165700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-input-channel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/339189380013165700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/339189380013165700'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-input-channel.html' title='Spring Integration - Input Channel Definition'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-2197938551814435531</id><published>2012-01-23T20:35:00.000-08:00</published><updated>2012-01-23T22:19:43.923-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='claim-check'/><title type='text'>Spring Integration - Transforming a Header Object to a Payload</title><content type='html'>Moving objects from the Spring Integration header can be done using several mechanisms. Firstly, a transformer construct can be used:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: gray; border-bottom-style: solid; border-left-color: gray; border-left-style: solid; border-right-color: gray; border-right-style: solid; border-top-color: gray; border-top-style: solid; border-width: initial; overflow-x: auto; overflow-y: auto; padding-bottom: 0.2em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.2em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="request-message-retrieval-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:transformer&lt;/span&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #4070a0;"&gt;expression="headers.get(T(com.l8mdv.sample.HeaderManagementGateway)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;      .REQUEST_PAYLOAD_HEADER_KEY)"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Secondly, the same action can be performed using a Service Activator:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: gray; border-bottom-style: solid; border-left-color: gray; border-left-style: solid; border-right-color: gray; border-right-style: solid; border-top-color: gray; border-top-style: solid; border-width: initial; overflow-x: auto; overflow-y: auto; padding-bottom: 0.2em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.2em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="request-message-retrieval-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #4070a0;"&gt;expression="headers.get(T(com.l8mdv.sample.HeaderManagementGateway)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="color: black; line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;       .REQUEST_PAYLOAD_HEADER_KEY)"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Here's a claim-check retrieval - notice the configuration option that triggers the Spring Integration framework to remove the object from the message store once it has been retrieved. If a message requires access several times in a flow, the last claim-check-out can be configured in this way in order to clean-up.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: gray; border-bottom-style: solid; border-left-color: gray; border-left-style: solid; border-right-color: gray; border-right-style: solid; border-top-color: gray; border-top-style: solid; border-width: initial; overflow-x: auto; overflow-y: auto; padding-bottom: 0.2em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.2em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="claim-check-out-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:transformer&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: #4070a0;"&gt;expression="headers&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;.get('#{T(com.l8mdv.sample.ClaimCheckGateway)&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;.CLAIM_CHECK_ID}')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:claim-check-out&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;message-store="simpleMessageStore"&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;                       remove-message="true"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Several interesting points arise:&lt;br /&gt;&lt;list&gt;&lt;/list&gt;&lt;ol&gt;&lt;li&gt;As can be seen here, it's advisable to reference constants for header key values rather than have the header name appearing as literals in several places throughout the code and configuration. On first sight the SpEL expression language may seem hard to fathom but it's worth investing the effort in order to understand it.&lt;/li&gt;&lt;li&gt;Don't forget that when header objects are moved back into Spring Integration payloads, the object remains in the Spring Integration message header. It may be worth clearing the header value away as part of transformation from the header back to the payload in order to maintain a cleaner and clearer Spring Integration message.&lt;/li&gt;&lt;li&gt;The intent should be clear from the configuration, what looks better a &lt;i&gt;Service Activator&lt;/i&gt; expression or a &lt;i&gt;Transformer&lt;/i&gt;? In my view the transformer conveys a slightly more accurate intent.&lt;/li&gt;&lt;li&gt;Consider using a &lt;i&gt;claim-check&lt;/i&gt; integration pattern instead of loading the header. The Spring Integration &lt;i&gt;claim-check&lt;/i&gt; uses a referenced message store (and provides a default implementation) that can be house-cleaned automatically by the framework.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-2197938551814435531?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/2197938551814435531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-transforming-header.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/2197938551814435531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/2197938551814435531'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-transforming-header.html' title='Spring Integration - Transforming a Header Object to a Payload'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-6400603185003935473</id><published>2012-01-21T19:36:00.000-08:00</published><updated>2012-01-23T21:53:23.706-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='claim-check'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><title type='text'>Spring Integration - Payload Storage via Claim-check</title><content type='html'>Continuing on the theme of temporary storage for transient messages used within Spring Integration flows, the claim-check model offers configurable storage for message payloads. The advantage in using this Enterprise Integration pattern, compared against &lt;i&gt;header enrichment,&lt;/i&gt; is that objects don't have to be packed into the header using a&amp;nbsp;&lt;a href="http://techiquest.blogspot.com/2012/01/spring-integration-payload-storage-via.html"&gt;Header Enrichment&lt;/a&gt;&amp;nbsp;technique. They can be stored in a local Java Map, an IMDB, cache or anything else that be used to hold data.&lt;br /&gt;&lt;br /&gt;Several advantages using this approach are evident. Firstly, performance and efficiency. When using&amp;nbsp;&lt;i&gt;header enrichment,&lt;/i&gt; if message payloads need to be managed outside of the JVM that generates the enriched message header, the object will not be available unless it's serialised and transported around the distributed application. This could be costly in terms of performance and transport efficiency. The key factor here is the frequency of remote dispatch and the size of the header object.&amp;nbsp;In specific circumstances the claim-check pattern may offer an advantage here, objects can be serialised and/or transformed into a storage specific format and stored internally in memory or externally in a data store.&lt;br /&gt;&lt;br /&gt;Secondly, accessibility. It's conceivable that message payloads undergoing claim-check processing may need to be accessed by third party applications that are unable to receive Spring Integration messages. The claim-check pattern allows this type of processing to take place.&lt;br /&gt;&lt;br /&gt;Thirdly, resiliency is offered.&amp;nbsp;A data store can be chosen that guarantees persistence for messages in order that they can be recovered following failure.&lt;br /&gt;&lt;br /&gt;The following code details how the &lt;i&gt;claim-check&lt;/i&gt; pattern can be used:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration/spring-integration-2.1.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;bean&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="simpleMessageStore"&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #4070a0;"&gt;class="org.springframework.integration.store.SimpleMessageStore"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:gateway&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;id="claimCheckGateway"&lt;/span&gt;&lt;br /&gt;                 &lt;span style="color: #4070a0;"&gt;service-interface="com.l8mdv.sample.ClaimCheckGateway"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="claim-check-in-channel"&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #4070a0;"&gt;output-channel="processing-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:claim-check-in&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;message-store="simpleMessageStore"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:header-enricher&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:header&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #4070a0;"&gt;                name="#{T(com.l8mdv.sample.ClaimCheckGateway).CLAIM_CHECK_ID}"&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #4070a0;"&gt;expression="payload"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:header-enricher&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="processing-channel"&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #4070a0;"&gt;output-channel="claim-check-out-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:service-activator&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;expression="new String('different string')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="claim-check-out-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:transformer&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #4070a0;"&gt;expression="headers.get('#{T(com.l8mdv.sample.ClaimCheckGateway)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;                .CLAIM_CHECK_ID}')"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:claim-check-out&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;message-store="simpleMessageStore"&lt;/span&gt;&lt;br /&gt;                             &lt;span style="color: #4070a0;"&gt;remove-message="true"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The gateway used is specified as the following Java class:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.Message&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.annotation.Gateway&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;interface&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;ClaimCheckGateway&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;static&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;final&lt;/span&gt; String CLAIM_CHECK_ID &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"CLAIM_CHECK_ID"&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Gateway&lt;/span&gt; &lt;span style="color: #666666;"&gt;(&lt;/span&gt;requestChannel &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"claim-check-in-channel"&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; send&lt;span style="color: #666666;"&gt;(&lt;/span&gt;Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; message&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Lastly, this can all be tested by using the following JUnit test case:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.Assert&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.Test&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.runner.RunWith&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.Message&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.support.MessageBuilder&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.test.context.ContextConfiguration&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.test.context.junit4.SpringJUnit4ClassRunner&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;static&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;ClaimCheckGateway&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;CLAIM_CHECK_ID&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #555555; font-weight: bold;"&gt;@RunWith&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;SpringJUnit4ClassRunner&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;class&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #555555; font-weight: bold;"&gt;@ContextConfiguration&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;&lt;br /&gt;    locations &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;"classpath:META-INF/spring/claim-check.xml"&lt;/span&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;ClaimCheckIntegrationTest&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Autowired&lt;/span&gt; ClaimCheckGateway claimCheckGateway&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Test&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #902000;"&gt;void&lt;/span&gt; &lt;span style="color: #06287e;"&gt;locatePayloadInHeader&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        String payload &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"Sample test message."&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;        Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; message &lt;span style="color: #666666;"&gt;= &lt;/span&gt;MessageBuilder&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;withPayload&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;payload&lt;span style="color: #666666;"&gt;).&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;build&lt;/span&gt;&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;        Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; response &lt;span style="color: #666666;"&gt;= &lt;/span&gt;claimCheckGateway&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;send&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;message&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        Assert&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;assertTrue&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;response&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getPayload&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;equals&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;payload&lt;span style="color: #666666;"&gt;));&lt;/span&gt;&lt;br /&gt;        Assert&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;assertTrue&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;response&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getHeaders&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;get&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;CLAIM_CHECK_ID&lt;span style="color: #666666;"&gt;)&lt;/span&gt; &lt;span style="color: #666666;"&gt;!=&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-6400603185003935473?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/6400603185003935473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-payload-storage-via_21.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/6400603185003935473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/6400603185003935473'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-payload-storage-via_21.html' title='Spring Integration - Payload Storage via Claim-check'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-4266281257832732917</id><published>2012-01-21T08:27:00.000-08:00</published><updated>2012-01-23T22:17:51.986-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring Integration'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><title type='text'>Spring Integration - Payload Storage via Header Enrichment</title><content type='html'>There's often a need to &lt;i&gt;temporarily&lt;/i&gt; store &lt;i&gt;transient&lt;/i&gt; messages during design of Spring Integration flows - several different mechanisms are available in the toolkit.&lt;br /&gt;&lt;br /&gt;It's pretty straight forward to take a message, use an SI header enricher construct and place the message in the header using a SpEL expression - in fact one for the header key name and one for the payload extraction.&lt;br /&gt;&lt;br /&gt;The following SI flow demonstrates an example of how to do just that :&lt;br /&gt;&lt;br /&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: gray; border-bottom-style: solid; border-left-color: gray; border-left-style: solid; border-right-color: gray; border-right-style: solid; border-top-color: gray; border-top-style: solid; border-width: initial; overflow-x: auto; overflow-y: auto; padding-bottom: 0.2em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.2em; width: auto;"&gt;&lt;pre style="color: black; line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #007020;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;beans&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;xmlns="http://www.springframework.org/schema/beans"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xmlns:int="http://www.springframework.org/schema/integration"&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: #4070a0;"&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="color: black; line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/beans/spring-beans.xsd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="color: black; line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;       http://www.springframework.org/schema/integration/spring-integration-2.1.xsd"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;  &amp;lt;int:gateway &lt;span style="color: #4070a0;"&gt;id="headerManagementGateway"&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="color: black; line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;                 service-interface="com.l8mdv.sample.HeaderManagementGateway"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="request-message-storage-channel"&lt;/span&gt;&lt;br /&gt;             &lt;span style="color: #4070a0;"&gt;output-channel="request-message-retrieval-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:header-enricher&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:header&lt;/span&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #4070a0;"&gt;name="#{T(com.l8mdv.sample.HeaderManagementGateway)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;                   .REQUEST_PAYLOAD_HEADER_KEY}"&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;expression="getPayload()"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:header-enricher&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:chain&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;input-channel="request-message-retrieval-channel"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;int:transformer&lt;/span&gt;&amp;nbsp;&lt;span style="color: #4070a0;"&gt;expression="headers&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;.get(T(com.l8mdv.sample.HeaderManagementGateway)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="color: black; line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="color: #4070a0;"&gt;               .REQUEST_PAYLOAD_HEADER_KEY)"&lt;/span&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: 125%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;  &lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/int:chain&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #062873; font-weight: bold;"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This example can be executed by implementing a gateway as follows:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.Message&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.annotation.Gateway&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;interface&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;HeaderManagementGateway&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;static&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;final&lt;/span&gt; String REQUEST_PAYLOAD_HEADER_KEY &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"REQUEST_PAYLOAD_HEADER_KEY"&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Gateway&lt;/span&gt; &lt;span style="color: #666666;"&gt;(&lt;/span&gt;requestChannel &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"request-message-storage-channel"&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; send&lt;span style="color: #666666;"&gt;(&lt;/span&gt;Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; message&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;and then running a test such as this one:&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;package&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.Assert&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.Test&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.junit.runner.RunWith&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.Message&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.integration.support.MessageBuilder&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.test.context.ContextConfiguration&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;org.springframework.test.context.junit4.SpringJUnit4ClassRunner&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;static&lt;/span&gt; com&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;l8mdv&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;sample&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;HeaderManagementGateway&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;REQUEST_PAYLOAD_HEADER_KEY&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #555555; font-weight: bold;"&gt;@RunWith&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;SpringJUnit4ClassRunner&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;class&lt;/span&gt;&lt;span style="color: #666666;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #555555; font-weight: bold;"&gt;@ContextConfiguration&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;locations &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;"classpath:META-INF/spring/header-management.xml"&lt;/span&gt;&lt;span style="color: #666666;"&gt;})&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold;"&gt;HeaderManagementIntegrationTest&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Autowired&lt;/span&gt;&lt;br /&gt;    HeaderManagementGateway headerManagementGateway&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Test&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #902000;"&gt;void&lt;/span&gt; &lt;span style="color: #06287e;"&gt;locatePayloadInHeader&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        String payload &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"Sample test message."&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;        Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; message &lt;span style="color: #666666;"&gt;=&lt;/span&gt; MessageBuilder&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;withPayload&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;payload&lt;span style="color: #666666;"&gt;).&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;build&lt;/span&gt;&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;        Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; response &lt;span style="color: #666666;"&gt;=&lt;/span&gt; headerManagementGateway&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;send&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;message&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        Assert&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;assertTrue&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;response&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getHeaders&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;get&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;REQUEST_PAYLOAD_HEADER_KEY&lt;span style="color: #666666;"&gt;).&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;equals&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;payload&lt;span style="color: #666666;"&gt;));&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #555555; font-weight: bold;"&gt;@Test&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #902000;"&gt;void&lt;/span&gt; &lt;span style="color: #06287e;"&gt;locateTransformedPayload&lt;/span&gt;&lt;span style="color: #666666;"&gt;()&lt;/span&gt; &lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;        String payload &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0;"&gt;"Sample test message."&lt;/span&gt;&lt;span style="color: #666666;"&gt;;&lt;/span&gt;&lt;br /&gt;        Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; message &lt;span style="color: #666666;"&gt;=&lt;/span&gt; MessageBuilder&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;withPayload&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;payload&lt;span style="color: #666666;"&gt;).&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;build&lt;/span&gt;&lt;span style="color: #666666;"&gt;();&lt;/span&gt;&lt;br /&gt;        Message&lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; response &lt;span style="color: #666666;"&gt;=&lt;/span&gt; headerManagementGateway&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;send&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;message&lt;span style="color: #666666;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        Assert&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;assertTrue&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;response&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;getPayload&lt;/span&gt;&lt;span style="color: #666666;"&gt;().&lt;/span&gt;&lt;span style="color: #4070a0;"&gt;contains&lt;/span&gt;&lt;span style="color: #666666;"&gt;(&lt;/span&gt;payload&lt;span style="color: #666666;"&gt;));&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;For full source code and configuration, see the header-management maven module under git://github.com/L8MDV/l8mdv-si-samples.git&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-4266281257832732917?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/4266281257832732917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-payload-storage-via.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/4266281257832732917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/4266281257832732917'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/01/spring-integration-payload-storage-via.html' title='Spring Integration - Payload Storage via Header Enrichment'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2357504012170207916.post-3870034995459063850</id><published>2012-01-13T04:49:00.000-08:00</published><updated>2012-01-23T21:22:31.585-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='backout'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='recovery'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Subversion Commit Revert</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: large;"&gt;Subversion Commit Backout [&lt;i&gt;svn merge -c&lt;/i&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Use:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step one&lt;/b&gt;, perform a local merge with the previous version. Ensure that any work after the commit being reverted-to is saved as it will be overwritten by the merge.&lt;br /&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;svn merge &lt;span style="color: #666666;"&gt;-&lt;/span&gt;c &lt;span style="color: #666666;"&gt;-&amp;lt;&lt;/span&gt;commit&lt;span style="color: #666666;"&gt;-&lt;/span&gt;version&lt;span style="color: #666666;"&gt;-&lt;/span&gt;to&lt;span style="color: #666666;"&gt;-&lt;/span&gt;revert&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #666666;"&gt;&amp;lt;&lt;/span&gt;repo&lt;span style="color: #666666;"&gt;-&lt;/span&gt;url&lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;b&gt;Step two&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;, commit the reverted code with an appropriate commit message.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="background: #f0f0f0; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;"&gt;&lt;pre style="line-height: 125%; margin: 0;"&gt;svn commit &lt;span style="color: #666666;"&gt;-&lt;/span&gt;m &lt;span style="color: #4070a0;"&gt;"Reverting commit [bad-commit-version] to previous version"&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;b&gt;Note:- &lt;/b&gt;If any further commits take place between the initial check-in and the merge revert there will be further work to do&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2357504012170207916-3870034995459063850?l=techiquest.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://techiquest.blogspot.com/feeds/3870034995459063850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://techiquest.blogspot.com/2012/01/subversion-commit-backout-svn-merge-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/3870034995459063850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2357504012170207916/posts/default/3870034995459063850'/><link rel='alternate' type='text/html' href='http://techiquest.blogspot.com/2012/01/subversion-commit-backout-svn-merge-c.html' title='Subversion Commit Revert'/><author><name>Matt Vickery</name><uri>http://www.blogger.com/profile/03127294834455141751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/-U5qhkHKI4PE/Tx16pbX2TMI/AAAAAAAAAa0/gtn4MhZpsJ8/s1600/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
