AMQP 1.0 support for RabbitMQ
This plugin adds AMQP 1.0 support to RabbitMQ.
This is mostly a prototype, but it is supported. We describe it as a prototype since the amount of real world use and thus battle-testing it has received is not so large as that of the STOMP or MQTT plugins. Howver, bugs do get fixed as they are reported.
You can send and receive messages between 0-9-1 or 0-8 clients and 1.0 clients with broadly the same semantics as you would get with 0-9-1.
Building and configuring
The plugin uses the standard RabbitMQ plugin build environment; see http://www.rabbitmq.com/plugin-development.html.
It will listen on the standard AMQP port, 5672. To reconfigure this, do so as you would for 0-9-1. Clients connecting with 0-9-1 and 0-8 will continue to work on the same port.
The following two configuration options (which are specific to the AMQP 1.0 adapter)
are accepted in the
rabbitmq_amqp1_0 section of the configuration file.
AMQP 1.0 conceptually allows connections that are not authenticated
with SASL (i.e. where no username and password is supplied). By
default these will connect as the "guest" user. To change this, set
default_user to a string with the name of the user to use, or the
none to prevent unauthenticated connections.
The default virtual host can be specified using the
See the "Virtual Hosts" section below for a description.
protocol_strict_mode setting controls how strictly peers must conform
to the specification. The default is not to enforce strictness, which allows
non-fatal byte-counts in frames and inaccuracies in flow-control from peers.
Clients we have tested
The current field of AMQP 1.0 clients is somewhat limited. Therefore we have not achieved as much interoperability as we might like.
We have tested against:
SwiftMQ Java client  We have done most of our testing against this client and things seem to work.
QPid / Proton C client  We have successfully tested against the "proton" command line tool this client ships with.
QPid / Proton Java client  We have not been able to get this client to get as far as opening a network connection (tested against 0.2 and 0.4).
Windows Azure Service Bus  It seems that the URI scheme used by this client assumes that it is connecting to Azure; it does not seem to be possible to get it to connect to another server.
As new clients appear we will of course work on interoperability with them.
Interoperability with AMQP 0-9-1
This implementation as a plugin aims for useful interoperability with AMQP 0-9-1 clients. AMQP 1.0 messages can be far more structured than AMQP 0-9-1 messages, which simply have a payload of bytes.
The way we deal with this is that an AMQP 1.0 message with a single
data section will be transcoded to an AMQP 0-9-1 message with just the
bytes from that section, and vice versa. An AMQP 1.0 with any other
payload will keep exactly that payload (i.e., encoded AMQP 1.0
sections, concatenated), and for AMQP 0-9-1 clients the
basic.properties will contain the value
Thus, AMQP 0-9-1 clients may receive messages that they cannot understand (if they don't have an AMQP 1.0 codec handy, anyway); however, these will at least be labelled. AMQP 1.0 clients shall receive exactly what they expect.
Message properties, annotations, headers, etc.
The headers and properties map as follows:
AMQP 1.0 AMQP 0-9-1 Header Properties durable <---------------> delivery-mode  priority <---------------> priority ttl <---------------> expiration  first-acquirer  delivery-count  Properties message-id <---------------> message-id  user-id <---------------> user-id to  subject  reply-to <---------------> reply-to  correlation-id <---------------> correlation-id content-type <---------------> content-type content-encoding <---------------> content-encoding absolute-expiry-time  creation-time <---------------> timestamp Application headers <-------/-------> headers 
true if and only if
expiration is a shortstr; since RabbitMQ will expect this to be
an encoded string, we translate a
ttl to the string representation
of its integer value.
first-acquirer is true if and only if the
redelivered is false.
delivery-count is left null.
 AMQP 0-9-1 expects this to be a shortstr.
 See Routing and Addressing below.
absolute-expiry-time has no corresponding field in AMQP 0-9-1,
and is not supported in RabbitMQ in any case.
 The application headers section and the
headers are natural analogues. However, rather than try to transcode
an AMQP 1.0 map to an AMQP 0-9-1 field-table, currently we discard
application headers (of AMQP 1.0 messages) and headers (of AMQP 0-9-1
messages sent through to AMQP 1.0). In other words, the (AMQP 1.0)
application headers section is only available to AMQP 1.0 clients, and
the (AMQP 0-9-1) headers field is only available to AMQP 0-9-1
Note that properties (in both AMQP 1.0 and AMQP 0-9-1) and application properties (in AMQP 1.0) are immutable; however, this can only apply when the sending and receiving clients are using the same protocol.
Routing and Addressing
In AMQP 1.0 source and destination addresses are opaque values, and
each message may have a
subject field value.
For targets, addresses are:
= "/exchange/" X "/" RK Publish to exchange X with routing key RK | "/exchange/" X Publish to exchange X with message subject as routing key | "/topic/" RK Publish to amq.topic with routing key RK | "/amq/queue/" Q Publish to default exchange with routing key Q | "/queue/" Q Publish to default exchange with routing key Q | Q (no leading slash) Publish to default exchange with routing key Q | "/queue" Publish to default exchange with message subj as routing key
For sources, addresses are:
= "/exchange/" X "/" RK Consume from temp queue bound to X with routing key RK | "/topic/" RK Consume from temp queue bound to amq.topic with routing key RK | "/amq/queue/" Q Consume from Q | "/queue/" Q Consume from Q | Q (no leading slash) Consume from Q
The intent is that the source and destination address formats should be mostly the same as those supported by the STOMP plugin, to the extent permitted by AMQP 1.0 semantics.
AMQP 1.0 has no equivalent of AMQP 0-9-1 virtual hosts. A virtual host
on the broker may be addressed when opening an AMQP 1.0 connection by setting
hostname field, prefixing with "vhost:". Setting the
to "vhost:/" addresses the default virtual host. If the
does not start with "vhost:" then the
setting will be consulted.
Limitations and unsupported features
At the minute, the RabbitMQ AMQP 1.0 adapter does not support:
- "Exactly once" delivery 
- Link recovery 
- Full message fragmentation 
- Resuming messages
- "Modified" outcome
- Filters 
- Source/target expiry-policy other than link-detach and timeout other than 0
- Max message size for links
- Aborted transfers
- TLS negotiation via the AMQP2100 handshake (although SSL is supported)
 We do not deduplicate as a target, though we may resend as a source (messages that have no settled outcome when an outgoing link is detached will be requeued).
 We do fragment messages over multiple frames; however, if this would overflow the session window we may discard or requeue messages.
 In principle, filters for consuming from an exchange could translate to AMQP 0-9-1 bindings. This is not implemented, so effectively only consuming from fanout exchanges and queues is useful currently.