INT-2269 Add ReplyChannelRegistry

Allows reply channel resolution after a message has been serialized
somewhere in a flow. Previously, the reply channel was lost.

With this change, the reply channel can be registered and the header
becomes a string (channel name) that can be serialized.

JIRA: https://jira.springsource.org/browse/INT-2269

INT-2269 Rename Registry to HeaderChannelRegistry

- Extract interface
- DefaultHeaderChannelRgistry

INT-2269 Polishing; PR Comments

- Add errorChannel registration as well.

INT-2269 HeaderChannelRegistry - Fix

The internal BridgeHandler in MessagingGatewaySupport did not have
a channel resolver. When a reply was explicitly routed to the gateway's
reply channel, the String representation of the reply channel could
not be resolved to a channel.

Set the BeanFactory on the bridge handler.

Add tests.

INT-2269 HeaderChannelRegistry - Fix JMS/Enricher

The JMS inbound gateway and ContentEnricher instantiate a
MessagingGatewaySupport internally it does not get a
reference to the BeanFactory. This means that the internal
BridgeHandler cannot resolve the String representation of
the reply channel to a channel.

Make ChannelPublishingJmsMessageListener BeanFactory aware, and
propagate the bean factory to the MGS.

Set the MGS bean factory in the ContentEnricher (which is already
BFA).

INT-2269: Polishing
This commit is contained in:
Gary Russell
2013-11-15 15:21:44 +02:00
committed by Artem Bilan
parent 1d0c28852f
commit 836c8e2556
21 changed files with 1060 additions and 185 deletions

View File

@@ -73,10 +73,10 @@
using generic <emphasis>&lt;header&gt;</emphasis> sub-elements where
you would have to provide both header 'name' and 'value', you can use
convenient sub-elements to set those values directly.
</para>
</para>
<para>
<emphasis>POJO Support</emphasis>
<emphasis role="bold">POJO Support</emphasis>
</para>
<para>
@@ -121,7 +121,7 @@
</int:header-enricher>]]></programlisting>
<para>
<emphasis>SpEL Support</emphasis>
<emphasis role="bold">SpEL Support</emphasis>
</para>
<para>
In Spring Integration 2.0 we have introduced the convenience of the
@@ -147,6 +147,51 @@
are bound to the SpEL Evaluation Context, giving you full access to
the incoming Message.
</para>
<para><emphasis role="bold">Header Channel Registry</emphasis></para>
<para>
Starting with <emphasis>Spring Integration 3.0</emphasis>, a new sub-element
<code>&lt;int:header-channels-to-string/&gt;</code> is available; it has no attributes.
This converts existing <code>replyChannel</code> and <code>errorChannel</code>
headers (when they are a
<classname>MessageChannel</classname>) to a String and stores the channel(s) in
a registry for later resolution when it is time to send a reply, or handle an error.
This is useful
for cases where the headers might be lost; for example when
serializing a message into a message store or when transporting the message
over JMS. If the header does not already exist, or it
is not a <classname>MessageChannel</classname>, no changes are made.
</para>
<para>
Use of this functionality requires the presence of a <classname>HeaderChannelRegistry</classname>
bean. By default, the framework creates a <classname>DefaultHeaderChannelRegistry</classname>
with the default expiry (60 seconds). Channels
are removed from the registry after this time. To change this, simply define a bean
with id <code>integrationHeaderChannelRegistry</code> and configure the required delay using
a constructor argument (milliseconds).
</para>
<para>
The <classname>HeaderChannelRegistry</classname> has a <code>size()</code> method to
determine the current size of the registry. The <code>runReaper()</code> method
cancels the current scheduled task and runs the reaper immediately; the task is
then scheduled to run again based on the current delay. These methods can be invoked
directly by getting a reference to the registry, or you can send a message with, for example,
the following content to a control bus:
</para>
<programlisting><![CDATA["@integrationHeaderChannelRegistry.runReaper()"]]></programlisting>
<para>
This sub-element is a convenience only, and is the equivalent of specifying:
</para>
<programlisting language="xml"><![CDATA[<int:reply-channel
expression="@integrationHeaderChannelRegistry.channelToChannelName(headers.replyChannel)"/>
<int:error-channel
expression="@integrationHeaderChannelRegistry.channelToChannelName(headers.errorChannel)"/>]]></programlisting>
<tip>
For more examples for configuring header enrichers, see
<ulink url="https://github.com/SpringSource/spring-integration/wiki/Header-Enricher-Advanced-Configuration">

View File

@@ -75,21 +75,21 @@
For example, if one of the headers contains an instance of some <emphasis>Spring Bean</emphasis>, upon deserialization you may end
up with a different instance of that bean,
which directly affects some of the implicit headers created by the framework (e.g., REPLY_CHANNEL or ERROR_CHANNEL).
Currently they are not serializable, but even if they were the deserialized channel would not represent the expected instance.
As a workaround we suggest to remove bean-ref headers via a <literal>&lt;header-filter/&gt;</literal>
before sending a message to an endpoint backed by a persistent <classname>MessageStore</classname>.
Also, we recommend using channel names instead of channel instances when setting those types of headers,
thus allowing it to be resolved in real time by the <classname>ChannelResolver</classname>.
Currently they are not serializable, but even if they were, the deserialized channel would not represent the expected instance.
</para>
<para>
Also avoid configuration of a message-flow like this:
Beginning with <emphasis>Spring Integration version 3.0</emphasis>, this issue can be resolved with a header enricher,
configured to replace these headers with a name after registering the channel with the <classname>HeaderChannelRegistry</classname>.
</para>
<para>
Also when configuring a message-flow like this:
<emphasis>gateway -&gt; queue-channel (backed by a persistent Message Store) -&gt; service-activator</emphasis>
That gateway creates a <emphasis>Temporary Reply Channel</emphasis> in the background, and it will be lost by the time the
service-activator's poller reads from the queue, because it has been deserialized by another thread on the sending side.
That gateway creates a <emphasis>Temporary Reply Channel</emphasis>, and it will be lost by the time the
service-activator's poller reads from the queue. Again, you can use the header enricher to replace the headers with a
String representation.
</para>
<para>
Nevertheless we are constantly thinking about potential improvements to the framework, such as a way to provide some
robust default serialization strategy for messages in these cases.
For more information, refer to the <xref linkend="header-enricher"/>.
</para>
</important>
</para>

View File

@@ -166,6 +166,16 @@
For more information see <xref linkend="redis" />.
</para>
</section>
<section id="3.0-hcr">
<title>Header Channel Registry</title>
<para>
It is now possible to instruct the framework to store reply and error channels
in a registry for later resolution. This is useful for cases where
the <code>replyChannel</code> or <code>errorChannel</code> might be lost; for example
when serializing
a message. See <xref linkend="header-enricher"/> for more information.
</para>
</section>
</section>
<section id="3.0-general">