Produce and Consume ActiveMQ messages with SoapUI

Martien van den Akker
virtualsciences
Published in
10 min readAug 24, 2021

In many integration projects queueing is a major transport mechanism for processing messages. Most queueing implementations have UIs or other mechanisms to interact with the queueing implementation. For instance: Weblogic has the admin-console that allows you to inspect messages, move and delete them. Red Hat Fuse on Karaf has HawtIO that allows you to interact with messages:

ActiveMQ in hawtIO

You can browse, send, move and delete messages in such a UI. And set or read (custom) Header-properties on a message.

But, what if your message processing services rely on several properties for the routing? Then for every test, you need to manually set those headers. And for regular sending of messages, it can be tedious to copy and paste the header names and values.

SoapUI supports JMS using the HermesJMS client. That means that you’ll have to install and configure it. Configuring HermesJMS can be a bit complex, although it is explained neatly in several blogs or the SoapUI website. The combination of my current setup of SoapUI 5.6.0 (the current version when writing this article), with the accompanying HermesJMS and Red Hat Fuse on Karaf version 6.3, with ActiveMQ 5.11 does not work properly.

After a few hours of struggling and googling, I tried to do the same but with a bit of Groovy (Java) script. And that works like a charm, with very little configuring.

Using SoapUI with HermesJMS allows you to configure your message producing and consuming test steps as if they were regular SoapUI request test steps. You’ll have functionality as assertions under your fingertips.

A disadvantage of my approach is that since it relies on groovy scripts, you can’t easily put assertions on the service test steps.

I posted my SoapUI project on Github. Below I’ll explain how I put it all together.

Placeholder for the request message

To be able to work with the test in a convenient way, I’d like to use the message editor of SoapUI. But since that requires a SOAP-Binding or a REST definition, I included a dummy WSDL:

Source Message

As you can see, I do not even bother the message to be a SOAP Envelope. You can also see that the test step is disabled. I only use it as a placeholder: it is not meant to be executed. Having the SOAP test step as a placeholder enables me to register name-value pairs as header properties to be used as JMS Custom Properties as we will see later.

Produce the message

The message is sent with a Groovy script. To have it reusable, I put it in a separate test case “PutAMQMessage TestCase” in a separate test suite “Utils TestSuite”. This test case can be run/invoked from any other test case.

Of course, the script needs to know which message has to be put on which destination, with possible properties, etc. You could put those all in SoapUI Properties to transfer that information to the test case. However, when extra properties are needed you’ll have to add those in the whole route of calling. I used to have several property transfer steps to transfer the payload and message properties. In the end, I found it more convenient to tell the script which service test step contains the request.

The following properties are used by the PutAMQMessage TestCase:

Testcase properties of PutAMQMessage TestCase

The brokerURL, brokerUser, and brokerPassword properties are kept on project level. Since they’re global, you would say that the script could use them directly. However, I provide them as parameters because on the project level they are dynamic properties. These have to be expanded and that occurs on invoking the test case. I’ll explain that later.

The destination property speaks for itself, and the properties requestTestSuite, requestTestCase, and requestTestStep refer to the SOAP Request test step that is the place holder of the request. The requestTestStep is a specific test case property refers to the name of the placeholder test step as described above. The properties requestTestSuite, requestTestCase are used in the script to traverse the project object-tree to get to the test step that where the requestTestStep property points to.

Groovy script to produce the message

The ProduceMessage groovy script contains the following code:

Lines 14–29 define several variables to refer to the current testStep, testCase, testSuite and project. I find it always convenient to have them available as separate values to get to the properties on different levels. The testStep is defined as an index in the current context, apparently not as a separate property in the testRunner. The current test step is convenient to name in the logging.

Lines 34–46 do the actual setup of the JMS Session and JMS MessageProducer for the destination. This is actually a “Groovication” of a Java snippet of producing a JMS Message. In line 43 you’ll see that a destination of type queue is created from the session. If you want to use a topic the line should use the createTopic() method.

Lines 49–52 read the Header properties from the request and add the values as JMS Properties to the JMS TextMessage. Apparently, SoapUI provides those values as an ArrayList. When converting them to a String, square brackets are added. Using the construct it.value.toString()[1..-2] these first and last characters are stripped.

JMS Implementation library

JMS is an interface definition, just like JDBC for instance. The first two imports show that we rely on an Apache ActiveMQ Connection factory. That means that a JMS Implementation needs to be added. I use the activemq-all-5.11.1.jar library that I extracted from an ActiveMQ Broker download. Newer versions exist, but this one matches my Red Hat Fuse version. Put the library in the ext subfolder of the bin folder of your SoapUI installation:

Extension folder of SoapUI

It will be picked up automatically after a SoapUI restart.

Invoke the PutAMQMessage test case

The actual test case is in this example Message Processing TestCase. On this test case the following properties are set:

Testcase properties of Message Processing TestCase

The destination property holds the name of the queue/topic (or Address in AMQP terms) to send the message to. The responseDestination refers to the queue/topic to get the response from. The property requestTestStep holds the name of the test step that contains the content and the header/jms properties that is to be send. In the same way, the property responseTestStep has the name of the test step that is used to write the response message and its properties to. When this testcase is cloned and you want to rename the placeholder test steps, you’ll need to update the requestTestStep and responseTestStep properties accordingly. You might want to have it reflect the type of message it holds.

