New URL format for AMQP + Qpid

The Qpid M4 Java and C++ clients use different URL formats.

Java uses: http://cwiki.apache.org/qpid/connection-url-format.html

C++ uses the AMQP 0-10 format: section 9.1.2

The AMQP 0-10 format only provides protocol address information for a (list of) brokers. The Qpid M4 Java format provides additional options for connection options (user, password, vhost etc.)

This is a proposal for the AMQP working group to extend the 0-10 URL format to have the flexibility of the Qpid format.

Proposed URL syntax

This proposal extends the AMQP 0-10 URL syntax to include user:pass@ style authentication information, virtual host and extensible name/value options. It also makes the implied extension points of the original grammer more explicit.

Note: terms not defined below (userinfo, host, port, pchar, scheme) are taken from


amqp_url       = "amqp://" [ userinfo "@" ] addr_list [ vhost ]
addr_list      = addr *( "," addr )
addr           = prot_addr [ options ]
prot_addr      = tcp_prot_addr | other_prot_addr
vhost          = "/" *pchar [ options ]


tcp_prot_addr  = tcp_id tcp_addr
tcp_id         = "tcp:" / ""	; tcp is the default
tcp_addr       = [ host [ ":" port ] ]



other_prot_addr= other_prot_id ":" *pchar
other_prot_id  = scheme


options        = "?" option *( ";" option )
option         = name "=" value
name           = *pchar
value          = *pchar

Rationale

Multiple addresses vs. single address.

The URL provides a standard way to group multiple addresses that belong to "the same broker". As well as being used in the AMQP protocol handshake, a URL is a convenient format to "bootstrap" the initial client-broker connection. It can be easily stored in a file, regsitered in a directory service passed as an argument to a program etc.

A clustered broker can advertise addresses of multiple nodes for fault tolerant connection by clients.

A broker that is connected to multiple networks or via multiple protocols can advertize addresses for each protocol.

Clients can select an address randomly, round robin or based on preference for a particular network or protocol.

Multiple addresses in a single URL should only be used for a set addresses belonging to "the same broker", with equivalent service at each address.

Options

Options can be set for the entire connection or for a specific protocol addresses, providing a flexible way to extend the URL syntax. The AMQP standard will define some options, implementations may define proprietary options. Implementations should ignore any option they do not recognize.

TODO: standard options.

Reserved characters in option names and values must be percent-encoded as per .

Userinfo

Putting security credentials in a URL is generally bad practice in a deployed system but useful in development and testing, so supported here.

The meaning of the userpass information depends on the security mechanism in use. Eg. for SASL authentication with the PLAIN mechanism, the userinfo would be username:password.

TODO need to define:

  • protocol address formats and options for other transports - ssl/tsl, infiniband, vm...
  • standard options for values in the standard connection negotiation.
  • qpid proprietary options (e.g. JMS clientid?)

Incompatibility with AMQP 0-10 format

This syntax is backward compatible with AMQP 0-10 with one exception: AMQP 0-10 did not have an initial // after amqp: The justification was that that the // form is only used for URIs with hierarchical structure as per

However it's been pointed out that in fact the URL does already specify a 1-level hierarchy of address / vhost. In the future the hierarchy could be extended to address objects within a vhost such as queues, exchanges etc. So this proposal adopts amqp:// syntax.

Its easy to write a backward-compatible parser by relaxing the grammer as follows:

amqp_url = "amqp:" [ "//" ] [ userinfo "@" ] addr_list [ vhost ]

Examples

# TCP connection to host1 on port 1234, virtual host "vhost" passing username "foo",
# password "bar" for authentication, and specifying a Qpid JMS client-id.
amqp://foo:bar@host1:1234/vhost?clientid=baz

# TCP connection to standard port 5672 on localhost
amqp://localhsot

# Choice of infiniband or tcp connections to host foo on different ports.
# TODO: merits of ib vs. rdma as a prefix?
amqp://ib:foo:1234,tcp:foo:5678/

# Connect to the first of host1,host2,host3 that succeeds, retry each twice.
# retry property at connection level is applied to all addresses.
amqp://host1,host2,host3/?retry=2

# Connect to the first of host1, host2, host3 that succeeds, retry host2 twice.
amqp://host1,host2?retry=2,host3

TODO: retry example above is a bit forced - better example for address options vs. url options.

# Connect to vhost over imaginary protocol grok: which has a bunch of optional parameters
# parameters to connect.
amqp://grok:hostname?flavour=strawberry;frobnication=on/vhost

# Connect using SSL (taken from qpid) see discussion below.
amqp://host?ssl=true

Protocols and security

tcp: is the only protcol in AMQP 0-10. Possible additional protocols: sctp, ib (infiniband), ssl, tls.

There are 3 possible ways to indicate a secure connection:

  1. Change the URL scheme: amqps://host # Change the protocol: amqp://ssl:host # Use a property: amqp://host?ssl=true

1. the problem here is AMQP supports non-TCP protocols. It's not so clear what amqps://ib:host means.

2. and 3. are more flexible. We can easily add a new protocol identifiers or options for secure variants of any protocol. We can't easily use an open-ended set of URL schemes.

TODO: what's the best thing here?

Differences from Qpid Java format

Addresses are at the start of the URL rather than in the "brokerlist" option.

Option format is ?foo=bar;x=y rather than ?foo='bar'&x='y'. The use of "'" quotes is not common for URI query strings, see . The use of "&" as a separator creates problems, see

user, pass and clientid are options rather than having a special place at the front of the URL. clientid is a Qpid proprietary property and user/pass are not relevant in all authentication schemes.

Qpid M4 Java URLs requires the brokerlist option, so this is an easy way to detect a Qpid M4 URL vs. a URL as defined here and parse accordingly.

This proposal only covers connection URLs. A fully-qualified binding URL could be represented as amqp://<addrs>/<vhost>/<binding_url>

  • No labels