<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="content-enricher"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>Content Enricher</title>

    <section id="content-enricher-introduction">
        <title>Introduction</title>
	    <para>
		    At times you may have a requirement to enhance a request with more
		    information than was provided by the target system. The
		    <ulink url="http://www.eaipatterns.com/DataEnricher.html">Content Enricher</ulink>
		    pattern describes various scenarios as well as the component
		    (Enricher), which allows you to address such requirements.
	    </para>
        <para>
            The Spring Integration <code>Core</code> module includes 2 enrichers:
        </para>
        <itemizedlist>
            <listitem><link linkend='header-enricher'>Header Enricher</link></listitem>
            <listitem><link linkend='payload-enricher'>Payload Enricher</link></listitem>
        </itemizedlist>
        <para>
	        Furthermore, several <emphasis>Adapter specific Header Enrichers</emphasis>
	        are included as well:
	    </para>
        <itemizedlist>
            <listitem><link linkend='xml-xpath-header-enricher'>XPath Header Enricher (XML Module)</link></listitem>
            <listitem><link linkend='mail-namespace'>Mail Header Enricher (Mail Module)</link></listitem>
            <listitem><link linkend='xmpp-message-outbound-channel-adapter'>XMPP Header Enricher (XMPP Module)</link></listitem>
        </itemizedlist>
	    <para>
	        Please go to the adapter specific sections of this reference manual
	        to learn more about those adapters.
	    </para>
    </section>

    <section id="header-enricher">
        <title>Header Enricher</title>

	    <para>
		    If you only need to add headers to a Message, and they are not
		    dynamically determined by the Message content, then referencing a
		    custom implementation of a Transformer may be overkill. For that reason,
		    Spring Integration provides support for the <emphasis>Header Enricher</emphasis>
		    pattern. It is exposed via the <code>&lt;header-enricher&gt;</code> element.
	    </para>

	    <programlisting language="xml"><![CDATA[<int:header-enricher input-channel="in" output-channel="out">
     <int:header name="foo" value="123"/>
     <int:header name="bar" ref="someBean"/>
</int:header-enricher>]]></programlisting>

	    <para>
	        The <emphasis>Header Enricher</emphasis> also provides helpful sub-elements
	        to set well-known header names.
	    </para>

        <programlisting language="xml"><![CDATA[<int:header-enricher input-channel="in" output-channel="out">
		<int:error-channel ref="applicationErrorChannel"/>
		<int:reply-channel ref="quoteReplyChannel"/>
		<int:correlation-id value="123"/>
		<int:priority value="HIGHEST"/>
		<int:header name="bar" ref="someBean"/>
</int:header-enricher>]]></programlisting>

		<para>
			In the above configuration you can clearly see that for well-known
			headers such as <code>errorChannel</code>, <code>correlationId</code>,
			<code>priority</code>, <code>replyChannel</code>etc., instead of
			using generic <emphasis>&lt;header&gt;</emphasis> sub-elements where
			you would have to provide both header 'name' and 'value', you can use
			convenient sub-elements to set those values directly.
	    </para>

	    <para>
	    	<emphasis>POJO Support</emphasis>
	    </para>

	    <para>
	        Often a header value cannot be defined statically and has to be
	        determined dynamically based on some content in the Message. That is why
	        <emphasis>Header Enricher</emphasis> allows you to also specify a bean
	        reference using the <code>ref</code> and <code>method</code> attribute.
	        The specified method will calculate the header value. Let's look at
	        the following configuration:
	    </para>

        <programlisting language="xml"><![CDATA[<int:header-enricher input-channel="in" output-channel="out">
    <int:header name="foo" method="computeValue" ref="myBean"/>
</int:header-enricher>

<bean id="myBean" class="foo.bar.MyBean"/>]]></programlisting>

        <programlisting language="java"><![CDATA[public class MyBean {
    public String computeValue(String payload){
        return payload.toUpperCase() + "_US";
    }

}]]></programlisting>

        <para>
            You can also configure your POJO as inner bean:
        </para>

