[[amqp-outbound-channel-adapter]]
= Outbound Channel Adapter

The following example shows the available properties for an AMQP outbound channel adapter:

[tabs]
======
Java DSL::
+
[source,java,role="primary"]
----
@Bean
public IntegrationFlow amqpOutbound(AmqpTemplate amqpTemplate,
        MessageChannel amqpOutboundChannel) {
    return IntegrationFlow.from(amqpOutboundChannel)
            .handle(Amqp.outboundAdapter(amqpTemplate)
                        .routingKey("queue1")) // default exchange - route to queue 'queue1'
            .get();
}
----

Java::
+
[source,java,role="secondary"]
----
@Bean
@ServiceActivator(inputChannel = "amqpOutboundChannel")
public AmqpOutboundEndpoint amqpOutbound(AmqpTemplate amqpTemplate) {
    AmqpOutboundEndpoint outbound = new AmqpOutboundEndpoint(amqpTemplate);
    outbound.setRoutingKey("queue1"); // default exchange - route to queue 'queue1'
    return outbound;
}

@Bean
public MessageChannel amqpOutboundChannel() {
    return new DirectChannel();
}
----

XML::
+
[source,xml,role="secondary"]
----
<int-amqp:outbound-channel-adapter id="outboundAmqp"             <1>
                               channel="outboundChannel"         <2>
                               amqp-template="myAmqpTemplate"    <3>
                               exchange-name=""                  <4>
                               exchange-name-expression=""       <5>
                               order="1"                         <6>
                               routing-key=""                    <7>
                               routing-key-expression=""         <8>
                               default-delivery-mode""           <9>
                               confirm-correlation-expression="" <10>
                               confirm-ack-channel=""            <11>
                               confirm-nack-channel=""           <12>
                               confirm-timeout=""                <13>
                               wait-for-confirm=""               <14>
                               return-channel=""                 <15>
                               error-message-strategy=""         <16>
                               header-mapper=""                  <17>
                               mapped-request-headers=""         <18>
                               lazy-connect="true"               <19>
                               multi-send="false"/>              <20>
----
======

