<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="channel-adapter"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Channel Adapter</title>
  <para>
    A Channel Adapter is a Message Endpoint that enables connecting a single sender or receiver to a Message Channel.
    Spring Integration provides a number of adapters out of the box to support various transports, such as JMS, File,
    HTTP, Web Services, Mail, and more. Those will be discussed in upcoming chapters of this reference guide. However, this
    chapter focuses on the simple but flexible Method-invoking Channel Adapter support. There are both inbound and
    outbound adapters, and each may be configured with XML elements provided in the core namespace. These provide an
    easy way to extend Spring Integration as long as you have a method that can be invoked as either a source or
    destination.
  </para>

  <section id="channel-adapter-namespace-inbound">
    <title>Configuring Inbound Channel Adapter</title>
    <para>
      An "inbound-channel-adapter" element can invoke any method on a Spring-managed Object and send a non-null return
      value to a <interfacename>MessageChannel</interfacename> after converting it to a <classname>Message</classname>.
      When the adapter's subscription is activated, a poller will attempt to receive messages from the source. The
      poller will be scheduled with the <interfacename>TaskScheduler</interfacename> according to the provided
      configuration. To configure the polling interval or cron expression for an individual channel-adapter,
      provide a 'poller' element with one of the scheduling attributes, such as 'fixed-rate' or 'cron'.
      <programlisting language="xml"><![CDATA[<inbound-channel-adapter ref="source1" method="method1" channel="channel1">
    <poller fixed-rate="5000"/>
</inbound-channel-adapter>

<inbound-channel-adapter ref="source2" method="method2" channel="channel2">
    <poller cron="30 * 9-17 * * MON-FRI"/>
</channel-adapter>]]></programlisting>
    </para>
    <note>
      <para>
        If no poller is provided, then a single default poller must be registered within the context.
        See <xref linkend="endpoint-namespace"/> for more detail.
      </para>
    </note>
    <important>
    	<para><emphasis>Poller Configuration</emphasis> </para>
    	<para>
    	Some <code>inbound-channel-adapter</code> types are backed by a <classname>SourcePollingChannelAdapter</classname> which 
    	means they contain Poller configuration which will poll the <classname>MessageSource</classname> (invoke a custom method 
    	which produces the value that becomes a <classname>Message</classname> payload) based on the configuration 
    	specified in the Poller. 
    	</para>
    	<para>For example:
    	
    	<programlisting language="xml"><![CDATA[<poller max-messages-per-poll="1" fixed-rate="1000"/>

<poller max-messages-per-poll="10" fixed-rate="1000"/>]]></programlisting>
		In the the first configuration the polling task will be invoked once per poll and during such task (poll) 
		the method (which results in the production of the Message) will be invoked once based on the 
		<code>max-messages-per-poll</code> attribute value. In the second configuration the polling task will be invoked 
		10 times per poll or until it returns 'null' thus possibly producing 10 Messages per poll while each poll happens 
		at 1 second intervals.
		However what if the configuration looks like this:
		<programlisting language="xml"><![CDATA[<poller fixed-rate="1000"/>]]></programlisting>
		Note there is no <code>max-messages-per-poll</code> specified. As you'll learn later the identical poller configuration 
		in the <classname>PollingConsumer</classname> (e.g., service-activator, filter, router etc.) would have a default 
		value of -1 for <code>max-messages-per-poll</code> which means "execute poling task non-stop unless polling method 
		returns null (e.g., no more Messages in the QueueChannel)" and then sleep for 1 second.
    	</para>
    	<para>
    	However in the SourcePollingChannelAdapter it is a bit different.
		The default value for <code>max-messages-per-poll</code> will be set to 1 by default unless you explicitly set it to 
		a negative value (e.g., -1). It is done so to make sure that poller can react to a LifeCycle events (e.g., start/stop) 
        and prevent it from potentially spinning in the infinite loop if the implementation of the custom 
		method of the <classname>MessageSource</classname> has a potential to never return null and happened to be non-interruptible.
    	</para>
    	<para>
    	However if you are sure that your method can return null and you need the behavior where you want to poll 
    	for as many sources as available per each poll, then you should explicitly set <code>max-messages-per-poll</code> 
    	to negative value.
		<programlisting language="xml"><![CDATA[<poller max-messages-per-poll="-1" fixed-rate="1000"/>]]></programlisting>

    	</para>
    	
    </important>
  </section>

  <section id="channel-adapter-namespace-outbound">
    <title>Configuring Outbound Channel Adapter</title>
    <para>
      An "outbound-channel-adapter" element can also connect a <interfacename>MessageChannel</interfacename> to any POJO consumer
      method that should be invoked with the payload of Messages sent to that channel.
      <programlisting language="xml"><![CDATA[<outbound-channel-adapter channel="channel1" ref="target" method="handle"/>

<beans:bean id="target" class="org.Foo"/>]]>
</programlisting>

      If the channel being adapted is a <interfacename>PollableChannel</interfacename>, provide a poller sub-element:
        <programlisting language="xml"><![CDATA[<outbound-channel-adapter channel="channel2" ref="target" method="handle">
    ]]><emphasis><![CDATA[<poller fixed-rate="3000"/>
]]></emphasis><![CDATA[
</outbound-channel-adapter>

<beans:bean id="target" class="org.Foo"/>
]]></programlisting>
    </para>
    <para>
      Using a "ref" attribute is generally recommended if the POJO consumer implementation can be reused
      in other <code>&lt;outbound-channel-adapter&gt;</code> definitions. However if the consumer implementation
      is only referenced by a single definition of the <code>&lt;outbound-channel-adapter&gt;</code>, you
      can define it as inner bean:
        <programlisting language="xml"><![CDATA[<outbound-channel-adapter channel="channel" method="handle">
        <beans:bean class="org.Foo"/>
    ]]><![CDATA[
</outbound-channel-adapter>
]]></programlisting>
    </para>
    <note>
    <para>
    Using both the "ref" attribute and an inner handler definition in the same <code>&lt;outbound-channel-adapter&gt;</code>
    configuration is not allowed as it creates an ambiguous condition. Such a configuration will result in an Exception
    being thrown.
    </para>
    </note>
    <para>
      Any Channel Adapter can be created without a "channel" reference in which case it will implicitly create an
      instance of <classname>DirectChannel</classname>. The created channel's name will match the "id" attribute
      of the &lt;inbound-channel-adapter/&gt; or &lt;outbound-channel-adapter&gt; element. Therefore, if the "channel"
      is not provided, the "id" is required.
    </para>
  </section>

</section>
