2069 lines
95 KiB
XML
2069 lines
95 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ip"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>TCP and UDP Support</title>
|
|
<para>
|
|
Spring Integration provides Channel Adapters for receiving and sending messages over internet protocols. Both UDP
|
|
(User Datagram Protocol)
|
|
and TCP (Transmission Control Protocol) adapters are provided. Each adapter provides for one-way communication
|
|
over the underlying protocol.
|
|
In addition, simple inbound and outbound tcp gateways are provided. These are used when two-way communication is
|
|
needed.
|
|
</para>
|
|
<section id="ip-intro">
|
|
<title>Introduction</title>
|
|
<para>
|
|
Two flavors each of UDP inbound and outbound channel adapters are provided <classname>UnicastSendingMessageHandler</classname>
|
|
sends a datagram packet to a single destination. <classname>UnicastReceivingChannelAdapter</classname> receives
|
|
incoming datagram packets. <classname>MulticastSendingMessageHandler</classname> sends (broadcasts) datagram packets to
|
|
a multicast address. <classname>MulticastReceivingChannelAdapter</classname> receives incoming datagram packets
|
|
by joining to a multicast address.
|
|
</para>
|
|
<para>
|
|
TCP inbound and outbound channel adapters are provided <classname>TcpSendingMessageHandler</classname>
|
|
sends messages over TCP. <classname>TcpReceivingChannelAdapter</classname> receives messages over TCP.
|
|
</para>
|
|
<para>
|
|
An inbound TCP gateway is provided; this allows for simple request/response processing. While
|
|
the gateway can support any number of connections, each connection can only process serially. The thread
|
|
that reads from the socket waits for, and sends, the response before reading again. If the connection factory
|
|
is configured for single use connections, the connection is closed after the socket times out.
|
|
</para>
|
|
<para>
|
|
An outbound TCP gateway is provided; this allows for simple request/response processing.
|
|
If the associated connection factory is configured for single use connections, a new connection is
|
|
immediately created for each new request. Otherwise, if the connection is in use,
|
|
the calling thread blocks on the connection until either a response is received or a timeout
|
|
or I/O error occurs.
|
|
</para>
|
|
<para>
|
|
The TCP and UDP inbound channel adapters, and the TCP inbound gateway, support the "error-channel" attribute.
|
|
This provides the same basic functionality as described in <xref linkend="gateway-proxy"/>.
|
|
</para>
|
|
</section>
|
|
<section id="udp-adapters">
|
|
<title>UDP Adapters</title>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:udp-outbound-channel-adapter id="udpOut"
|
|
host="somehost"
|
|
port="11111"
|
|
multicast="false"
|
|
channel="exampleChannel"/>]]></programlisting>
|
|
A simple UDP outbound channel adapter.
|
|
<tip>
|
|
When setting multicast to true, provide the multicast address in the host
|
|
attribute.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
UDP is an efficient, but unreliable protocol. Two attributes are added to improve reliability. When check-length is
|
|
set to true, the adapter precedes the message data with a length field (4 bytes in network byte order). This enables
|
|
the receiving side to verify the length of the packet received. If a receiving system uses a buffer that is too
|
|
short the contain the packet, the packet can be truncated. The length header provides a mechanism to detect this.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:udp-outbound-channel-adapter id="udpOut"
|
|
host="somehost"
|
|
port="11111"
|
|
multicast="false"
|
|
check-length="true"
|
|
channel="exampleChannel"/>]]></programlisting>
|
|
An outbound channel adapter that adds length checking to the datagram packets.
|
|
<tip>
|
|
The recipient of the packet must also be configured to expect a length to precede the
|
|
actual data. For a Spring Integration UDP inbound channel adapter, set its
|
|
<classname>check-length</classname> attribute.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
The second reliability improvement allows an application-level acknowledgment protocol to be used. The receiver
|
|
must send an acknowledgment to the sender within a specified time.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:udp-outbound-channel-adapter id="udpOut"
|
|
host="somehost"
|
|
port="11111"
|
|
multicast="false"
|
|
check-length="true"
|
|
acknowledge="true"
|
|
ack-host="thishost"
|
|
ack-port="22222"
|
|
ack-timeout="10000"
|
|
channel="exampleChannel"/>]]></programlisting>
|
|
An outbound channel adapter that adds length checking to the datagram packets and waits for an acknowledgment.
|
|
<tip>
|
|
Setting acknowledge to true implies the recipient of the packet can interpret the header added to the packet
|
|
containing acknowledgment data (host and port). Most likely, the recipient will be a Spring Integration inbound
|
|
channel adapter.
|
|
</tip>
|
|
<tip>
|
|
When multicast is true, an additional attribute min-acks-for-success specifies
|
|
how many acknowledgments must be received within the ack-timeout.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
For even more reliable networking, TCP can be used.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:udp-inbound-channel-adapter id="udpReceiver"
|
|
channel="udpOutChannel"
|
|
port="11111"
|
|
receive-buffer-size="500"
|
|
multicast="false"
|
|
check-length="true"/>]]></programlisting>
|
|
A basic unicast inbound udp channel adapter.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:udp-inbound-channel-adapter id="udpReceiver"
|
|
channel="udpOutChannel"
|
|
port="11111"
|
|
receive-buffer-size="500"
|
|
multicast="true"
|
|
multicast-address="225.6.7.8"
|
|
check-length="true"/>]]></programlisting>
|
|
A basic multicast inbound udp channel adapter.
|
|
</para>
|
|
<para>
|
|
By default, reverse DNS lookups are done on inbound packets to convert IP addresses to
|
|
hostnames for use in message headers.
|
|
In environments where DNS is not configured, this can cause delays.
|
|
This default behavior can be overridden by setting the <literal>lookup-host</literal>
|
|
attribute to "false".
|
|
</para>
|
|
</section>
|
|
<section id="connection-factories">
|
|
<title>TCP Connection Factories</title>
|
|
<para>
|
|
For TCP, the configuration of the underlying connection is provided using a
|
|
Connection Factory. Two types of connection factory are provided; a
|
|
client connection factory and a server connection factory. Client connection
|
|
factories are used to establish outgoing connections; Server connection factories
|
|
listen for incoming connections.
|
|
</para>
|
|
<para>
|
|
A client connection factory is used
|
|
by an outbound channel adapter but a reference to a client connection factory
|
|
can also be provided to an inbound channel adapter and that adapter will receive
|
|
any incoming messages received on connections created by the outbound adapter.
|
|
</para>
|
|
<para>
|
|
A server connection factory is used by an inbound channel adapter or gateway (in fact
|
|
the connection factory will not function without one). A reference to a server
|
|
connection factory can also be provided to an outbound adapter; that adapter
|
|
can then be used to send replies to incoming messages to the same connection.
|
|
<tip>
|
|
<para>Reply messages will only be routed to the connection if the reply contains
|
|
the header ip_connection_id that was inserted into the original message by
|
|
the connection factory.</para></tip>
|
|
<tip>
|
|
<para>
|
|
This is the extent of message correlation performed when sharing connection
|
|
factories between inbound and outbound adapters. Such sharing allows for
|
|
asynchronous two-way communication over TCP. By default, only payload information is
|
|
transferred using TCP; therefore any message correlation must be performed
|
|
by downstream components such as aggregators or other endpoints. Support for
|
|
transferring selected headers was introduced in version 3.0.
|
|
For more information refer to <xref linkend="ip-correlation" />.
|
|
</para>
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
A maximum of one adapter of each type may be given a reference to a connection
|
|
factory.
|
|
</para>
|
|
<para>
|
|
Connection factories using <classname>java.net.Socket</classname> and
|
|
<classname>java.nio.channel.SocketChannel</classname> are provided.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:tcp-connection-factory id="server"
|
|
type="server"
|
|
port="1234"/>]]></programlisting>
|
|
A simple server connection factory that uses <classname>java.net.Socket</classname>
|
|
connections.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:tcp-connection-factory id="server"
|
|
type="server"
|
|
port="1234"
|
|
using-nio="true"/>]]></programlisting>
|
|
A simple server connection factory that uses <classname>java.nio.channel.SocketChannel</classname>
|
|
connections.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:tcp-connection-factory id="client"
|
|
type="client"
|
|
host="localhost"
|
|
port="1234"
|
|
single-use="true"
|
|
so-timeout="10000"/>]]></programlisting>
|
|
A client connection factory that uses <classname>java.net.Socket</classname>
|
|
connections and creates a new connection for each message.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:tcp-connection-factory id="client"
|
|
type="client"
|
|
host="localhost"
|
|
port="1234"
|
|
single-use="true"
|
|
so-timeout="10000"
|
|
using-nio=true/>]]></programlisting>
|
|
A client connection factory that uses <classname>java.nio.channel.Socket</classname>
|
|
connections and creates a new connection for each message.
|
|
</para>
|
|
<para>
|
|
TCP is a streaming protocol; this means that some structure has to be provided to data
|
|
transported over TCP, so the receiver can demarcate the data into discrete messages.
|
|
Connection factories are configured to use (de)serializers to convert between the message
|
|
payload and the bits that are sent over TCP. This is accomplished by providing a
|
|
deserializer and serializer for inbound and outbound messages respectively.
|
|
A number of standard (de)serializers are provided.
|
|
</para>
|
|
<para>
|
|
The <classname>ByteArrayCrlfSerializer</classname>,
|
|
converts a byte array to a stream of bytes followed by carriage
|
|
return and linefeed characters (\r\n). This is the default (de)serializer and can be used with
|
|
telnet as a client, for example.
|
|
</para>
|
|
<para>
|
|
The <classname>ByteArraySingleTerminatorSerializer</classname>,
|
|
converts a byte array to a stream of bytes followed by a single termination
|
|
character (default 0x00).
|
|
</para>
|
|
<para>
|
|
The <classname>ByteArrayLfSerializer</classname>,
|
|
converts a byte array to a stream of bytes followed by a single linefeed
|
|
character (0x0a).
|
|
</para>
|
|
<para>
|
|
The <classname>ByteArrayStxEtxSerializer</classname>,
|
|
converts a byte array to a stream of bytes preceded by an STX (0x02) and
|
|
followed by an ETX (0x03).
|
|
</para>
|
|
<para>
|
|
The <classname>ByteArrayLengthHeaderSerializer</classname>,
|
|
converts a byte array to a stream of bytes preceded by a binary
|
|
length in network byte order (big endian). This a very efficient deserializer
|
|
because it does not have to parse every byte looking for a termination
|
|
character sequence. It can also be used for payloads containing binary data;
|
|
the above serializers only support text in the payload. The default size of
|
|
the length header is 4 bytes (Integer), allowing for messages up to 2**31-1
|
|
bytes. However, the length header can be a single byte (unsigned) for
|
|
messages up to 255 bytes, or an unsigned short (2 bytes) for messages up to
|
|
2**16 bytes. If you need any other format for the header, you can subclass
|
|
this class and provide implementations for the readHeader and writeHeader
|
|
methods. The absolute maximum data size supported is 2**31-1 bytes.
|
|
</para>
|
|
<para>
|
|
The <classname>ByteArrayRawSerializer</classname>,
|
|
converts a byte array to a stream of bytes and adds no additional message
|
|
demarcation data; with this (de)serializer, the end of a message is indicated
|
|
by the client closing the socket in an orderly fashion. When using this serializer,
|
|
message reception will hang until the client closes the socket, or a timeout occurs;
|
|
a timeout will NOT result in a message. When this serializer is being used, and the client
|
|
is a Spring Integration application, the client must use a connection factory that is
|
|
configured with single-use=true - this causes the adapter to close the socket after sending
|
|
the message; the serializer will not, itself, close the connection. This serializer
|
|
should only be used with connection factories used by channel adapters (not gateways), and the
|
|
connection factories should be used by either an inbound or outbound adapter, and not both.
|
|
</para>
|
|
<para>
|
|
Each of these is a subclass of
|
|
<classname>AbstractByteArraySerializer</classname> which implements both
|
|
<classname>org.springframework.core.serializer.Serializer</classname> and
|
|
<classname>org.springframework.core.serializer.Deserializer</classname>.
|
|
For backwards compatibility, connections using any subclass of
|
|
<classname>AbstractByteArraySerializer</classname> for serialization
|
|
will also accept a String which will be converted to a byte array first.
|
|
Each of these (de)serializers converts an input stream containing the
|
|
corresponding format to a byte array payload.
|
|
</para>
|
|
<para>
|
|
To avoid memory exhaustion due to a badly behaved client (one that does not adhere to
|
|
the protocol of the configured serializer), these serializers impose a maximum message
|
|
size. If the size is exceeded by an incoming message, an exception will be thrown.
|
|
The default maximum message size is 2048 bytes, and can be increased by setting the
|
|
<classname>maxMessageSize</classname> property. If you are using the default (de)serializer
|
|
and wish to increase the maximum message size, you must declare it as an explicit bean
|
|
with the property set and configure the connection factory to use that bean.
|
|
</para>
|
|
<para>
|
|
The <classname>MapJsonSerializer</classname> uses a Jackson
|
|
<classname>ObjectMapper</classname> to convert between a <interfacename>Map</interfacename>
|
|
and JSON. This can be used in conjunction with a <classname>MessageConvertingTcpMessageMapper
|
|
</classname> and a <classname>MapMessageConverter</classname>
|
|
to transfer selected headers and the payload in a JSON format.
|
|
<note>
|
|
The Jackson <classname>ObjectMapper</classname> cannot demarcate messages in the stream.
|
|
Therefore, the <classname>MapJsonSerializer</classname> needs to delegate to another
|
|
(de)serializer to handle message demarcation. By default, a
|
|
<classname>ByteArrayLfSerializer</classname> is used, resulting in messages with the
|
|
format <code><json><LF></code> on the wire, but you can configure it to
|
|
use others instead.
|
|
</note>
|
|
</para>
|
|
<para>
|
|
The final standard serializer is
|
|
<classname>org.springframework.core.serializer.DefaultSerializer</classname> which can be
|
|
used to convert Serializable objects using java serialization.
|
|
<classname>org.springframework.core.serializer.DefaultDeserializer</classname> is provided for
|
|
inbound deserialization of streams containing Serializable objects.
|
|
</para>
|
|
<para>
|
|
To implement a custom (de)serializer pair, implement the
|
|
<classname>org.springframework.core.serializer.Deserializer</classname> and
|
|
<classname>org.springframework.core.serializer.Serializer</classname> interfaces.
|
|
</para>
|
|
<para>
|
|
If you do not wish to use
|
|
the default (de)serializer (<classname>ByteArrayCrLfSerializer</classname>), you must supply
|
|
<classname>serializer</classname> and
|
|
<classname>deserializer</classname> attributes on the connection factory (example below).
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<bean id="javaSerializer"
|
|
class="org.springframework.core.serializer.DefaultSerializer" />
|
|
<bean id="javaDeserializer"
|
|
class="org.springframework.core.serializer.DefaultDeserializer" />
|
|
|
|
<int-ip:tcp-connection-factory id="server"
|
|
type="server"
|
|
port="1234"
|
|
deserializer="javaDeserializer"
|
|
serializer="javaSerializer"/>]]></programlisting>
|
|
A server connection factory that uses <classname>java.net.Socket</classname>
|
|
connections and uses Java serialization on the wire.
|
|
</para>
|
|
<para>
|
|
For full details of the attributes available on connection factories, see the
|
|
reference at the end of this section.
|
|
</para>
|
|
<para>
|
|
By default, reverse DNS lookups are done on inbound packets to convert IP addresses to
|
|
hostnames for use in message headers.
|
|
In environments where DNS is not configured, this can cause connection delays.
|
|
This default behavior can be overridden by setting the <literal>lookup-host</literal>
|
|
attribute to "false".
|
|
</para>
|
|
<note>
|
|
<para>
|
|
It is possible to modify the creation of and/or attributes of sockets - see
|
|
<xref linkend="ssl-tls"/>. As is noted there, such modifications are possible whether
|
|
or not SSL is being used.
|
|
</para>
|
|
</note>
|
|
<section id="caching-cf">
|
|
<title>TCP Caching Client Connection Factory</title>
|
|
<para>
|
|
As noted above, TCP sockets cam be 'single-use' (one request/response)
|
|
or shared. Shared sockets do not perform well with outbound gateways,
|
|
in high-volume environments,
|
|
because the socket can only process one request/response at a time.
|
|
</para>
|
|
<para>
|
|
To improve performance, users could use collaborating channel adapters
|
|
instead of gateways, but that requires application-level message
|
|
correlation. See <xref linkend="ip-correlation" />for more information.
|
|
</para>
|
|
<para>
|
|
Spring Integration 2.2 introduced a caching client connection factory,
|
|
where a pool of shared sockets is used, allowing a gateway to
|
|
process multiple concurrent requests with a pool of shared
|
|
connections.
|
|
</para>
|
|
</section>
|
|
<section id="failover-cf">
|
|
<title>TCP Failover Client Connection Factory</title>
|
|
<para>
|
|
It is now possible to configure a TCP connection factory that
|
|
supports failover to one or more other servers. When sending
|
|
a message, the factory will iterate over all its configured
|
|
factories until either the message can be sent, or no connection
|
|
can be found. Initially, the first factory in the configured
|
|
list is used; if a connection subsequently fails the next
|
|
factory will become the current factory.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<bean id="failCF" class="o.s.i.ip.tcp.connection.FailoverClientConnectionFactory">
|
|
<constructor-arg>
|
|
<list>
|
|
<ref bean="clientFactory1"/>
|
|
<ref bean="clientFactory2"/>
|
|
</list>
|
|
</constructor-arg>
|
|
</bean>]]></programlisting>
|
|
</para>
|
|
<para>
|
|
<note>When using the failover connection factory, the singleUse property must be consistent between
|
|
the factory itself and the list of factories it is configured to use.
|
|
</note>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="ip-interceptors">
|
|
<title>TCP Connection Interceptors</title>
|
|
<para>
|
|
Connection factories can be configured with a reference to a
|
|
<classname>TcpConnectionInterceptorFactoryChain</classname>. Interceptors can be used
|
|
to add behavior to connections, such as negotiation, security, and other setup.
|
|
No interceptors are currently provided by the framework but, for an example,
|
|
see the <classname>InterceptedSharedConnectionTests</classname> in the source
|
|
repository.
|
|
</para>
|
|
<para>
|
|
The <classname>HelloWorldInterceptor</classname> used in the test case works as follows:
|
|
</para>
|
|
<para>
|
|
When configured with a client connection factory,
|
|
when the first message is sent over a connection that is intercepted, the interceptor
|
|
sends 'Hello' over the connection, and expects to receive 'world!'. When that occurs,
|
|
the negotiation is complete and the original message is sent; further messages
|
|
that use the same connection are sent without any additional negotiation.
|
|
</para>
|
|
<para>
|
|
When configured with a server connection factory, the interceptor requires the first
|
|
message to be 'Hello' and, if it is, returns 'world!'. Otherwise it throws an exception causing
|
|
the connection to be closed.
|
|
</para>
|
|
<para>
|
|
All <classname>TcpConnection</classname> methods are intercepted.
|
|
Interceptor instances are created for each connection by an interceptor factory.
|
|
If an interceptor is stateful, the factory should create a new instance for each connection;
|
|
if there is no state, the same interceptor can wrap each connection. Interceptor
|
|
factories are added to the configuration of an interceptor factory chain, which is provided
|
|
to a connection factory using the <classname>interceptor-factory</classname> attribute.
|
|
Interceptors must extend <classname>TcpConnectionInterceptorSupport</classname>;
|
|
factories
|
|
must implement the <classname>TcpConnectionInterceptorFactory</classname> interface.
|
|
<classname>TcpConnectionInterceptorSupport</classname> is provided
|
|
with passthrough methods; by extending this class, you only need to implement those
|
|
methods you wish to intercept.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<bean id="helloWorldInterceptorFactory"
|
|
class="o.s.i.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
|
|
<property name="interceptors">
|
|
<array>
|
|
<bean class="o.s.i.ip.tcp.connection.HelloWorldInterceptorFactory"/>
|
|
</array>
|
|
</property>
|
|
</bean>
|
|
|
|
<int-ip:tcp-connection-factory id="server"
|
|
type="server"
|
|
port="12345"
|
|
using-nio="true"
|
|
single-use="true"
|
|
interceptor-factory-chain="helloWorldInterceptorFactory"/>
|
|
|
|
<int-ip:tcp-connection-factory id="client"
|
|
type="client"
|
|
host="localhost"
|
|
port="12345"
|
|
single-use="true"
|
|
so-timeout="100000"
|
|
using-nio="true"
|
|
interceptor-factory-chain="helloWorldInterceptorFactory"/>]]></programlisting>
|
|
Configuring a connection interceptor factory chain.
|
|
</para>
|
|
</section>
|
|
<section id="tcp-events">
|
|
<title>TCP Connection Events</title>
|
|
<para>
|
|
Beginning with version 3.0, changes to <interfacename>TcpConnection</interfacename>s
|
|
are reported by <classname>TcpConnectionEvent</classname>s. <classname>TcpConnectionEvent</classname>
|
|
is a subclass of <classname>ApplicationEvent</classname> and thus can
|
|
be received by any <interfacename>ApplicationListener</interfacename> defined in
|
|
the <interfacename>ApplicationContext</interfacename>.
|
|
</para>
|
|
<para>
|
|
For convenience, a <code><int-ip:tcp-connection-event-inbound-channel-adapter/></code>
|
|
is provided. This adapter will receive all <classname>TcpConnectionEvent</classname>s (by
|
|
default), and send them to its <code>channel</code>. The adapter accepts an <code>event-type</code>
|
|
attribute, which is a list of class names for events that should be sent. This can be used
|
|
if an application subclasses <classname>TcpConnectionEvent</classname> for some reason, and wishes
|
|
to only receive those events. Omitting this attribute will mean that all
|
|
<classname>TcpConnectionEvent</classname>s will be sent. You can also use this to limit which
|
|
<classname>TcpConnectionEvent</classname>s you are interested in (
|
|
<classname>TcpConnectionOpenEvent</classname>, <classname>TcpConnectionCloseEvent</classname>,
|
|
or <classname>TcpConnectionExceptionEvent</classname>).
|
|
</para>
|
|
<para>
|
|
<classname>TcpConnectionEvents</classname> have the following properties:
|
|
<itemizedlist>
|
|
<listitem><code>connectionId</code> - the connection identifier which can be used in a message header
|
|
to send data to the connection</listitem>
|
|
<listitem><code>connectionFactoryName</code> - the bean name of the connection factory the connection belongs to</listitem>
|
|
<listitem><code>throwable</code> - the <classname>Throwable</classname> (for <classname>TcpConnectionExceptionEvent</classname> events only)</listitem>
|
|
<listitem><code>source</code> - the <interfacename>TcpConnection</interfacename>; this can be
|
|
used, for example, to determine the remote IP Address with <code>getHostAddress()</code> (cast required)
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
In addition, since <emphasis>version 4.0</emphasis> the standard deserializers discussed in
|
|
<xref linkend="connection-factories"/> now emit <classname>TcpDeserializationExceptionEvent</classname>s
|
|
when problems are encountered decoding the data stream. These events contain the exception, the
|
|
buffer that was in the process of being built, and an offset into the buffer (if available) at the
|
|
point the exception occurred. Applications can use a normal <interfacename>ApplicationListener</interfacename>,
|
|
or see <xref linkend="applicationevent-inbound"/>, to capture these events, allowing analysis of the problem.
|
|
</para>
|
|
</section>
|
|
<section id="tcp-adapters">
|
|
<title>TCP Adapters</title>
|
|
<para>
|
|
TCP inbound and outbound channel adapters that utilize the above connection
|
|
factories are provided. These adapters have attributes
|
|
<classname>connection-factory</classname> and <classname>channel</classname>.
|
|
The channel attribute specifies the channel on which messages arrive at an
|
|
outbound adapter and on which messages are placed by an inbound adapter.
|
|
The connection-factory attribute indicates which connection factory is to be used to
|
|
manage connections for the adapter. While both inbound and outbound adapters
|
|
can share a connection factory, server connection factories are always 'owned'
|
|
by an inbound adapter; client connection factories are always 'owned' by an
|
|
outbound adapter. One, and only one, adapter of each type may get a reference
|
|
to a connection factory.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[<bean id="javaSerializer"
|
|
class="org.springframework.core.serializer.DefaultSerializer"/>
|
|
<bean id="javaDeserializer"
|
|
class="org.springframework.core.serializer.DefaultDeserializer"/>
|
|
|
|
<int-ip:tcp-connection-factory id="server"
|
|
type="server"
|
|
port="1234"
|
|
deserializer="javaDeserializer"
|
|
serializer="javaSerializer"
|
|
using-nio="true"
|
|
single-use="true"/>
|
|
|
|
<int-ip:tcp-connection-factory id="client"
|
|
type="client"
|
|
host="localhost"
|
|
port="#{server.port}"
|
|
single-use="true"
|
|
so-timeout="10000"
|
|
deserializer="javaDeserializer"
|
|
serializer="javaSerializer"/>
|
|
|
|
<int:channel id="input" />
|
|
|
|
<int:channel id="replies">
|
|
<int:queue/>
|
|
</int:channel>
|
|
|
|
<int-ip:tcp-outbound-channel-adapter id="outboundClient"
|
|
channel="input"
|
|
connection-factory="client"/>
|
|
|
|
<int-ip:tcp-inbound-channel-adapter id="inboundClient"
|
|
channel="replies"
|
|
connection-factory="client"/>
|
|
|
|
<int-ip:tcp-inbound-channel-adapter id="inboundServer"
|
|
channel="loop"
|
|
connection-factory="server"/>
|
|
|
|
<int-ip:tcp-outbound-channel-adapter id="outboundServer"
|
|
channel="loop"
|
|
connection-factory="server"/>
|
|
|
|
<int:channel id="loop"/>]]></programlisting>
|
|
In this configuration, messages arriving in channel 'input'
|
|
are serialized over connections created by 'client' received
|
|
at the server and placed on channel 'loop'. Since 'loop' is
|
|
the input channel for 'outboundServer' the message is simply
|
|
looped back over the same connection and received by
|
|
'inboundClient' and deposited in channel 'replies'. Java
|
|
serialization is used on the wire.
|
|
</para>
|
|
<para>
|
|
Normally, inbound adapters use a type="server" connection
|
|
factory, which listens for incoming connection requests.
|
|
In some cases, it is desirable to establish the connection
|
|
in reverse, whereby the inbound adapter connects to an
|
|
external server and then waits for inbound messages on that
|
|
connection.
|
|
</para>
|
|
<para>
|
|
This topology is supported by using <emphasis>client-mode="true"</emphasis>
|
|
on the inbound adapter. In this case, the connection factory must
|
|
be of type 'client' and must have <emphasis>single-use</emphasis>
|
|
set to false.
|
|
</para>
|
|
<para>
|
|
Two additional attributes are used to support this mechanism:
|
|
<emphasis>retry-interval</emphasis> specifies (in milliseconds)
|
|
how often the framework will attempt to reconnect after a
|
|
connection failure. <emphasis>scheduler</emphasis> is used to
|
|
supply a <classname>TaskScheduler</classname> used to
|
|
schedule the connection attempts, and to test that the connection is
|
|
still active.
|
|
</para>
|
|
<para>
|
|
For an outbound adapter, the connection is normally established
|
|
when the first message is sent. <emphasis>client-mode="true"</emphasis>
|
|
on an outbound adapter will cause the connection to be established
|
|
when the adapter is started. Adapters are automatically started
|
|
by default. Again, the connection factory must be of type client
|
|
and have <emphasis>single-use</emphasis> set to false and
|
|
<emphasis>retry-interval</emphasis> and
|
|
<emphasis>scheduler</emphasis> are also supported. If a connection
|
|
fails, it will be re-established either by the scheduler or
|
|
when the next message is sent.
|
|
</para>
|
|
<para>
|
|
For both inbound and outbound,
|
|
if the adapter is started, you may force the adapter to establish
|
|
a connection by sending a <control-bus /> command:
|
|
<classname>@adapter_id.retryConnection()</classname> and examine the
|
|
current state with <classname>@adapter_id.isConnected()</classname>.
|
|
</para>
|
|
</section>
|
|
<section id="tcp-gateways">
|
|
<title>TCP Gateways</title>
|
|
<para>
|
|
The inbound TCP gateway <classname>TcpInboundGateway</classname>
|
|
and outbound TCP gateway <classname>TcpOutboundGateway</classname>
|
|
use a server and client connection factory respectively. Each connection
|
|
can process a single request/response at a time.
|
|
</para>
|
|
<para>
|
|
The inbound gateway, after constructing a message with the incoming payload and sending
|
|
it to the requestChannel, waits for a response and sends the payload
|
|
from the response message by writing it to the connection.
|
|
</para>
|
|
<para>
|
|
<note>
|
|
<para>
|
|
For the inbound gateway, care must be taken to retain, or populate, the
|
|
<emphasis>ip_connectionId</emphasis> header because it is used to
|
|
correlate the message to a connection. Messages that originate at the
|
|
gateway will automatically have the header set. If the reply is
|
|
constructed as a new message, you will need to set the header. The
|
|
header value can be captured from the incoming message.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<para>
|
|
As with inbound adapters, inbound gateways normally use a
|
|
type="server" connection
|
|
factory, which listens for incoming connection requests.
|
|
In some cases, it is desirable to establish the connection
|
|
in reverse, whereby the inbound gateway connects to an
|
|
external server and then waits for, and replies to, inbound
|
|
messages on that connection.
|
|
</para>
|
|
<para>
|
|
This topology is supported by using <emphasis>client-mode="true"</emphasis>
|
|
on the inbound gateway. In this case, the connection factory must
|
|
be of type 'client' and must have <emphasis>single-use</emphasis>
|
|
set to false.
|
|
</para>
|
|
<para>
|
|
Two additional attributes are used to support this mechanism:
|
|
<emphasis>retry-interval</emphasis> specifies (in milliseconds)
|
|
how often the framework will attempt to reconnect after a
|
|
connection failure. <emphasis>scheduler</emphasis> is used to
|
|
supply a <classname>TaskScheduler</classname> used to
|
|
schedule the connection attempts, and to test that the connection is
|
|
still active.
|
|
</para>
|
|
<para>
|
|
If the gateway is started, you may force the gateway to establish
|
|
a connection by sending a <control-bus /> command:
|
|
<classname>@adapter_id.retryConnection()</classname> and examine the
|
|
current state with <classname>@adapter_id.isConnected()</classname>.
|
|
</para>
|
|
<para>
|
|
The outbound gateway, after sending a message over the connection, waits for a response and
|
|
constructs a response message and puts in on the reply channel.
|
|
Communications over the connections are single-threaded. Users should be aware that only one
|
|
message can be handled at a time and, if another thread attempts to send
|
|
a message before the current response has been received, it will block until
|
|
any previous requests are complete (or time out).
|
|
If, however, the client connection factory is configured for single-use connections
|
|
each new request gets its own connection and is processed immediately.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[
|
|
<int-ip:tcp-inbound-gateway id="inGateway"
|
|
request-channel="tcpChannel"
|
|
reply-channel="replyChannel"
|
|
connection-factory="cfServer"
|
|
reply-timeout="10000"/>]]></programlisting>
|
|
A simple inbound TCP gateway; if a connection factory configured with the default
|
|
(de)serializer is used, messages will be \r\n delimited data and the gateway can be
|
|
used by a simple client such as telnet.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[
|
|
<int-ip:tcp-outbound-gateway id="outGateway"
|
|
request-channel="tcpChannel"
|
|
reply-channel="replyChannel"
|
|
connection-factory="cfClient"
|
|
request-timeout="10000"
|
|
remote-timeout="10000"/>]]></programlisting>
|
|
A simple outbound TCP gateway.
|
|
</para>
|
|
</section>
|
|
<section id="ip-correlation">
|
|
<title>TCP Message Correlation</title>
|
|
<section>
|
|
<title>Overview</title>
|
|
<para>
|
|
One goal of the IP Endpoints is to provide communication with systems other
|
|
than another Spring Integration application. For this reason, only
|
|
message payloads are sent and received, by default. Since 3.0, headers can
|
|
be transferred, using JSON, Java serialization, or with custom
|
|
<interfacename>Serializer</interfacename>s and
|
|
<interfacename>Deserializer</interfacename>s; see <xref linkend="ip-headers"/>
|
|
for more information.
|
|
No message correlation is provided by the framework,
|
|
except when using the gateways, or collaborating channel adapters on the
|
|
server side. In the paragraphs below we discuss the various
|
|
correlation techniques available to applications. In most cases, this
|
|
requires specific application-level correlation of messages, even when
|
|
message payloads contain some natural correlation data (such as an order
|
|
number).
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Gateways</title>
|
|
<para>
|
|
The gateways will automatically correlate messages. However, an outbound
|
|
gateway should only be used for relatively low-volume use.
|
|
When the connection factory is configured for a single shared connection
|
|
to be used for all message pairs ('single-use="false"'),
|
|
only one message can be processed at a time.
|
|
A new message will have to wait until the reply to the previous message has
|
|
been received.
|
|
When a connection factory is configured for each new message to use a new connection
|
|
('single-use="true"'), the above restriction does not apply.
|
|
While this may give higher throughput
|
|
than a shared connection environment, it comes with the overhead of opening
|
|
and closing a new connection for each message pair.
|
|
</para>
|
|
<para>
|
|
Therefore, for high-volume messages, consider using a collaborating pair of
|
|
channel adapters. However, you will need to provide collaboration logic.
|
|
</para>
|
|
<para>
|
|
Another solution, introduced in Spring Integration 2.2, is to use a
|
|
<classname>CachingClientConnectionFactory</classname>, which allows
|
|
the use of a pool of shared connections.
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Collaborating Outbound and Inbound Channel Adapters</title>
|
|
<para>
|
|
To achieve high-volume throughput (avoiding the pitfalls of using gateways
|
|
as mentioned above) you may consider configuring a pair of collaborating
|
|
outbound and inbound channel adapters.
|
|
Collaborating adapters can also be used (server-side or client-side) for
|
|
totally asynchronous communication (rather than with request/reply semantics).
|
|
On the server side, message
|
|
correlation is automatically handled by the adapters because the inbound
|
|
adapter adds a header allowing the outbound adapter to determine which
|
|
connection to use to send the reply message.
|
|
</para>
|
|
<para>
|
|
<note>
|
|
<para>
|
|
On the server side, care must be taken to populate the
|
|
<emphasis>ip_connectionId</emphasis> header because it is used to
|
|
correlate the message to a connection. Messages that originate at the
|
|
inbound adapter will automatically have the header set. If you wish to
|
|
construct other messages to send, you will need to set the header. The
|
|
header value can be captured from an incoming message.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<para>
|
|
On the client side,
|
|
the application will have to provide its own correlation logic, if needed.
|
|
This can be done in a number of ways.
|
|
</para>
|
|
<para>
|
|
If the message payload has some natural correlation data, such as a
|
|
transaction id or an order number, AND there is no need to retain any
|
|
information (such as a reply channel header) from the original outbound message,
|
|
the correlation is simple and would done at the application level in any case.
|
|
</para>
|
|
<para>
|
|
If the message payload has some natural correlation data, such as a
|
|
transaction id or an order number, but there is a need to retain some
|
|
information (such as a reply channel header) from the original outbound message,
|
|
you may need to retain a copy of the original outbound message (perhaps
|
|
by using a publish-subscribe channel) and use an aggregator to recombine
|
|
the necessary data.
|
|
</para>
|
|
<para>
|
|
For either of the previous two paragraphs, if the payload has no natural
|
|
correlation data, you may need to provide a transformer upstream of the
|
|
outbound channel adapter to enhance the payload with such data. Such a
|
|
transformer may transform the original payload to a new object containing
|
|
both the original payload and some subset of the message headers. Of course,
|
|
live objects (such as reply channels) from the headers can not be
|
|
included in the transformed payload.
|
|
</para>
|
|
<para>
|
|
If such a strategy is chosen you will need to ensure the connection factory
|
|
has an appropriate serializer/deserializer pair to handle such a payload,
|
|
such as the <classname>DefaultSerializer/Deserializer</classname> which use java
|
|
serialization, or a custom serializer and deserializer.
|
|
The <classname>ByteArray*Serializer</classname> options
|
|
mentioned in <xref linkend="connection-factories" />,
|
|
including the default <classname>ByteArrayCrLfSerializer</classname>,
|
|
do not support such payloads,
|
|
unless the transformed payload is a <classname>String</classname> or
|
|
<classname>byte[]</classname>,
|
|
</para>
|
|
<para>
|
|
<note>
|
|
<para>
|
|
Before the 2.2 release,
|
|
when a <emphasis>client</emphasis> connection factory was used by
|
|
collaborating channel
|
|
adapters, the <emphasis>so-timeout</emphasis> attribute defaulted
|
|
to the default reply timeout (10 seconds). This meant that if
|
|
no data were received by the inbound adapter for this period of
|
|
time, the socket was closed.
|
|
</para>
|
|
<para>
|
|
This default behavior was not appropriate in a truly asynchronous
|
|
environment, so it now defaults to an infinite timeout.
|
|
You can reinstate the previous default behavior by setting the
|
|
<emphasis>so-timeout</emphasis> attribute on the client connection
|
|
factory to 10000 milliseconds.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
</section>
|
|
<section id="ip-headers">
|
|
<title>Transferring Headers</title>
|
|
<para>
|
|
TCP is a streaming protocol; <interfacename>Serializers</interfacename> and
|
|
<interfacename>Deserializers</interfacename> are used to demarcate messages
|
|
within the stream. Prior to 3.0, only message payloads (String or byte[])
|
|
could be transferred over
|
|
TCP. Beginning with 3.0, you can now transfer selected headers as well as the
|
|
payload. It is important to understand, though, that "live" objects, such
|
|
as the <code>replyChannel</code> header cannot be serialized.
|
|
</para>
|
|
<para>
|
|
Sending header information over TCP requires some additional configuration.
|
|
</para>
|
|
<para>
|
|
The first step is to provide the <classname>ConnectionFactory</classname>
|
|
with a <classname>MessageConvertingTcpMessageMapper</classname> using the
|
|
<code>mapper</code> attribute. This mapper delegates to any
|
|
<interfacename>MessageConverter</interfacename> implementation to convert
|
|
the message to/from some object that can be (de)serialized by the
|
|
configured <code>serializer</code> and <code>deserializer</code>.
|
|
</para>
|
|
<para>
|
|
A <classname>MapMessageConverter</classname> is provided, which allows the
|
|
specification of a list of headers that will be added to a
|
|
<interfacename>Map</interfacename> object, along with the payload.
|
|
The generated Map has two entries: <code>payload</code> and
|
|
<code>headers</code>. The <code>headers</code> entry is itself a
|
|
<interfacename>Map</interfacename> containing the selected headers.
|
|
</para>
|
|
<para>
|
|
The second step is to provide a (de)serializer that can convert between
|
|
a <interfacename>Map</interfacename> and some wire format. This can
|
|
be a custom <interfacename>(de)Serializer</interfacename>, which would
|
|
typically be needed if the peer system is not a Spring Integration
|
|
application.
|
|
</para>
|
|
<para>
|
|
A <classname>MapJsonSerializer</classname> is provided that will
|
|
convert a Map to/from JSON. This uses a Spring Integration
|
|
<classname>JsonObjectMapper</classname> to perform this function. You
|
|
can provide a custom <classname>JsonObjectMapper</classname> if needed.
|
|
By default, the serializer inserts a linefeed
|
|
<code>0x0a</code> character between objects.
|
|
See the JavaDocs for more information.
|
|
</para>
|
|
<note>
|
|
At the time of writing, the <classname>JsonObjectMapper</classname>
|
|
uses whichever version of <code>Jackson</code> is on the classpath.
|
|
</note>
|
|
<para>
|
|
You can also use standard Java serialization of the Map, using
|
|
the <classname>DefaultSerializer</classname> and
|
|
<classname>DefaultDeserializer</classname>.
|
|
</para>
|
|
<para>
|
|
The following example shows the configuration of a connection
|
|
factory that transfers the <code>correlationId</code>,
|
|
<code>sequenceNumber</code>, and <code>sequenceSize</code>
|
|
headers using JSON.
|
|
</para>
|
|
<programlisting language="xml"><![CDATA[<int-ip:tcp-connection-factory id="client"
|
|
type="client"
|
|
host="localhost"
|
|
port="12345"
|
|
mapper="mapper"
|
|
serializer="jsonSerializer"
|
|
deserializer="jsonSerializer"/>
|
|
|
|
<bean id="mapper"
|
|
class="o.sf.integration.ip.tcp.connection.MessageConvertingTcpMessageMapper">
|
|
<constructor-arg name="messageConverter">
|
|
<bean class="o.sf.integration.support.converter.MapMessageConverter">
|
|
<property name="headerNames">
|
|
<list>
|
|
<value>correlationId</value>
|
|
<value>sequenceNumber</value>
|
|
<value>sequenceSize</value>
|
|
</list>
|
|
</property>
|
|
</bean>
|
|
</constructor-arg>
|
|
</bean>
|
|
|
|
<bean id="jsonSerializer" class="o.sf.integration.ip.tcp.serializer.MapJsonSerializer" />
|
|
]]></programlisting>
|
|
<para>
|
|
A message sent with the above configuration, with payload 'foo' would appear on the wire like so:
|
|
</para>
|
|
<programlisting language="xml"><![CDATA[
|
|
{"headers":{"correlationId":"bar","sequenceSize":5,"sequenceNumber":1},"payload":"foo"}]]></programlisting>
|
|
</section>
|
|
</section>
|
|
<section id="note_nio">
|
|
<title>A Note About NIO</title>
|
|
<para>
|
|
Using NIO (see <classname>using-nio</classname> in
|
|
<xref linkend="ip-endpoint-reference" />)
|
|
avoids dedicating a thread to read from each socket. For a small number
|
|
of sockets, you will likely find that <emphasis>not</emphasis> using NIO,
|
|
together with an async handoff (e.g. to a <classname>QueueChannel</classname>),
|
|
will perform as well as, or better than, using NIO.
|
|
</para>
|
|
<para>
|
|
Consider using NIO when handling a large number of connections. However, the use
|
|
of NIO has some other ramifications. A pool of threads (in the task executor) is
|
|
shared across all the sockets; each incoming message is assembled and sent to the
|
|
configured channel as a separate unit of work on a thread selected from that pool.
|
|
Two sequential
|
|
messages arriving on the <emphasis>same</emphasis> socket <emphasis>might</emphasis>
|
|
be processed by different threads. This means that the order in which the messages are
|
|
sent to the channel is indeterminate; the strict ordering of the messages arriving on the
|
|
socket is not maintained.
|
|
</para>
|
|
<para>
|
|
For some applications, this is not an issue; for others it is. If strict ordering
|
|
is required, consider setting <classname>using-nio</classname> to false
|
|
and using async handoff.
|
|
</para>
|
|
<para>
|
|
Alternatively, you may choose to insert a resequencer downstream of the inbound endpoint to
|
|
return the messages to their proper sequence. Set <emphasis>apply-sequence</emphasis>
|
|
to true on the connection factory, and messages arriving on a TCP connection will
|
|
have <emphasis>sequenceNumber</emphasis> and <emphasis>correlationId</emphasis> headers
|
|
set. The resequencer uses these headers to return the messages to their proper
|
|
sequence.
|
|
</para>
|
|
<para><emphasis>Pool Size</emphasis></para>
|
|
<para>
|
|
The pool size attribute is no longer used; previously, it specified the size
|
|
of the default thread pool when a task-executor was not specified. It was also
|
|
used to set the connection backlog on server sockets. The first function is
|
|
no longer needed (see below); the second function is replaced by the
|
|
<emphasis>backlog</emphasis> attribute.
|
|
</para>
|
|
<para>
|
|
Previously, when using a fixed thread pool task executor (which was the default), with NIO, it
|
|
was possible to get a deadlock and processing would stop. The problem occurred when
|
|
a buffer was full, a thread reading from the socket was trying to add more data
|
|
to the buffer, and there were no threads available to make space in the buffer.
|
|
This only occurred with a very small pool size, but it could be possible under
|
|
extreme conditions. Since 2.2, two changes have eliminated this problem. First,
|
|
the default task executor is a cached thread pool executor. Second, deadlock
|
|
detection logic has been added such that if thread starvation occurs, instead of
|
|
deadlocking, an exception is thrown, thus releasing the deadlocked resources.
|
|
</para>
|
|
<important>
|
|
Now that the default task executor is unbounded, it is possible that an out of
|
|
memory condition might occur with high rates of incoming messages, if message
|
|
processing takes extended time. If your application exhibits this type of
|
|
behavior, you are advised to use a pooled task executor with an appropriate
|
|
pool size, but see the next section.
|
|
</important>
|
|
<section>
|
|
<title>Thread Pool Task Executor with CALLER_RUNS Policy</title>
|
|
<para>
|
|
There are some important considerations when using a fixed thread pool with
|
|
the <classname>CallerRunsPolicy</classname> (<code>CALLER_RUNS</code> when
|
|
using the <code><task/></code> namespace) and the queue capacity is small.
|
|
</para>
|
|
<para>
|
|
The following does not apply if you are not using a fixed thread pool.
|
|
</para>
|
|
<para>
|
|
With NIO connections there are 3 distinct task types; the IO Selector processing
|
|
is performed on one dedicated thread - detecting events, accepting new connections,
|
|
and dispatching the IO read operations to other threads, using the task
|
|
executor. When an IO reader thread (to which the read operation is dispatched)
|
|
reads data, it hands off to another thread
|
|
to assemble the incoming message; large messages may take several reads to complete.
|
|
These "assembler" threads can block waiting for data. When a new read event
|
|
occurs, the reader determines if this socket already has an assembler and
|
|
runs a new one if not. When the assembly process is complete, the assembler
|
|
thread is returned to the pool.
|
|
</para>
|
|
<para>
|
|
This can cause a deadlock when the pool is exhausted and the CALLER_RUNS
|
|
rejection policy is in use, and the task queue is full.
|
|
When the pool is empty and there is no room in the queue, the IO selector thread
|
|
receives an <code>OP_READ</code> event and dispatches the read using the
|
|
executor; the queue is full, so the selector thread itself starts the
|
|
read process; now, it detects that there is not an assembler for this
|
|
socket and, before it does the read, fires off an assembler; again, the
|
|
queue is full, and the selector thread becomes the assembler. The assembler
|
|
is now blocked awaiting the data to be read, which will never happen.
|
|
The connection factory is now deadlocked because the selector thread
|
|
can't handle new events.
|
|
</para>
|
|
<para>
|
|
We must avoid the selector (or reader) threads performing the
|
|
assembly task to avoid this deadlock. It is desirable to use seperate
|
|
pools for the IO and assembly operations.
|
|
</para>
|
|
<para>
|
|
The framework provides a
|
|
<classname>CompositeExecutor</classname>, which allows the configuration
|
|
of two distinct executors; one for performing IO operations, and
|
|
one for message assembly. In this environment, an IO thread can never
|
|
become an assembler thread, and the deadlock cannot occur.
|
|
</para>
|
|
<para>
|
|
In addition, the task executors should be configured to use a
|
|
<classname>AbortPolicy</classname> (ABORT when using <code><task></code>).
|
|
When an IO cannot be completed, it is deferred for a short time and
|
|
retried continually until it can be completed and an assembler
|
|
allocated. By default, the delay is 100ms but it can be changed using the
|
|
<code>readDelay</code> property on the connection factory (<code>read-delay</code>
|
|
when configuring with the XML namespace).
|
|
</para>
|
|
<para>
|
|
Example configuration of the composite executor is shown below.
|
|
</para>
|
|
<programlisting language="java"><![CDATA[@Bean
|
|
private CompositeExecutor compositeExecutor() {
|
|
ThreadPoolTaskExecutor ioExec = new ThreadPoolTaskExecutor();
|
|
ioExec.setCorePoolSize(4);
|
|
ioExec.setMaxPoolSize(10);
|
|
ioExec.setQueueCapacity(0);
|
|
ioExec.setThreadNamePrefix("io-");
|
|
ioExec.setRejectedExecutionHandler(new AbortPolicy());
|
|
ioExec.initialize();
|
|
ThreadPoolTaskExecutor assemblerExec = new ThreadPoolTaskExecutor();
|
|
assemblerExec.setCorePoolSize(4);
|
|
assemblerExec.setMaxPoolSize(10);
|
|
assemblerExec.setQueueCapacity(0);
|
|
assemblerExec.setThreadNamePrefix("assembler-");
|
|
assemblerExec.setRejectedExecutionHandler(new AbortPolicy());
|
|
assemblerExec.initialize();
|
|
return new CompositeExecutor(ioExec, assemblerExec);
|
|
}]]></programlisting>
|
|
<programlisting language="xml"><![CDATA[<bean id="myTaskExecutor" class="org.springframework.integration.util.CompositeExecutor">
|
|
<constructor-arg ref="io"/>
|
|
<constructor-arg ref="assembler"/>
|
|
</bean>
|
|
|
|
<task:executor id="io" pool-size="4-10" queue-capacity="0" rejection-policy="ABORT" />
|
|
<task:executor id="assembler" pool-size="4-10" queue-capacity="0" rejection-policy="ABORT" />]]></programlisting>
|
|
|
|
<programlisting language="xml"><![CDATA[<bean id="myTaskExecutor" class="org.springframework.integration.util.CompositeExecutor">
|
|
<constructor-arg>
|
|
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
|
|
<property name="threadNamePrefix" value="io-" />
|
|
<property name="corePoolSize" value="4" />
|
|
<property name="maxPoolSize" value="8" />
|
|
<property name="queueCapacity" value="0" />
|
|
<property name="rejectedExecutionHandler">
|
|
<bean class="java.util.concurrent.ThreadPoolExecutor.AbortPolicy" />
|
|
</property>
|
|
</bean>
|
|
</constructor-arg>
|
|
<constructor-arg>
|
|
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
|
|
<property name="threadNamePrefix" value="assembler-" />
|
|
<property name="corePoolSize" value="4" />
|
|
<property name="maxPoolSize" value="10" />
|
|
<property name="queueCapacity" value="0" />
|
|
<property name="rejectedExecutionHandler">
|
|
<bean class="java.util.concurrent.ThreadPoolExecutor.AbortPolicy" />
|
|
</property>
|
|
</bean>
|
|
</constructor-arg>
|
|
</bean>]]></programlisting>
|
|
</section>
|
|
</section>
|
|
<section id="ssl-tls">
|
|
<title>SSL/TLS Support</title>
|
|
<section>
|
|
<title>Overview</title>
|
|
<para>
|
|
Secure Sockets Layer/Transport Layer Security is supported. When using NIO, the JDK 5+
|
|
<classname>SSLEngine</classname> feature is used to handle handshaking after the
|
|
connection is established. When not using NIO, standard
|
|
<classname>SSLSocketFactory</classname> and <classname>SSLServerSocketFactory</classname> objects are
|
|
used to create connections. A number of strategy interfaces are provided to allow
|
|
significant customization; default implementations of these interfaces provide for
|
|
the simplest way to get started with secure communications.
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Getting Started</title>
|
|
<para>
|
|
Regardless of whether NIO is being used, you need to configure the
|
|
<classname>ssl-context-support</classname> attribute on the connection factory.
|
|
This attribute references a <bean/> definition that describes the location
|
|
and passwords for the required key stores.
|
|
</para>
|
|
<para>
|
|
SSL/TLS peers require two keystores each; a keystore containing private/public key
|
|
pairs identifying the peer; a truststore, containing the public keys for peers that
|
|
are trusted. See the documentation for the <classname>keytool</classname> utility
|
|
provided with the JDK. The essential steps are
|
|
</para>
|
|
<para>
|
|
<orderedlist>
|
|
<listitem><para>Create a new key pair and store in a keystore.</para></listitem>
|
|
<listitem><para>Export the public key.</para></listitem>
|
|
<listitem><para>Import the public key into the peer's truststore.</para></listitem>
|
|
</orderedlist>
|
|
</para>
|
|
<para>
|
|
Repeat for the other peer.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
It is common in test cases to use the same key stores on both peers, but this should
|
|
be avoided for production.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
After establishing the key stores, the next step is to indicate their locations to the
|
|
<classname>TcpSSLContextSupport</classname> bean, and provide a reference to that bean
|
|
to the connection factory.
|
|
</para>
|
|
<para><programlisting language="xml"><![CDATA[<bean id="sslContextSupport"
|
|
class="o.sf.integration.ip.tcp.connection.support.DefaultTcpSSLContextSupport">
|
|
<constructor-arg value="client.ks"/>
|
|
<constructor-arg value="client.truststore.ks"/>
|
|
<constructor-arg value="secret"/>
|
|
<constructor-arg value="secret"/>
|
|
</bean>
|
|
|
|
<ip:tcp-connection-factory id="clientFactory"
|
|
type="client"
|
|
host="localhost"
|
|
port="1234"
|
|
ssl-context-support="sslContextSupport"]]></programlisting>
|
|
</para>
|
|
<para>
|
|
The <classname>DefaulTcpSSLContextSupport</classname> class also has an optional
|
|
'protocol' property, which can be 'SSL' or 'TLS' (default).
|
|
</para>
|
|
<para>
|
|
The keystore file names (first two constructor arguments) use the Spring <classname>Resource</classname>
|
|
abstraction; by default the files will be located on the classpath, but this can be overridden by using
|
|
the <classname>file:</classname> prefix, to find the files on the filesystem instead.
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Advanced Techniques</title>
|
|
<para>
|
|
In many cases, the configuration described above is all that is needed to enable secure
|
|
communication over TCP/IP. However, a number of strategy interfaces are provided to
|
|
allow customization and modification of socket factories and sockets.
|
|
</para>
|
|
<para>
|
|
<itemizedlist>
|
|
<listitem><para><classname>TcpSSLContextSupport</classname></para></listitem>
|
|
<listitem><para><classname>TcpSocketFactorySupport</classname></para></listitem>
|
|
<listitem><para><classname>TcpSocketSupport</classname></para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para><programlisting language="java"><![CDATA[public interface TcpSSLContextSupport {
|
|
|
|
SSLContext getSSLContext() throws Exception;
|
|
|
|
}]]></programlisting>
|
|
</para>
|
|
<para>
|
|
Implementations of this interface are responsible for creating an SSLContext.
|
|
The sole implementation provided by the framework is the
|
|
<classname>DefaultTcpSSLContextSupport</classname> described above. If you require
|
|
different behavior, implement this interface and provide the connection factory with
|
|
a reference to a bean of your class' implementation.
|
|
</para>
|
|
<para><programlisting language="java"><![CDATA[public interface TcpSocketFactorySupport {
|
|
|
|
ServerSocketFactory getServerSocketFactory();
|
|
|
|
SocketFactory getSocketFactory();
|
|
|
|
}
|
|
]]></programlisting>
|
|
</para>
|
|
<para>
|
|
Implementations of this interface are responsible for obtaining references to
|
|
<classname>ServerSocketFactory</classname> and <classname>SocketFactory</classname>.
|
|
Two implementations are provided; the first is <classname>DefaultTcpNetSocketFactorySupport</classname>
|
|
for non-SSL sockets (when no 'ssl-context-support' attribute is defined); this simply
|
|
uses the JDK's default factories. The second implementation is
|
|
<classname>DefaultTcpNetSSLSocketFactorySupport</classname>; this is used, by default,
|
|
when an 'ssl-context-support' attribute is defined; it uses the <classname>SSLContext</classname>
|
|
created by that bean to create the socket factories.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
This interface only applies if <classname>using-nio</classname> is "false"; socket factories
|
|
are not used by NIO.
|
|
</para>
|
|
</note>
|
|
<para><programlisting language="java"><![CDATA[public interface TcpSocketSupport {
|
|
|
|
void postProcessServerSocket(ServerSocket serverSocket);
|
|
|
|
void postProcessSocket(Socket socket);
|
|
|
|
]]></programlisting>
|
|
</para>
|
|
<para>
|
|
Implementations of this interface can modify sockets after they are created, and after
|
|
all configured attributes have been applied, but before the sockets are used. This applies
|
|
whether or not NIO is being used. For example,
|
|
you could use an implementation of this interface to modify the supported cipher suites on
|
|
an SSL socket, or you could add a listener that gets notified after SSL handshaking is
|
|
complete. The sole implementation provided by the framework is the
|
|
<classname>DefaultTcpSocketSupport</classname> which does not modify the sockets in
|
|
any way
|
|
</para>
|
|
<para>
|
|
To supply your own implementation of <classname>TcpSocketFactorySupport</classname> or
|
|
<classname>TcpSocketSupport</classname>, provide the connection factory with references to
|
|
beans of your custom type using the <classname>socket-factory-support</classname> and
|
|
<classname>socket-support</classname> attributes, respectively.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="ip-endpoint-reference">
|
|
<title>IP Configuration Attributes</title>
|
|
<para>
|
|
<table id="connection-factory-attributes">
|
|
<title>Connection Factory Attributes</title>
|
|
<tgroup cols="5">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="0.4*" align="center"/>
|
|
<colspec colnum="3" colname="col3" colwidth="0.4*" align="center"/>
|
|
<colspec colnum="4" colname="col4" colwidth="1*"/>
|
|
<colspec colnum="5" colname="col5" colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="center">Client?</entry>
|
|
<entry align="center">Server?</entry>
|
|
<entry align="center">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>type</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>client, server</entry>
|
|
<entry>Determines whether the connection factory is a client or server.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>host</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry></entry>
|
|
<entry>The host name or ip address of the destination.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>port</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>The port.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>serializer</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>An implementation of <classname>Serializer</classname> used to serialize
|
|
the payload. Defaults to <classname>ByteArrayCrLfSerializer</classname></entry>
|
|
</row>
|
|
<row>
|
|
<entry>deserializer</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>An implementation of <classname>Deserializer</classname> used to deserialize
|
|
the payload. Defaults to <classname>ByteArrayCrLfSerializer</classname></entry>
|
|
</row>
|
|
<row>
|
|
<entry>using-nio</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not connection uses NIO. Refer to the java.nio
|
|
package for more information.
|
|
See <xref linkend="note_nio" />.
|
|
Default false.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>using-direct-buffers</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>When using NIO, whether or not the connection uses direct buffers.
|
|
Refer to <classname>java.nio.ByteBuffer</classname> documentation for
|
|
more information. Must be false if using-nio is false. </entry>
|
|
</row>
|
|
<row>
|
|
<entry>apply-sequence</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>When using NIO, it may be necessary to resequence messages. When this
|
|
attribute is set to true, <emphasis>correlationId</emphasis> and
|
|
<emphasis>sequenceNumber</emphasis> headers will be added to
|
|
received messages.
|
|
See <xref linkend="note_nio" />.
|
|
Default false.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-timeout</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Defaults to 0 (infinity), except for
|
|
server connection factories with single-use="true".
|
|
In that case, it
|
|
defaults to the default reply timeout (10 seconds).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-send-buffer-size</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket. setSendBufferSize()</classname>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-receive-buffer- size</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket. setReceiveBufferSize()</classname>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-keep-alive</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>See <classname>java.net.Socket. setKeepAlive()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-linger</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Sets linger to true with supplied value.
|
|
See <classname>java.net.Socket. setSoLinger()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-tcp-no-delay</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>See <classname>java.net.Socket. setTcpNoDelay()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-traffic-class</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket. setTrafficClass()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>local-address</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>On a multi-homed system, specifies an IP address
|
|
for the interface to which the socket will be bound.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>task-executor</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>
|
|
Specifies a specific Executor to be used for socket handling. If not supplied, an internal
|
|
cached thread executor will be used. Needed on some platforms that require the use of specific
|
|
task executors such as a WorkManagerTaskExecutor.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>single-use</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Specifies whether a connection can be used for multiple messages.
|
|
If true, a new connection will be used for each message.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>pool-size</entry>
|
|
<entry>N</entry>
|
|
<entry>N</entry>
|
|
<entry></entry>
|
|
<entry>This attribute is no longer used. For backward
|
|
compatibility, it sets the backlog but users should
|
|
use backlog to specify the
|
|
connection backlog in server factories</entry>
|
|
</row>
|
|
<row>
|
|
<entry>backlog</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Sets the connection backlog for server factories.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>lookup-host</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
Specifies whether reverse lookups are done on IP addresses to convert to host names
|
|
for use in message headers. If false, the IP address is used instead. Defaults to true.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>interceptor-factory-chain</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <xref linkend="ip-interceptors"/> </entry>
|
|
</row>
|
|
<row>
|
|
<entry>ssl-context-support</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <xref linkend="ssl-tls"/> </entry>
|
|
</row>
|
|
<row>
|
|
<entry>socket-factory-support</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <xref linkend="ssl-tls"/> </entry>
|
|
</row>
|
|
<row>
|
|
<entry>socket-support</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <xref linkend="ssl-tls"/> </entry>
|
|
</row>
|
|
<row>
|
|
<entry>read-delay</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>long > 0</entry>
|
|
<entry>The delay (in milliseconds) before retrying a read after the previous attempt
|
|
failed due to insufficient threads. Default 100.
|
|
Only applies if <code>using-nio</code> is <code>true</code>.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="ip-ib-adapter-attributes">
|
|
<title>UDP Inbound Channel Adapter Attributes</title>
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col4" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col5" colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="center">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>port</entry>
|
|
<entry></entry>
|
|
<entry>The port on which the adapter listens.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>multicast</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not the udp adapter uses multicast.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>multicast-address</entry>
|
|
<entry></entry>
|
|
<entry>When multicast is true, the multicast address to which the adapter
|
|
joins.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>pool-size</entry>
|
|
<entry></entry>
|
|
<entry>Specifies the concurrency. Specifies how many packets can
|
|
be handled concurrently.
|
|
It only applies if task-executor is not configured.
|
|
Defaults to 5.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>task-executor</entry>
|
|
<entry></entry>
|
|
<entry>
|
|
Specifies a specific Executor to be used for socket handling. If not supplied, an internal
|
|
pooled executor will be used. Needed on some platforms that require the use of specific
|
|
task executors such as a WorkManagerTaskExecutor. See pool-size for thread
|
|
requirements.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>receive-buffer-size</entry>
|
|
<entry></entry>
|
|
<entry>The size of the buffer used to receive DatagramPackets.
|
|
Usually set to the MTU size. If a smaller buffer is used than the
|
|
size of the sent packet, truncation can occur. This can be detected
|
|
by means of the check-length attribute..</entry>
|
|
</row>
|
|
<row>
|
|
<entry>check-length</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not a udp adapter expects a data length field in the
|
|
packet received. Used to detect packet truncation.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-timeout</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.DatagramSocket</classname>
|
|
setSoTimeout() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-send-buffer-size</entry>
|
|
<entry></entry>
|
|
<entry>Used for udp acknowledgment packets. See <classname>java.net.DatagramSocket</classname>
|
|
setSendBufferSize() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-receive-buffer- size</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.DatagramSocket</classname>
|
|
setReceiveBufferSize() for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>local-address</entry>
|
|
<entry></entry>
|
|
<entry>On a multi-homed system, specifies an IP address
|
|
for the interface to which the socket will be bound.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>error-channel</entry>
|
|
<entry></entry>
|
|
<entry>If an Exception is thrown by a downstream
|
|
component, the MessagingException message containing the exception
|
|
and failed message is sent to this channel.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>lookup-host</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
Specifies whether reverse lookups are done on IP addresses to convert to host names
|
|
for use in message headers. If false, the IP address is used instead. Defaults to true.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="ip-ob-adapter-attributes">
|
|
<title>UDP Outbound Channel Adapter Attributes</title>
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col4" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col5" colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="center">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>host</entry>
|
|
<entry></entry>
|
|
<entry>The host name or ip address of the destination. For multicast udp
|
|
adapters, the multicast address.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>port</entry>
|
|
<entry></entry>
|
|
<entry>The port on the destination.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>multicast</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not the udp adapter uses multicast.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>acknowledge</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not a udp adapter requires an acknowledgment from the destination.
|
|
when enabled, requires setting the following 4 attributes.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ack-host</entry>
|
|
<entry></entry>
|
|
<entry>When acknowledge is true, indicates the host or ip address to which the
|
|
acknowledgment should be sent. Usually the current host, but may be
|
|
different, for example when Network Address Transaction (NAT) is
|
|
being used.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ack-port</entry>
|
|
<entry></entry>
|
|
<entry>When acknowledge is true, indicates the port to which the
|
|
acknowledgment should be sent. The adapter listens on this port for
|
|
acknowledgments.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ack-timeout</entry>
|
|
<entry></entry>
|
|
<entry>When acknowledge is true, indicates the time in milliseconds that the
|
|
adapter will wait for an acknowledgment. If an acknowledgment is not
|
|
received in time, the adapter will throw an exception.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>min-acks-for- success</entry>
|
|
<entry></entry>
|
|
<entry>Defaults to 1. For multicast adapters, you can set this to a larger
|
|
value, requiring acknowledgments from multiple destinations.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>check-length</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not a udp adapter includes a data length field in the
|
|
packet sent to the destination.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>time-to-live</entry>
|
|
<entry></entry>
|
|
<entry>For multicast adapters, specifies the time to live attribute for
|
|
the <classname>MulticastSocket</classname>; controls the scope
|
|
of the multicasts. Refer to the Java API
|
|
documentation for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-timeout</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.DatagramSocket</classname>
|
|
setSoTimeout() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-send-buffer-size</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.DatagramSocket</classname>
|
|
setSendBufferSize() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-receive-buffer- size</entry>
|
|
<entry></entry>
|
|
<entry>Used for udp acknowledgment packets. See <classname>java.net.DatagramSocket</classname>
|
|
setReceiveBufferSize() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>local-address</entry>
|
|
<entry></entry>
|
|
<entry>On a multi-homed system, for the UDP adapter, specifies an IP address
|
|
for the interface to which the socket will be bound for reply messages.
|
|
For a multicast adapter it is also used to determine which interface
|
|
the multicast packets will be sent over.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>task-executor</entry>
|
|
<entry></entry>
|
|
<entry>
|
|
Specifies a specific Executor to be used for acknowledgment handling. If not supplied, an internal
|
|
single threaded executor will be used. Needed on some platforms that require the use of specific
|
|
task executors such as a WorkManagerTaskExecutor. One thread will be dedicated to handling
|
|
acknowledgments (if the acknowledge option is true).</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="tcp-ib-adapter-attributes">
|
|
<title>TCP Inbound Channel Adapter Attributes</title>
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col3" colwidth="3*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="left">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>channel</entry>
|
|
<entry></entry>
|
|
<entry>The channel to which inbound messages will be sent.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>connection-factory</entry>
|
|
<entry></entry>
|
|
<entry>If the connection factory has a type 'server', the factory is 'owned'
|
|
by this adapter. If it has a type 'client', it is 'owned' by an
|
|
outbound channel adapter and this adapter will receive any
|
|
incoming messages on the connection created by the
|
|
outbound adapter.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>error-channel</entry>
|
|
<entry></entry>
|
|
<entry>If an Exception is thrown by a downstream
|
|
component, the MessagingException message containing the exception
|
|
and failed message is sent to this channel.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>client-mode</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
When true, the inbound adapter will act as a client, with respect to establishing
|
|
the connection and then receive incoming messages on that connection. Default = false.
|
|
Also see <emphasis>retry-interval</emphasis> and <emphasis>scheduler</emphasis>.
|
|
The connection factory must be of type 'client' and have <emphasis>single-use</emphasis>
|
|
set to false.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>retry-interval</entry>
|
|
<entry></entry>
|
|
<entry>
|
|
When in <emphasis>client-mode</emphasis>, specifies the number of milliseconds
|
|
to wait between connection attempts, or after a connection failure. Default 60,000
|
|
(60 seconds).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>scheduler</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
Specifies a <classname>TaskScheduler</classname> to use for managing the
|
|
<emphasis>client-mode</emphasis> connection. Defaults to a
|
|
<classname>ThreadPoolTaskScheduler</classname> with a pool size of `.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="tcp-ob-adapter-attributes">
|
|
<title>TCP Outbound Channel Adapter Attributes</title>
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col3" colwidth="3*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="left">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>channel</entry>
|
|
<entry></entry>
|
|
<entry>The channel on which outbound messages arrive.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>connection-factory</entry>
|
|
<entry></entry>
|
|
<entry>If the connection factory has a type 'client', the factory is
|
|
'owned' by this adapter. If it has a type 'server', it is 'owned'
|
|
by an inbound channel adapter and this adapter will attempt
|
|
to correlate messages to the connection on which an
|
|
original inbound message was received. </entry>
|
|
</row>
|
|
<row>
|
|
<entry>client-mode</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
When true, the outbound adapter will attempt to establish the connection as
|
|
soon as it is started. When false, the connection is established when
|
|
the first message is sent. Default = false.
|
|
Also see <emphasis>retry-interval</emphasis> and <emphasis>scheduler</emphasis>.
|
|
The connection factory must be of type 'client' and have <emphasis>single-use</emphasis>
|
|
set to false.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>retry-interval</entry>
|
|
<entry></entry>
|
|
<entry>
|
|
When in <emphasis>client-mode</emphasis>, specifies the number of milliseconds
|
|
to wait between connection attempts, or after a connection failure. Default 60,000
|
|
(60 seconds).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>scheduler</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
Specifies a <classname>TaskScheduler</classname> to use for managing the
|
|
<emphasis>client-mode</emphasis> connection. Defaults to a
|
|
<classname>ThreadPoolTaskScheduler</classname> with a pool size of `.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="tcp-ib-gateway-attributes">
|
|
<title>TCP Inbound Gateway Attributes</title>
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col3" colwidth="3*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="left">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>connection-factory</entry>
|
|
<entry></entry>
|
|
<entry>The connection factory must be of type server. </entry>
|
|
</row>
|
|
<row>
|
|
<entry>request-channel</entry>
|
|
<entry></entry>
|
|
<entry>The channel to which incoming messages will be sent.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>reply-channel</entry>
|
|
<entry></entry>
|
|
<entry>The channel on which reply messages may arrive. Usually replies will
|
|
arrive on a temporary reply channel added to the inbound message
|
|
header</entry>
|
|
</row>
|
|
<row>
|
|
<entry>reply-timeout</entry>
|
|
<entry></entry>
|
|
<entry>The time in milliseconds for which the gateway will wait for a reply.
|
|
Default 1000 (1 second).</entry>
|
|
</row>
|
|
<row>
|
|
<entry>error-channel</entry>
|
|
<entry></entry>
|
|
<entry>If an Exception is thrown by a downstream
|
|
component, the MessagingException message containing the exception
|
|
and failed message is sent to this channel;
|
|
any reply from that flow will then be returned as a response by
|
|
the gateway.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>client-mode</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
When true, the inbound gateway will act as a client, with respect to establishing
|
|
the connection and then receive (and reply to) incoming messages on that connection.
|
|
Default = false.
|
|
Also see <emphasis>retry-interval</emphasis> and <emphasis>scheduler</emphasis>.
|
|
The connection factory must be of type 'client' and have <emphasis>single-use</emphasis>
|
|
set to false.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>retry-interval</entry>
|
|
<entry></entry>
|
|
<entry>
|
|
When in <emphasis>client-mode</emphasis>, specifies the number of milliseconds
|
|
to wait between connection attempts, or after a connection failure. Default 60,000
|
|
(60 seconds).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>scheduler</entry>
|
|
<entry>true, false</entry>
|
|
<entry>
|
|
Specifies a <classname>TaskScheduler</classname> to use for managing the
|
|
<emphasis>client-mode</emphasis> connection. Defaults to a
|
|
<classname>ThreadPoolTaskScheduler</classname> with a pool size of `.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="tcp-ob-gateway-attributes">
|
|
<title>TCP Outbound Gateway Attributes</title>
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col3" colwidth="3*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="left">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>connection-factory</entry>
|
|
<entry></entry>
|
|
<entry>The connection factory must be of type client. </entry>
|
|
</row>
|
|
<row>
|
|
<entry>request-channel</entry>
|
|
<entry></entry>
|
|
<entry>The channel on which outgoing messages will arrive.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>reply-channel</entry>
|
|
<entry></entry>
|
|
<entry>Optional. The channel to which reply messages may be sent if the
|
|
original outbound message did not contain a reply channel header.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>remote-timeout</entry>
|
|
<entry></entry>
|
|
<entry>The time in milliseconds for which the gateway will wait for a reply from the
|
|
remote system.
|
|
Default: Same value as reply-timeout, if specified, or 10000 (10 seconds) otherwise.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>request-timeout</entry>
|
|
<entry></entry>
|
|
<entry>If a single-use connection factory is not being used, The time in milliseconds
|
|
for which the gateway will wait to get access to the shared connection.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>reply-timeout</entry>
|
|
<entry></entry>
|
|
<entry>The time in milliseconds for which the gateway will wait when sending the reply
|
|
to the reply-channel. Only applies if the reply-channel might block, such as a
|
|
bounded QueueChannel that is currently full.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</para>
|
|
</section>
|
|
<section id="ip-msg-headers">
|
|
<title>IP Message Headers</title>
|
|
<para>
|
|
The following <code>MessageHeader</code>s are used by this module:
|
|
</para>
|
|
<table id="ip-msg-headers-tbl">
|
|
<tgroup cols="3">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1*"/>
|
|
<colspec colnum="3" colname="col3"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Header Name</entry>
|
|
<entry align="center">IpHeaders Constant</entry>
|
|
<entry align="left">Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>ip_hostname</entry>
|
|
<entry>HOSTNAME</entry>
|
|
<entry>
|
|
The host name from which a TCP message or UDP packet was received. If
|
|
<code>lookupHost</code> is <code>false</code>, this will contain the ip address.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_address</entry>
|
|
<entry>IP_ADDRESS</entry>
|
|
<entry>The ip address from which a TCP message or UDP packet was received.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_port</entry>
|
|
<entry>PORT</entry>
|
|
<entry>The remote port for a UDP packet.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_ackTo</entry>
|
|
<entry>ACKADDRESS</entry>
|
|
<entry>
|
|
The remote ip address to which UDP application-level acks will be sent. The
|
|
framework includes acknowledgment information in the data packet.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_ackId</entry>
|
|
<entry>ACK_ID</entry>
|
|
<entry>
|
|
A correlation id for UDP application-level acks. The
|
|
framework includes acknowledgment information in the data packet.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_tcp_remotePort</entry>
|
|
<entry>REMOTE_PORT</entry>
|
|
<entry>The remote port for a UDP packet.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_connectionId</entry>
|
|
<entry>CONNECTION_ID</entry>
|
|
<entry>
|
|
A unique identifier for a TCP connection; set by the framework for
|
|
inbound messages; when sending to a server-side inbound
|
|
channel adapter, or replying to an inbound gateway, this header is
|
|
required so the endpoint can determine which connection to send
|
|
the message to.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ip_actualConnectionId</entry>
|
|
<entry>ACTUAL_CONNECTION_ID</entry>
|
|
<entry>
|
|
For information only - when using a cached or failover client connection
|
|
factory, contains the actual underlying connection id.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</section>
|
|
</chapter>
|