<1> The unique ID for this adapter.
Optional.
<2> Message channel to which messages should be sent to have them converted and published to an AMQP exchange.
Required.
<3> Bean reference to the configured AMQP template.
Optional (defaults to `amqpTemplate`).
<4> The name of the AMQP exchange to which messages are sent.
If not provided, messages are sent to the default, no-name exchange.
Mutually exclusive with 'exchange-name-expression'.
Optional.
<5> A SpEL expression that is evaluated to determine the name of the AMQP exchange to which messages are sent, with the message as the root object.
If not provided, messages are sent to the default, no-name exchange.
Mutually exclusive with 'exchange-name'.
Optional.
<6> The order for this consumer when multiple consumers are registered, thereby enabling load-balancing and failover.
Optional (defaults to `Ordered.LOWEST_PRECEDENCE [=Integer.MAX_VALUE]`).
<7> The fixed routing-key to use when sending messages.
By default, this is an empty `String`.
Mutually exclusive with 'routing-key-expression'.
Optional.
<8> A SpEL expression that is evaluated to determine the routing key to use when sending messages, with the message as the root object (for example, 'payload.key').
By default, this is an empty `String`.
Mutually exclusive with 'routing-key'.
Optional.
<9> The default delivery mode for messages: `PERSISTENT` or `NON_PERSISTENT`.
Overridden if the `header-mapper` sets the delivery mode.
If the Spring Integration message header `amqp_deliveryMode` is present, the `DefaultHeaderMapper` sets the value.
If this attribute is not supplied and the header mapper does not set it, the default depends on the underlying Spring AMQP `MessagePropertiesConverter` used by the `RabbitTemplate`.
If that is not customized at all, the default is `PERSISTENT`.
Optional.
<10> An expression that defines correlation data.
When provided, this configures the underlying AMQP template to receive publisher confirmations.
Requires a dedicated `RabbitTemplate` and a `CachingConnectionFactory` with the `publisherConfirms` property set to `true`.
When a publisher confirmation is received and correlation data is supplied, it is written to either the `confirm-ack-channel` or the `confirm-nack-channel`, depending on the confirmation type.
The payload of the confirmation is the correlation data, as defined by this expression.
The message has an 'amqp_publishConfirm' header set to `true` (`ack`) or `false` (`nack`).
Examples: `headers['myCorrelationData']` and `payload`.
Version 4.1 introduced the `amqp_publishConfirmNackCause` message header.
It contains the `cause` of a 'nack' for a publisher confirmation.
Starting with version 4.2, if the expression resolves to a `Message<?>` instance (such as `#this`), the message emitted on the `ack`/`nack` channel is based on that message, with the additional header(s) added.
Previously, a new message was created with the correlation data as its payload, regardless of type.
Also see xref:amqp/alternative-confirms-returns.adoc[Alternative Mechanism for Publisher Confirms and Returns].
Optional.
<11> The channel to which positive (`ack`) publisher confirms are sent.
The payload is the correlation data defined by the `confirm-correlation-expression`.
If the expression is `#root` or `#this`, the message is built from the original message, with the `amqp_publishConfirm` header set to `true`.
Also see xref:amqp/alternative-confirms-returns.adoc[Alternative Mechanism for Publisher Confirms and Returns].
Optional (the default is `nullChannel`).
<12> The channel to which negative (`nack`) publisher confirmations are sent.
The payload is the correlation data defined by the `confirm-correlation-expression` (if there is no `ErrorMessageStrategy` configured).
If the expression is `#root` or `#this`, the message is built from the original message, with the `amqp_publishConfirm` header set to `false`.
When there is an `ErrorMessageStrategy`, the message is an `ErrorMessage` with a `NackedAmqpMessageException` payload.
Also see xref:amqp/alternative-confirms-returns.adoc[Alternative Mechanism for Publisher Confirms and Returns].
Optional (the default is `nullChannel`).
<13> When set, the adapter will synthesize a negative acknowledgment (nack) if a publisher confirm is not received within this time in milliseconds.
Pending confirms are checked every 50% of this value, so the actual time a nack is sent will be between 1x and 1.5x this value.
Also see xref:amqp/alternative-confirms-returns.adoc[Alternative Mechanism for Publisher Confirms and Returns].
Default none (nacks will not be generated).
<14> When set to true, the calling thread will block, waiting for a publisher confirmation.
This requires a `RabbitTemplate` configured for confirms as well as a `confirm-correlation-expression`.
The thread will block for up to `confirm-timeout` (or 5 seconds by default).
If a timeout occurs, a `MessageTimeoutException` will be thrown.
If returns are enabled and a message is returned, or any other exception occurs while awaiting the confirmation, a `MessageHandlingException` will be thrown, with an appropriate message.
<15> The channel to which returned messages are sent.
When provided, the underlying AMQP template is configured to return undeliverable messages to the adapter.
When there is no `ErrorMessageStrategy` configured, the message is constructed from the data received from AMQP, with the following additional headers: `amqp_returnReplyCode`, `amqp_returnReplyText`, `amqp_returnExchange`, `amqp_returnRoutingKey`.
When there is an `ErrorMessageStrategy`, the message is an `ErrorMessage` with a `ReturnedAmqpMessageException` payload.
Also see xref:amqp/alternative-confirms-returns.adoc[Alternative Mechanism for Publisher Confirms and Returns].
Optional.
<16> A reference to an `ErrorMessageStrategy` implementation used to build `ErrorMessage` instances when sending returned or negatively acknowledged messages.
<17> A reference to an `AmqpHeaderMapper` to use when sending AMQP Messages.
By default, only standard AMQP properties (such as `contentType`) are copied to the Spring Integration `MessageHeaders`.
Any user-defined headers is not copied to the message by the default`DefaultAmqpHeaderMapper`.
Not allowed if 'request-header-names' is provided.
Optional.
<18> Comma-separated list of names of AMQP Headers to be mapped from the `MessageHeaders` to the AMQP Message.
Not allowed if the 'header-mapper' reference is provided.
The values in this list can also be simple patterns to be matched against the header names (e.g. `"\*"` or `"thing1*, thing2"` or `"*thing1"`).
<19> When set to `false`, the endpoint attempts to connect to the broker during application context initialization.
This allows "`fail fast`" detection of bad configuration but also causes initialization to fail if the broker is down.
When `true` (the default), the connection is established (if it does not already exist because some other component established it) when the first message is sent.
<20> When set to `true`, payloads of type `Iterable<Message<?>>` will be sent as discrete messages on the same channel within the scope of a single `RabbitTemplate` invocation.
Requires a `RabbitTemplate`.
When `wait-for-confirms` is true, `RabbitTemplate.waitForConfirmsOrDie()` is invoked after the messages have been sent.
With a transactional template, the sends will be performed in either a new transaction or one that has already been started (if present).

[IMPORTANT]
.return-channel
=====
Using a `return-channel` requires a `RabbitTemplate` with the `mandatory` property set to `true` and a `CachingConnectionFactory` with the `publisherReturns` property set to `true`.
When using multiple outbound endpoints with returns, a separate `RabbitTemplate` is needed for each endpoint.
=====