In this testcase the PutAMQMessage TestCase is invoked using the test step InvokePutAMQMessage. The test case properties of PutAMQMessage TestCase are used as a parameter in the invocation:

InvokePutAMQMessage parameters

As you can see, the brokerURL, brokerUser and brokerPassword are provided as project-level properties. The destination is fetched from the test case. In the groovy script, we need to get the request test step, which is part of the current test case and test suite. The requestTestSuite and requestTestCase are needed to get to the requestTestStep. These names are in the same test case context, hence they are filled with a dynamic property (indicated by the equal ‘=’ sign) that gets the names from the particular objects that are apparently available. The requestTestStep property is registered as a test case property.

This test step is a “Run TestCase” test step that invokes the “PutAMQMessage TestCase”:

In the test case use can use the cog-icon to bring up the settings:

Click on the cog icon to view the settings

The Target TestSuite and Target TestCase are selected (yes indeed, in that order) to be called. Check that the Run Mode is set as follows:

Configure the Run TestCase step

Consume the message

Most of the construction of the message consumption in the SoapUI project is similar to the message production part. Again there is a separate test case “GetAMQMessage TestCase that contains the groovy script. Invoking it is identical to the “PutAMQMessage TestCase”. Also in this case there is a placeholder test case that is used to save the response message that results from the get, together with the JMS properties as header properties. The response message is saved in the Request pane of the placeholder test-step. In SoapUI the response pane in a test step is read-only. Therefor it is unfortunately not possible to set it using Groovy.

Groovy script to consume the message

The ConsumeMessage groovy script contains the following code:

Most of it is a clone of the ProduceMessage script. Instead of a MessageProducer, a MessageConsumer is created for the destination, in line 58. No message selector is provided here, and therefore the message at the top of the queue is consumed. Note again, that in line 55 a destination of type queue is created.

Line 61 does a receive with a timeout of 5000 ms. Should actually be a configurable property as well.

Then in lines 62 to 72 the JMS Properties from the TextMessage are copied to a request headers ArrayList. This is

Conditional Consumption

A typical test case could look like the following:

Message processing test case

In some cases, you may not want to do a get message for certain environments. In your local test server, you might want to get the message to check out the message or just to clean up your queue. In other environments, another process or application consumes the message.

SoapUI does have a conditional goto test step, but that can only define rules that is based on the response of the previous test step. In this case, a “conditional goto” based on a property is needed. This is done with the CheckIf2Get groovy test step:

CheckIf2Get groovy script

Here the “Environment” should be “local” to have the Message Consumption done. If it is not “local” then the testRunner is directed to skip and resume at the test step called “End”. This test step is a dummy test step with a Groovy script as well, that only logs “Done”.

Environment specific project properties

To create a ActiveMQ connection factory a connection to a broker has to be made, using an URL and username/password credentials. This connection is environment-dependent. ReadyAPI, the big subscription-based brother of SoapUI, has functionality to register project properties per environment. With a pull-down list, you can select the environment against which you want to execute your tests. Very convenient, but not available in SoapUI. With a property trick, you could achieve almost the same thing.

On the project level, you’ll find the following properties.

Project Level environment-specific broker properties

Per environment, you’ll see properties with the format “app_environment_property”. For instance, for the local-environment you’ll see the properties broker_local_URL, broker_local_User and broker_local_Password. The actual properties for _URL, _User, and _Password select the actual values with a dynamic property. For _URL this is ${#Project#broker_${#Project#Environment}_URL}. Which is a combined, dynamic property based on the Project level Environment property. By changing that property you can select other corresponding values for these properties.

TLS broker URLs

The test environment has a broker URL that has ssl: as protocol, in stead of tls:. To be able to connect to TLS based brokers, you’ll need to add the public certificates of the certificate authorities in the certificate chain to the trust store of the JVM you’re running SoapUI. This can be the embedded JRE, or the particular specific JVM if you run SoapUI with a separate one. The trust and key stores that you can add to SoapUI are not used for Groovy.

I added an import script and a keystore list Windows script to the GitHub project that helps contains the commands to import the certificate into the trust store and list the trust/key store. These rely on a keystore_env script that sets the references to the JAVA_HOME, trust/keystore with password and certificates to import.

Conclusion

This is a quite configurable way to do JMS actions on an ActiveMQ broker from SoapUI. In earlier iterations of my project and in a base project that I created with a previous customer, I used a lot of properties on the project and test case level and several property-transfer test steps to pass these around. I managed to mitigate that in this setup so I only need a placeholder test step and an run-test-case step to invoke the produce or consume actions.

A big advantage is that it does not rely on HermesJMS. I got the impression that the development of that project has ended. I haven’t heard any rumors on the use of the tool within SoapUI. Installing HermesJMS with SoapUI is optional. In ReadyAPI support for JMS is now built-in. You can still work with a separately installed HermesJMS and ReadyAPI as before. It is not easy to configure, and you don’t need to anymore.

As said earlier, a disadvantage of this approach is that you cannot set assertions on the placeholder test steps. Assertions are set on the response of a request-test step. But you can’t set the response programmatically. You could work around this, by creating and invoking a mock service that can respond back to your consumed message.

Since Groovy is “reduced-boiler-plate-Java”, you can use this also to check out your Java code snippets. To see if things work with the JMS library as you would expect.

--

--

Martien van den Akker
virtualsciences

Technology Architect at Oracle Netherlands. The views expressed on this blog are my own and do not necessarily reflect the views of Oracle