Search code examples
javatestingrabbitmqqpid

Testing RabbitMQ locally with Apache QPID - random port


I wanted to set up a little local test for some components connecting to RabbitMQ. For this, one solution seems to be the QPID In-Memory Broker and actually that works quite well when following these instructions (only using the current version of 7.0.3 instead of 7.0.0)...

For Rabbit MQ, I removed the "AMQP_1_0" protocol and only added the qpid-broker-plugins-amqp-0-8-protocol dependency. Also I replaced the Authenticationprovider with a PLAIN. This was enough to get my RabbitMQ components working and sending/receiving messages through that Broker.

But the problem is this line...

"port" : "${qpid.amqp_port}",

As far as I understand it, this should allow me to define the port the broker is listening at by setting this property when calling systemLauncher.startup.

attributes.put("qpid.amqp_port", 12345);

Unfortunately, this does not work and the Broker always listens at the default port (5672, iirc). Obviously this is not optimal for automated tests, so I am looking for one of the following possibilities (or a better one):

  1. Putting a random port in the properties (I can find an open port myself, no problem) or...
  2. Telling QPID to use a random (open) port - but then I also need to know which port is actually used, since SystemLauncher does not seem to offer any way to query that.

Solution

  • Apache Qpid Broker-J's SystemLauncher supports SystemLauncherListeners which get notified once a various points through the startup sequence. If you configure the Broker to bind to port 0, a dynamically assigned port will be assigned at run-time. You can then use an #afterStartup() implementation to determine which port has been bound. Take a look at PortExtractingLauncherListener (test harness code) as an example to follow.

    In Broker-J's model there is a distinction between an object's attributes and context variables. If you want to provide a substitution for qpid.amqp_port you do this by providing a context variable. You can so this programmatically like so:

    attributes.put("context", Collections.singletonMap("qpid.amqp_port", 0))

    or, as context variables are defaulted from Java system properties, like this on the JVM command line -Dqpid.amqp_port=0