<programlisting language="xml"><![CDATA[<int:header-enricher  input-channel="inputChannel" output-channel="outputChannel">
	<int:header name="some_header">
            <bean class="org.MyEnricher"/>
        </int:header>
</int:header-enricher>]]></programlisting>
	    <para>
	        as well as point to a Groovy script:
	    </para>

        <programlisting language="xml"><![CDATA[<int:header-enricher  input-channel="inputChannel" output-channel="outputChannel">
		<int:header name="some_header">
            <int-groovy:script location="org/SampleGroovyHeaderEnricher.groovy"/>
        </int:header>
</int:header-enricher>]]></programlisting>

	    <para>
	    	<emphasis>SpEL Support</emphasis>
	    </para>
	    <para>
	        In Spring Integration 2.0 we have introduced the convenience of the
	        <ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html">Spring Expression Language (SpEL)</ulink>
	        to help configure many different components. The <emphasis>Header
	        Enricher</emphasis> is one of them.

		    Looking again at the POJO example above, you can see that the computation
		    logic to determine the header value is actually pretty simple. A natural
		    question would be: "is there a simpler way to accomplish this?". That
		    is where SpEL shows its true power.
	    </para>

	    <programlisting language="xml"><![CDATA[<int:header-enricher input-channel="in" output-channel="out">
	<int:header name="foo" expression="payload.toUpperCase() + '_US'"/>
</int:header-enricher>]]></programlisting>

	    <para>
			As you can see, by using SpEL for such simple cases, we no longer have
			to provide a separate class and configure it in the application context.
			All we need is the <emphasis>expression</emphasis> attribute configured
			with a valid SpEL expression. The 'payload' and 'headers' variables
			are bound to the SpEL Evaluation Context, giving you full access to
			the incoming Message.
	    </para>

    </section>

    <section id="payload-enricher">
        <title>Payload Enricher</title>
        <para>
            In certain situations the Header Enricher, as discussed above, may
            not be sufficient and payloads themselves may have to be enriched
            with additional information. For example, order messages that enter
            the Spring Integration messaging system have to look up the order's
            customer based on the provided customer number and then enrich the original
            payload with that information.
        </para>
        <para>
            Since Spring Integration 2.1, the Payload Enricher is provided. A
            Payload Enricher defines an endpoint that passes a <interfacename>
            Message</interfacename> to the exposed request channel and then
            expects a reply message. The reply message then becomes the root object
            for evaluation of expressions to enrich the target payload.
        </para>
        <para>
            The Payload Enricher provides full XML namespace support via the <code>enricher</code>
            element. In order to send request messages, the payload enricher has a
            <code>request-channel</code> attribute that allows you to dispatch
            messages to a request channel.
        </para>
        <para>
            Basically by defining the request channel, the Payload Enricher acts
            as a Gateway, waiting for the message that were sent to the request
            channel to return, and the Enricher then augments the message's payload with
            the data provided by the reply message.
        </para>
        <para>
            When sending messages to the request channel you also have the option
            to only send a subset of the original payload using the
            <code>request-payload-expression</code> attribute.
        </para>
        <para>
            The enriching of payloads is configured through SpEL expressions,
            providing users with a maximum degree of flexibility. Therefore, users
            are not only able to enrich payloads with direct values from the reply channel's
            <interfacename>Message</interfacename>, but they can use SpEL
            expressions to extract a subset from that Message, only, or to apply
            addtional inline transformations, allowing them to further manipulate
            the data.
        </para>
        <para>
            If you only need to enrich payloads with static values, you don't have
            to provide the <code>request-channel</code> attribute.
        </para>
        <note>
            Enrichers are a variant of Transformers and in many cases you could
            use a Payload Enricher or a generic Transformer implementation to add
            additional data to your messages payloads. Thus, familiarize yourself
            with all transformation-capable components that are provided by Spring
            Integration and carefully select the implementation that semantically
            fits your business case best.
        </note>

        <section id="payload-enricher-configuration">
            <title>Configuration</title>

	        <para>
	            Below, please find an overview of all available configuration options that
	            are available for the payload enricher:
	        </para>

            <programlisting language="xml"><![CDATA[<int:enricher request-channel=""                          ]]><co id="payload-enricher01-co" linkends="payload-enricher01" /><![CDATA[
              auto-startup="true"                         ]]><co id="payload-enricher02-co" linkends="payload-enricher02" /><![CDATA[
              id=""                                       ]]><co id="payload-enricher03-co" linkends="payload-enricher03" /><![CDATA[
              order=""                                    ]]><co id="payload-enricher04-co" linkends="payload-enricher04" /><![CDATA[
              output-channel=""                           ]]><co id="payload-enricher05-co" linkends="payload-enricher05" /><![CDATA[
              request-payload-expression=""               ]]><co id="payload-enricher06-co" linkends="payload-enricher06" /><![CDATA[
              reply-channel=""                            ]]><co id="payload-enricher07-co" linkends="payload-enricher07" /><![CDATA[
              send-timeout=""                             ]]><co id="payload-enricher08-co" linkends="payload-enricher08" /><![CDATA[
              should-clone-payload="false">               ]]><co id="payload-enricher09-co" linkends="payload-enricher09" /><![CDATA[
    <int:poller></int:poller>                             ]]><co id="payload-enricher10-co" linkends="payload-enricher10" /><![CDATA[
    <int:property name="" expression=""/>  ]]><co id="payload-enricher11-co" linkends="payload-enricher11" /><![CDATA[
    <int:property name="" value=""/>
</int:enricher>]]></programlisting>

	        <para>
	            <calloutlist>
	                <callout arearefs="payload-enricher01-co" id="payload-enricher01">
	                    <para>
	                        Channel to which a Message will be sent to get the data to use for enrichment.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher02-co" id="payload-enricher02">
	                    <para>
	                        Lifecycle attribute signaling if this component should be
	                        started during Application Context startup. Defaults to true.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher03-co" id="payload-enricher03">
	                    <para>
	                        Id of the underlying bean definition, which is either
	                        an <classname>EventDrivenConsumer</classname> or a
	                        <classname>PollingConsumer</classname>.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher04-co" id="payload-enricher04">
	                    <para>
	                        Specifies the order for invocation when this endpoint is
	                        connected as a subscriber to a channel. This is particularly
	                        relevant when that channel is using a "failover" dispatching
	                        strategy. It has no effect when this endpoint itself is a
	                        Polling Consumer for a channel with a queue.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher05-co" id="payload-enricher05">
	                    <para>
	                        Identifies the Message channel where a Message will
	                        be sent after it is being processed by this endpoint.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher06-co" id="payload-enricher06">
	                    <para>
	                        By default the original message's payload will be used as
	                        payload that will be send to the <code>request-channel</code>.
	                        By specifying a SpEL expression as value for the
	                        <code>request-payload-expression</code> attribute, a
	                        subset of the original payload, a header value or any other
	                        resolvable SpEL expression can be used as the basis for the
	                        payload, that will be sent to the request-channel.
	                    </para>
	                    <para>
	                        For the Expression evaluation the full message is available
	                        as the 'root object'.
	                    </para>
	                    <para>
	                        For instance the following SpEL expressions (among others)
	                        are possible:
	                    </para>
	                    <itemizedlist>
	                        <listitem>payload.foo</listitem>
	                        <listitem>headers.foobar</listitem>
	                        <listitem>new java.util.Date()</listitem>
	                        <listitem>'foo' + 'bar'</listitem>
	                    </itemizedlist>
	                    <para>
	                        If more sophisticated logic is required (e.g. changing the
	                        message headers etc.) please use additional downstream transformers.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher07-co" id="payload-enricher07">
	                    <para>
	                        Channel where a reply Message is expected. This is optional; typically the auto-generated
	                        temporary reply channel is sufficient.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher08-co" id="payload-enricher08">
	                    <para>
	                        Maximum amount of time in milliseconds to wait when
	                        sending a message to the channel, if such channel may block.
	                    </para>
	                    <para>
	                        For example, a Queue Channel can block until space is
	                        available, if its maximum capacity has been reached. Internally
	                        the send timeout is set on the <classname>MessagingTemplate</classname>
	                        and ultimately applied when invoking the send operation on the
	                        <interfacename>MessageChannel</interfacename>.
	                    </para>
	                    <para>
	                        By default the send timeout is set to '-1', which may cause
	                        the send operation on the <interfacename>MessageChannel</interfacename>,
	                        depending on the implementation, to block indefinitely.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher09-co" id="payload-enricher09">
	                    <para>
	                        Boolean value indicating whether any payload that implements
	                        <interfacename>Cloneable</interfacename> should be cloned
	                        prior to sending the Message to the request chanenl for
	                        acquiring the enriching data. The cloned version would be
	                        used as the target payload for the ultimate reply.
	                        Default is <code>false</code>.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher10-co" id="payload-enricher10">
	                    <para>
	                        Allows you to configure a Message Poller if this endpoint
	                        is a Polling Consumer.
	                        <emphasis>Optional</emphasis>.
	                    </para>
	                </callout>
	                <callout arearefs="payload-enricher11-co" id="payload-enricher11">
	                    <para>
                            Each <code>property</code> sub-element provides the
                            name of a property (via the mandatory <code>name</code>
                            attribute). That property should  be settable on the
                            target payload instance. Exactly one of the <code>value</code>
                            or <code>expression</code> attributes must be provided
                            as well. The former for a literal value to set, and the
                            latter for a SpEL expression to be evaluated. The root
                            object of the evaluation context is the Message that was
                            returned from the flow initiated by this enricher.
	                    </para>
	                </callout>
	            </calloutlist>
	        </para>

        </section>

        <section id="payload-enricher-examples">
            <title>Examples</title>

            <para>
	            Below, please find several examples of using a Payload Enricher
	            in various situations.
	        </para>

	        <para>
	            In the following example, a <classname>User</classname> object is passed
	            as the payload of the <interfacename>Message</interfacename>. The
	            <classname>User</classname> has several properties but only the
	            <code>username</code> is set initially. The Enricher's
	            <code>request-channel</code> attribute below is configured to
	            pass the <classname>User</classname> on to the <code>findUserServiceChannel</code>.
	        </para>
	        <para>
	            Through the implicitly set <code>reply-channel</code> a
	            <classname>User</classname> object is returned and using the
	            <code>property</code> sub-element, properties from the reply are
	            extracted and used to enrich the original payload.
	        </para>

            <programlisting language="xml"><![CDATA[<int:enricher id="findUserEnricher"
              input-channel="findUserEnricherChannel"
              request-channel="findUserServiceChannel">
    <int:property name="email"    expression="payload.email"/>
    <int:property name="password" expression="payload.password"/>
</int:enricher>]]></programlisting>

	        <note>
	            The code samples shown here, are part of the <emphasis>Spring
	            Integration Samples</emphasis> project. Please feel free to
	            check it out at:

	            <ulink url="https://github.com/SpringSource/spring-integration-samples"/>

	        </note>

	        <para><emphasis>How do I pass only a subset of data to the request channel?</emphasis></para>
	        <para>
	            Using a <code>request-payload-expression</code> attribute
	            a single property of the payload can be passed on to the request
	            channel instead of the full message. In the example below on the
	            username property is passed on to the request channel. Keep in mind,
	            that alwhough only the username is passed on, the resulting message
	            send to the request channel will contain the full set of
	            <classname>MessageHeaders</classname>.
	        </para>

            <programlisting language="xml"><![CDATA[<int:enricher id="findUserByUsernameEnricher"
              input-channel="findUserByUsernameEnricherChannel"
              request-channel="findUserByUsernameServiceChannel"
              request-payload-expression="payload.username">
    <int:property name="email"    expression="payload.email"/>
    <int:property name="password" expression="payload.password"/>
</int:enricher>]]></programlisting>

	        <para><emphasis>How can I enrich payloads that consist of Collection data?</emphasis></para>
	        <para>
	            In the following example, instead of a <classname>User</classname> object,
	            a <interfacename>Map</interfacename> is passed in. The
	            <interfacename>Map</interfacename> contains the username under the map
	            key <code>username</code>. Only the <code>username</code> is passed on
	            to the request channel. The reply contains a full <classname>User</classname> object, which
	            is ultimately added to the <interfacename>Map</interfacename> under the
	            <code>user</code> key.
	        </para>

            <programlisting language="xml"><![CDATA[<int:enricher id="findUserWithMapEnricher"
              input-channel="findUserWithMapEnricherChannel"
              request-channel="findUserByUsernameServiceChannel"
              request-payload-expression="payload.username">
    <int:property name="user"    expression="payload"/>
</int:enricher>]]></programlisting>

	        <para><emphasis>How can I enrich payloads with static information without using a request channel?</emphasis></para>
	        <para>
	           Here is an example that does not use a request channel at all,
	           but solely enriches the message's payload with static values. But please
	           be aware that the word 'static' is used loosly here. You can still use
	           SpEL expressions for setting those values.
	        </para>

            <programlisting language="xml"><![CDATA[<int:enricher id="userEnricher"
              input-channel="input">
    <int:property name="user.updateDate" expression="new java.util.Date()"/>
    <int:property name="user.firstName" value="foo"/>
    <int:property name="user.lastName"  value="bar"/>
    <int:property name="user.age"       value="42"/>
</int:enricher>]]></programlisting>

        </section>

    </section>
</section>
