SoapUI Cookbook
上QQ阅读APP看书,第一时间看更新

Publishing, browsing, and consuming ActiveMQ JMS messages via the REST API

For SOAP over JMS SoapUI uses HermesJMS to provide JMS integration to test multiple broker implementations. While HermesJMS is a comprehensive option, it needs some setup and may not be necessary in all test scenarios.

Note

HermesJMS issues

I have noticed the following issues with HermesJMS:

  • Java version: This doesn't seem to work with Java 1.7 (Swing UI class load issue), at least not on MacOS (1.7.0_25). To work around this downgrade from JAVA_HOME to version 1.6 (1.6.0_65), that is, export JAVA_HOME=$(/usr/libexec/java_home -v 1.6) and start SoapUI in the same shell.
  • ActiveMQ version: Above ActiveMQ version 5.4.3, Hermes seems to have a class-load issue. Others have logged this issue with HermesJMS. As a possible workaround, using Hermes with the ActiveMQ 5.4.3 core JAR seems successful against the latest ActiveMQ version 5.10.

Often, you will just want to browse, consume, or publish test messages on a queue or topic. This is where ActiveMQ provides a convenient REST API that can be used directly from browsers, code, REST clients, and of course SoapUI tests.

Getting ready

I am assuming that you're reasonably familiar with the JMS concepts, if not ActiveMQ itself. Here are some very brief sample setup instructions:

Download the latest ActiveMQ from http://activemq.apache.org/download.html (this recipe used version 5.10) and unzip it somewhere convenient.

cd <activemq home>/bin
./activemq console (or use start & stop to run in headless mode)

When it starts, check whether it's fine by browsing to the web console using the following URL and credentials: http://localhost:8161/admin/; username/password: admin/admin.

The web admin console should display.

Note

ActiveMQ setup

Obviously, this is just a very quick default ActiveMQ setup. See http://activemq.apache.org/ for more detailed setup information.

Later versions of ActiveMQ (5.8 onwards) present a useful REST API (see http://activemq.apache.org/rest.html). As you might expect for a given queue or topic request, POST publishes messages, and GET (and DELETE) requests consume messages. This sounds reasonable enough, but from a purely RESTful and HTTP perspective, using GET to modify data like this is not correct, that is, it changes the state of the queue or topic. To browse messages, there is an admin queueBrowse URI.

For this recipe, we'll interact with the REST API using SoapUI, but you can of course use any suitable HTTP client, for example, browsers, plugins, curl, wget, and so on.

The completed project ActiveMQRESTAPI-soapui-project.xml can be found in the Chapter 2 samples.

How to do it...

With ActiveMQ already set up and running, we'll first set up a new REST project to interact with the Active MQ REST API. Then, we'll use REST POST Request to create or publish a JMS message. After that, we'll use the ActiveMQ Console to browse the queues and messages. Finally, we'll use a REST GET Request to consume a message.

  1. Let's get started! Open SoapUI and create new REST project.
    • When prompted for the URI, enter this http://localhost:8161/api/message/testqueue?type=queue&clientId=soapui&requestTimeout=1000.
    • URI: /api/message/<queue or topic name>.
    • Parameters: (case sensitive).
    • clientId=<string>: To avoid the need to maintain a request session, we can use the clientId parameter. In the point-to-point model, JMS states that you can only have one consumer per queue (see http://activemq.apache.org/multiple-consumers-on-a-queue.html). This equates to one clientId per queue. However, any number of producers can publish messages to the same queue.
    • Type=queue – Can also be topic.
    • readTimeout=1000 (milliseconds): Can be advisable to limit delays; for example, attempt to consume from an empty queue delays the response.
    • Click on OK. This should create a project, a resource called Testqueue, a GET method, and a sample request.
    • Rename the method to consume message.
    • Right-click on the Testqueue resource and create a new method called publish message with the method of POST.
  2. The ActiveMQ REST API requires HTTP Basic authentication, unless you disable it. To add the credentials to the requests, open the POST request, click on the Auth tab at the bottom left, select Add New Authorization, and select Basic. Enter username as admin and password as admin. Do the same for the GET request. Not doing this correctly will result in an error (HTTP status 401 Unauthorized) in the response. Refer to the Testing basic HTTP authenticated web services recipe of Chapter 7, Testing Secured Web Services, for setting Basic Auth.
  3. Next, we need to add a message to the POST request to publish to testqueue. The JMS API defines five message types (Stream, Map, Text, Object, and Bytes), but text will do in most cases, for example, XML/SOAP, key-value pairs, and JSON. We'll receive a message as follows:
    <Invoice>
    <invoiceNo>12345</invoiceNo>
    <company>Test Company</company>
    <amount>100</amount>
    </Invoice>
  4. Paste this invoice XML into the body of the POST request and select Media Type as text/xml.
  5. Now, click on the green arrow to submit, and you should get a raw response, something like:
    HTTP/1.1 200 OK
    messageID: ID:bear-software-macpro.home-51228-1409661873402-3:1:1:1:2
    Content-Length: 12
    Server: Jetty(7.6.9.v20130131)
    
    Message sent
  6. Queues and topics are created on the fly, so let's take a look at the ActiveMQ Web Console and see how it's looking. In the console, click on queues or go to http://localhost:8161/admin/queues.jsp, and you should see the details of testqueue, for example, Number Of Pending Messages=1 and so on.
  7. To browse through the messages on the queue without consuming them, click on testqueue, and you should see your message with the id from the POST response you got. Click on the message id and you should see all the properties, options, and the message body you posted.
  8. Next, try consuming the message using your GET request, and you should see:
    HTTP/1.1 200 OK
    Cache-Control: no-cache, no-store, must-revalidate
    Pragma: no-cache
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
    Content-Type: application/xml;charset=ISO-8859-1
    destination: queue://testqueue
    id: ID:bear-software-macpro.home-57501-1409656609482-3:3:1:1:1
    readTimeout: 1000
    Transfer-Encoding: chunked
    Server: Jetty(7.6.9.v20130131)
    
    <Invoice> <invoiceNo>12345</invoiceNo> <company>Test Company</company> <amount>100</amount> <Invoice>
  9. In the web console, you can also verify that testqueue is now empty.

How it works...

There isn't a lot to say here except that ActiveMQ provides a REST API that acts as a proxy to the message broker, decoupling clients from the actual JMS message operations. This contrasts to using HermesJMS, which is a Java Swing user interface with Java libraries that SoapUI uses to publish and consume JMS messages.

There's more...

Moving on from the previous example, you can of course derive TestSteps and Assertions depending on what kind of message format you expect to receive. In our example, an XPath Assertions would do, for example, to test the company name returned in the response:

XPath: //Invoice[1]/company[1]
Expected: Test Company

Perhaps an assertion to check the HTTP status code is as expected, for example, 200 for success.

If you need to browse messages on the queue directly, there are services for this too. For example, to get a list of all messages on testqueue go to http://localhost:8161/admin/queueBrowse/testqueue.

This will return an XML list of the message IDs.

To get an individual message go to http://localhost:8161/admin/queueBrowse/testqueue?msgId=<message id>.

This will give quite verbose data on the message. You can also get a list of queues with http://localhost:8161/admin/xml/queues.jsp.

Apart from the REST API, there is some nice looking work going on to produce a Groovy style JMS API (see http://groovy.codehaus.org/GroovyJMS). Another approach is to use the ActiveMQConnectionFactory class directly; lots of examples of this can be found at http://www.programcreek.com/java-api-examples/index.php?api=org.apache.activemq.ActiveMQConnectionFactory.

See also