On 28/02/14 21:51, Crinklaw-Vogt, Matthew wrote:
I was curious how to create a header exchange via an address string.

Doing something like:
`test_header_ex; {create: always, node: {type: headers}}`

appears to be invalid as the only valid node types are "topic" and "queue."  Is 
there some other way to create a header exchange via an address string?

-Matt

Hi Matt,
The "subtle little nuance" here is that when talking about node types in this context it's *really* meaning the semantic type of the AMQP node and not the explicit type of an exchange.

What I mean by that is that if you think about messaging patterns there are two main types
1) Point to Point
2) Publish/Subscribe

If you are familiar with JMS that has Destination types of Queue and Topic and it is in that sense of topic that the node type is labelled, so a queue node is fairly obviously a queue but (most) exchange nodes (aside I guess from direct exchanges) behave in a pub/sub like way.

The most obvious example would be amq.topic but amq.match, xml and amq.fanout are semantically quite similar albeit with different message selection mechanisms.


To answer your question, what you need to include is some additional information, namely the topic type. The following does what I think you are expecting:

./drain -b localhost -f \
"test_header_ex; {create: always, node: {type: topic, x-declare: {type: headers}}}"

If you want to get a bit fancier here's a way to make it auto delete:

./drain -b localhost -f \
"test_header_ex; {create: always, node: {type: topic, x-declare: {type: headers, auto-delete: true}}}"


The following example exercises pretty much every exchange option (though auto delete and durable is probably a bonkers combination) this sets an alternate exchange and makes it an Initial Value Exchange with sequence numbering enabled (I don't tend to use those myself but thought you might be interested in the syntax).

./drain -b localhost -f \
"test_header_ex; {create: always, node: {type: topic, durable: true, x-declare: {type: headers, auto-delete: true, alternate-exchange: 'amq.match', arguments: {'qpid.ive': 1, 'qpid.msg_sequence': 1}}}}"




One thing that's worth pointing out is that the x-declare stuff is protocol specific (i.e. AMQP 0.10 specific) though as it happens I tried this using AMQP 1.0 and found the following works (but see my note below):

./drain --connection-options {protocol:amqp1.0} -b localhost -f \
"test_header_ex; {create: always, node: {type: topic, x-declare: {type: headers, auto-delete: true}}}"


though I think that the following equivalent address is a bit more idiomatic:

./drain --connection-options {protocol:amqp1.0} -b localhost -f \
"test_header_ex; {create: always, node: {type: topic, properties: {exchange-type: headers, auto-delete: true}}}"



One other important thing to note about AMQP 1.0 is that (quoted from Gordon Sim)
"
* The 'create' option in qpid::messaging addresses

Using this option with an explicit node name results in non-standard AMQP and is discouraged where it can be avoided. A better alternative is to configure node policies. These are patterns that an attaching links address are checked against if it doesn't resolve to any existing node. If a matching pattern is found, the node will be auto-created with the properties of that policy.
"


So basically the AMQP 1.0 examples that I illustrated above are actually *non-standard AMQP*. I'm afraid that I'm somewhat unfamiliar with the work around "A better alternative is to configure node policies" but the following approach seems to work:

Firstly you need to add a TopicPolicy Management Object to the broker. I'm not exactly sure when this feature was added (it was October 2013, but I can't recall which Qpid version - I'm using 0.27 on Qpid trunk)

qpid-config add TopicPolicy header-exchange-* --argument exchange-type=headers --argument auto-delete=false --argument alternate-exchange=amq.match --argument qpid.ive=1 --argument qpid.msg_sequence=1

You can check what was added using:

qpid-config list TopicPolicy


Now if we specify the following address what it does is to check the address against an existing node and if one exists attaches to that, but if not it checks the policy patterns and if a match is found it will auto-create a node with the properties of that policy (I've not checked to see if the IVE stuff actually works doing this, but the properties do seem to be added to the created exchange so it *probably* works).

./drain --connection-options {protocol:amqp1.0} -b localhost -f "header-exchange-test"

You can delete a TopicPolicy as follows

qpid-config del TopicPolicy header-exchange-*


The TopicPolicy/QueuePolicy stuff is qpidd specific (other brokers may have analogous features) but it does allow the use of a standard AMQP 1.0 address.


Hopefully that's given you a fairly comprehensive answer to your question :-)

If you want to get really flashy here's an AMQP 1.0 address that dynamically creates an exchange as above, but it also creates a subscription queue called "test-link" with bindings that match on message properties data-service=amqp-delivery item-owner=fadams

./drain --connection-options {protocol:amqp1.0} -b localhost -f \
"header-exchange-test; {node: {capabilities: [shared]}, link: {name: test-link, filter: {name: key, descriptor: 'apache.org:legacy-amqp-headers-binding:map', value: {x-match: all, data-service: amqp-delivery, item-owner: fadams}}}}"


Finally it's worth bearing in mind that even though I've explained a bit about how to make the general topic creation standard in AMQP 1.0 the filter stuff, although a registered AMQP 1.0 extension, is unlikely to be implemented in non-Qpid Brokers, so you'd probably want to use message selectors if you wanted to give your address more portability.

HTH,
Frase


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to