Example of standalone Apache Qpid (amqp) Junit Test

Wiretap picture Wiretap · Feb 1, 2010 · Viewed 8.7k times · Source

Does anyone have an example of using Apache Qpid within a standalone junit test.

Ideally I want to be able to create a queue on the fly which I can put/get msgs within my test. So I'm not testing QPid within my test, I'll use integration tests for that, however be very useful to test methods handling msgs with having to mock out a load of services.

Answer

user3107951 picture user3107951 · Nov 5, 2014

Here is the setup method I use for QPID 0.30 (I use this in a Spock test but should be portable to Java of Junit with no problems). This supports SSL connection, the HTTP management, and uses only in-memory startup. Startup time is sub-second. Configuration for QPID is awkward compared to using ActiveMQ for the same purpose, but QPID is AMQP compliant and allows for a smooth, neutral testing for AMQP clients (obviously the use of exchanges can not mimic RabbitMQs implementation, but for basic purposes it is sufficient)

First I created a minimal test-config.json which I put in the resources folder:

{
  "name": "${broker.name}",
  "modelVersion": "2.0",
  "defaultVirtualHost" : "default",
  "authenticationproviders" : [ {
    "name" : "passwordFile",
    "type" : "PlainPasswordFile",
    "path" : "${qpid.home_dir}${file.separator}etc${file.separator}passwd",
    "preferencesproviders" : [{
        "name": "fileSystemPreferences",
        "type": "FileSystemPreferences",
        "path" : "${qpid.work_dir}${file.separator}user.preferences.json"
    }]
  } ],
  "ports" : [  {
    "name" : "AMQP",
    "port" : "${qpid.amqp_port}",
    "authenticationProvider" : "passwordFile",
    "keyStore" : "default",
    "protocols": ["AMQP_0_10", "AMQP_0_8", "AMQP_0_9", "AMQP_0_9_1" ],
    "transports" : [ "SSL" ]
  }, {
    "name" : "HTTP",
    "port" : "${qpid.http_port}",
    "authenticationProvider" : "passwordFile",
    "protocols" : [ "HTTP" ]
  }],
  "virtualhostnodes" : [ {
    "name" : "default",
    "type" : "JSON",
    "virtualHostInitialConfiguration" : "{ \"type\" : \"Memory\" }"
  } ],
  "plugins" : [ {
    "type" : "MANAGEMENT-HTTP",
    "name" : "httpManagement"
  }],
  "keystores" : [ {
     "name" : "default",
        "password" : "password",
      "path": "${qpid.home_dir}${file.separator}keystore.jks"

    }]
}

I I also needed to create a keystore.jks file for localhost because the QPID broker and the RabbitMQ client do not like to communicate over an unencrypted channel. I also added a file called "passwd" in "integTest/resources/etc" that has this content:

guest:password

Here is the code from the unit test setup:

class level variables:

def tmpFolder = Files.createTempDir()
Broker broker

def amqpPort = PortFinder.findFreePort()
def httpPort = PortFinder.findFreePort()

def qpidHomeDir = 'src/integTest/resources/'
def configFileName = "/test-config.json"

code for the setup() method:

   def setup() {

    broker = new Broker();
    def brokerOptions = new BrokerOptions()

    File file = new File(qpidHomeDir)
    String homePath = file.getAbsolutePath();
    log.info(' qpid home dir=' + homePath)
    log.info(' qpid work dir=' + tmpFolder.absolutePath)

    brokerOptions.setConfigProperty('qpid.work_dir', tmpFolder.absolutePath);

    brokerOptions.setConfigProperty('qpid.amqp_port',"${amqpPort}")
    brokerOptions.setConfigProperty('qpid.http_port', "${httpPort}")
    brokerOptions.setConfigProperty('qpid.home_dir', homePath);


    brokerOptions.setInitialConfigurationLocation(homePath + configFileName)
    broker.startup(brokerOptions)
    log.info('broker started')
}

code for cleanup()

broker.shutdown()

To make an AMQP connection from a Rabbit MQ client:

        ConnectionFactory factory = new ConnectionFactory();
        factory.setUri("amqp://guest:password@localhost:${amqpPort}");
        factory.useSslProtocol()

        log.info('about to make connection')


        def connection = factory.newConnection();
        //get a channel for sending the "kickoff" message
        def channel = connection.createChannel();