Interoperability
Interoperation with Qpid
We have performed basic interoperability testing against Qpid's 0.6 release. So far, we have tested:
- Qpid's 0.6 clients against the RabbitMQ broker
- the RabbitMQ clients against Qpid's 0.6 Java broker
- Qpid's Python test-suite against the RabbitMQ broker
Qpid clients » RabbitMQ broker
The 0.6 release of the Qpid java client was shipped with a bug that prevents it from correctly negotiating the protocol version. As it defaults to AMQP 0-10, it is unable to connect to any 0-8 or 0-9-1 broker (including RabbitMQ).
A solution is to use git revision 6f5d963, committed shortly after the main release which fixes protocol negotiation.
In order to run their examples, one must first configure the RabbitMQ broker with the necessary vhost (/test) and permissions(.* .* .*). This is most easily done through the management tools (rabbitmqctl).
Due to a disagreement regarding the spec, almost none of the examples will work. RabbitMQ declares the standard amq.* exchanges as durable. Before using them, Qpid always re-declares them, and does so as non-durable. As a result, RabbitMQ will raise a precondition failed exception for most of the examples.
As the tests below show, the Python client interoperates with the RabbitMQ broker completely -- the only incompatibilities are in the interpretation of AMQP. A slight difficulty lies in that the Python client has different APIs for AMQP 0-8/0-9/0-9-1 and 0-10. In order to work with RabbitMQ, the former should be used.
Both the Qpid Ruby client and the .NET client can connect to the RabbitMQ broker, but since both clients use 0-9-1 methods for 0-8 connections and since both clients default to 0-8, framing errors occur and the broker closes the connection. This problem might go away if the clients were somehow forced to use 0-9-1.
RabbitMQ clients » Qpid Java broker
Broadly speaking, the RabbitMQ clients can interoperate with Qpid. Exceptions to this rule are documented below.
Some of the RabbitMQ Java client tests and examples use features that are not implemented (correctly) in Qpid.
- Qpid does not support the if-unused parameter of exchange.delete.
- Qpid does not support auto-deleted and alternate exchanges.
Qpid misinterprets empty strings in the type field of passive exchange.declare methods; it will raise an exception in these circumstances. As a result, the exchangeDeclarePassive methods in the RabbitMQ clients will not work.
- There are some differences in transaction semantics; Qpid is generally more lax and does not raise exceptions in certain circumstances.
- There are some minor differences in qos semantics.
Furthermore, the Qpid Java broker does not accept "/" for a virtual host. Since this is the default value for all RabbitMQ clients, care must be taken to specify a different one before attempting to connect to Qpid.
The .NET and Erlang clients can connect to the Qpid broker. We have not done more in-depth testing.
Qpid C++ broker
The 0.6 Qpid C++ broker supports only AMQP 0-10; none of the RabbitMQ clients can connect to it.
Test results from Qpid/Python Test Suite
The Qpid project maintains a Python test-suite that aims to be mostly broker independent. It can currently be found in the python/ directory of their source distribution. To run the test suite, execute the following command in the aforementioned directory:
python2.7 ./qpid-python-test -m tests_0-9 -m tests_0-8
The following table details the results of running the 0-8 and 0-9 tests against the RabbitMQ broker.
Current Status | Test Name | Notes |
---|---|---|
ok | tests_0-8.basic.BasicTests.test_ack | |
ok | tests_0-8.basic.BasicTests.test_cancel | |
ok | tests_0-8.basic.BasicTests.test_consume_exclusive | |
planned | tests_0-8.basic.BasicTests.test_consume_no_local | RabbitMQ does not support basic.consume{no-local}. |
invalid | tests_0-8.basic.BasicTests.test_consume_queue_errors | Error codes changed for 0-9-1 |
ok | tests_0-8.basic.BasicTests.test_consume_unique_consumers | |
ok | tests_0-8.basic.BasicTests.test_get | |
ok | tests_0-8.basic.BasicTests.test_qos_prefetch_count | |
planned | tests_0-8.basic.BasicTests.test_qos_prefetch_size | RabbitMQ does not support basic.qos{prefetch-size}. |
ok | tests_0-8.basic.BasicTests.test_recover_requeue | |
ok | tests_0-8.broker.BrokerTests.test_ack_and_no_ack | |
failing | tests_0-8.broker.BrokerTests.test_basic_delivery_immediate | RabbitMQ does not support the basic.publish 'immediate' flag. |
ok | tests_0-8.broker.BrokerTests.test_basic_delivery_queued | |
ok | tests_0-8.broker.BrokerTests.test_channel_flow | |
ok | tests_0-8.broker.BrokerTests.test_closed_channel | |
ok | tests_0-8.broker.BrokerTests.test_invalid_channel | |
ok | tests_0-8.example.ExampleTest.test_example | |
ok | tests_0-8.exchange.DeclareMethodOkiveFieldNotFoundRuleTests.test | |
ok | tests_0-8.exchange.DefaultExchangeRuleTests.testDefaultExchange | |
ok | tests_0-8.exchange.HeadersExchangeTests.testMatchAll | |
ok | tests_0-8.exchange.HeadersExchangeTests.testMatchAny | |
invalid | tests_0-8.exchange.MiscellaneousErrorsTests.testDifferentDeclaredType | Error codes changed for 0-9-1 |
ok | tests_0-8.exchange.MiscellaneousErrorsTests.testTypeNotKnown | |
ok | tests_0-8.exchange.RecommendedTypesRuleTests.testDirect | |
ok | tests_0-8.exchange.RecommendedTypesRuleTests.testFanout | |
ok | tests_0-8.exchange.RecommendedTypesRuleTests.testHeaders | |
ok | tests_0-8.exchange.RecommendedTypesRuleTests.testTopic | |
ok | tests_0-8.exchange.RequiredInstancesRuleTests.testAmqDirect | |
ok | tests_0-8.exchange.RequiredInstancesRuleTests.testAmqFanOut | |
ok | tests_0-8.exchange.RequiredInstancesRuleTests.testAmqMatch | |
ok | tests_0-8.exchange.RequiredInstancesRuleTests.testAmqTopic | |
ok | tests_0-8.queue.QueueTests.test_bind | |
ok | tests_0-8.queue.QueueTests.test_declare_exclusive | |
ok | tests_0-8.queue.QueueTests.test_declare_okive | |
ok | tests_0-8.queue.QueueTests.test_delete_ifempty | |
ok | tests_0-8.queue.QueueTests.test_delete_ifunused | |
ok | tests_0-8.queue.QueueTests.test_delete_simple | |
invalid | tests_0-8.queue.QueueTests.test_purge | Error codes changed for 0-9-1. |
ok | tests_0-8.testlib.TestBaseTest.testAssertEmptyFailing | |
ok | tests_0-8.testlib.TestBaseTest.testAssertEmptyPass | |
ok | tests_0-8.testlib.TestBaseTest.testMessageProperties | |
invalid | tests_0-8.tx.TxTests.test_rollback | The test assumes that delivered messages are re-queued on rollback, which is in violation of the spec. |
invalid | tests_0-8.tx.TxTests.test_auto_rollback | The test is actually the same as test_rollback and is therefore invalid for the same reason. |
ok | tests_0-8.tx.TxTests.test_commit | |
ok | tests_0-8.tx.TxTests.test_commit_overlapping_acks | |
invalid | tests_0-9.query.QueryTests.* | Qpid specific extension. |
Interoperation with OpenAMQ
OpenAMQ brokers
We have performed basic interoperability testing against the OpenAMQ/1.3d0 and OpenAMQ/1.4c0 brokers. We have run our Java client tests and examples against them.
Unfortunately, we found that the OpenAMQ brokers do not implement (correctly) a large part of the AMQP specification. As a result, they fail a large number of our tests. More precisely, we found that OpenAMQ:
- does not support durable queues,
- does not support multiple channels per connection,
- does not encode queue.unbind methods correctly,
- misinterprets the type field for exchange methods, and
- does not appear to support transactions
Some of our examples, most notably MulticastMain, do work, so it is possible to do basic publish/consume. Note that the OpenAMQ brokers occasionally reset the connection without warning.
OpenAMQ PAL Examples
The OpenAMQ project has a small number of PAL scripts designed to test AMQP brokers.
These are short scripts that are compiled to C programs that use the OpenAMQ WireAPI. When running the examples, we found that it is useful to set the trace level to 1 (-t 1).
RabbitMQ passes most of the tests; the only incompatibilities we found are:
- In addition to amq.topic, OpenAMQ implements an amq.regexp exchange.
- OpenAMQ appears to add an extra 0 at the end of queue.unbind methods. This breaks RabbitMQ's frame decoding and causes the broker to close the connection.
- RabbitMQ does not support the no-local parameter of basic.consume.
- There are some slight disagreements as to what exception codes should be used in what situations.
RabbitMQ versions tested
The following versions of the RabbitMQ broker and clients were used when performing the tests:
RabbitMQ broker | 2.0.0 |
RabbitMQ Java Client | 2.0.0 |
RabbitMQ Erlang Client | 2.0.0 |
RabbitMQ .NET Client | 2.0.0 |
Getting Help and Providing Feedback
If you have questions about the contents of this guide or any other topic related to RabbitMQ, don't hesitate to ask them using GitHub Discussions or our community Discord server.
Help Us Improve the Docs <3
If you'd like to contribute an improvement to the site, its source is available on GitHub. Simply fork the repository and submit a pull request. Thank you!