In the last post I wrote about sending a simple text message to the Oracle’s AQ queue.

This time let’s have a look at a bit different case of having an object marshalled to JSON and then sent to the queue as a byte message. And yes, we still will be sending the message to Oracle’s AQ, but this time we will utilize JMeter’s JMS Publisher sampler.

 

Setting up the scene

Once again I need to point you to the last post on the queues as all the stuff concerning the required libraries and which values to use for the sampler are almost the same, so please check that out.

Now, we need to differentiate two cases here:

  • First is that you are sending a simple JSON -> you may jump straight to ‘Configure JMS Publisher sampler’ section and you should be just fine
  • second is that you might be sending quite complex message and want to make sure that your message will be always structured in the right way as in the system you are testing -> just read on

 

If you’ve chosen to continue reading, here is what we aim to do:

  • we will be sending an object, so we need to create one first
  • convert the object into JSON
  • add info what is the class of the object
  • send as byte message with JMS Publisher sampler

Let’s go through each of the above points one by one.

 

Creating an object

OK, let’s start with a simple task of creating on object that will be sent.

 

  • Suppose that we have a class called ‘DataMessage’ that defines the features of the message
package com.perftuned.example.jms;

public class DataMessage {
	
	protected String data;
	protected long id;
	protected String system;
	protected String timestamp;
	protected String user;

// here come all getters and setters methods. I've omitted them for brevity.
}

 

  • Note! You need to have this class compiled, put in a jar and the jar should be placed in the JMeter’s /lib/ folder.

 

  • Then add a JMS Publisher to your JMeter script and put a JSR223 PreProcessor underneath it.

 

  • Finally! We can create an object of the DataMessage class in the preprocessor now!
import com.perftuned.example.jms.DataMessage;

DataMessage dmsg = new DataMessage();

dmsg.setId(Integer.valueOf(vars.get("id")));
dmsg.setData(vars.get("data"));
dmsg.setSystem(vars.get("system"));
dmsg.setTimestamp(vars.get("timestamp"));
dmsg.setUser(vars.get("user"));

 

Convert it to JSON

I’ve used Jackson Data Processor for JSON data-binding  https://github.com/FasterXML/jackson-databind . If you are using another library in your project, then it might be necessary to change the code accordingly.

 

  • Firstly, we need to get more libraries and place them into JMeter’s /lib/ folder:
    • jackson-annotation.jar
    • jackson-core.jar
    • jackson-databind.jar

 

  • Then, let’s surround the code for object creation with the stuff below that converts the object to JSON and saves it in a byte array:
// adding more imports
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

...
// all of the code creating the object comes here
...

ObjectMapper objectMapper = new ObjectMapper();
// convert to JSON and save as byte array
byte[] jsonBytes = objectMapper.writeValueAsBytes(dmesg);
  • As a result we get a message like the one below (but saved at the moment in a byte array of course)

 

{"data":"{\"exportingDataSuccessful\":\"true\",\"RequestedBy\":\"DummyUser\",\"ElapsedTimeMs\":\"8243\"}","id":1,"system":"Perftuned.com","timestamp":"2019-05-25T12:34:27.609Z","user":"Tester"}

 

Configure the JMS Publisher sampler

We can start working on the sampler itself now, it shall be configured in a very similar fashion to the JMS Point-to-Point sampler mentioned in the previous post. Check it for some more detailed info on the values behind the variables visible below.

The one new thing is a JMS Property called ‘_type’ that defines the class of the object we will be sending in the message. Well, the other side needs to know what it’s getting out of the queue right? 🙂

 

jmeter jms publisher configuration

 

Sending the message as byte message

Here comes the last part, but it is actually not straightforward. There are 2 things here that we need to overcome.

First thing is that we would like to send the message as ‘bytes message’. However JMS Publisher only enables us to do so when the payload is provided from a file.
It’s a shame that there is no other possibility, but we need to save message to a file and only then send it.

 

Additionally, JMS Publisher has a caching feature that saves content of the last used file.
So once a file with the same name is used twice in a row, JMeter simply takes the content straight from the cache without opening the file again.
That is not the most useful feature in this case, so we need to make sure the filename changes every iteration of a single thread avoiding cache lookup.
 
One of the approaches could be to include in the filename: current timestamp,  thread number and thread group name (if the messages will be sent by multiple threads from many thread groups) and then save the byte array with the message to the file.
 
Let’s add following code to the preprocessor:
 

// 'jmsBytesMessagePath' variable can contain path for the file
String filename = vars.get("jmsBytesMessagePath") + "jms" + ${__time()} + "_" + ${__threadNum} + "_" + ctx.getThreadGroup().getName() +".dat";

// save the path + filename to the 'jmsBytesMessageFullPath' variable
vars.put("jmsBytesMessageFullPath",filename);

// writing message to a file
FileOutputStream fos = new FileOutputStream(filename);
fos.write(jsonBytes);
fos.close();

 
As you could already spot in the screenshot of the JMS Publisher sampler in the previous section, the ‘jmsBytesMessageFullPath’ variable is used in the sampler’s ‘Filename’ field.
 
Finally, we can also add a postprocessor to the sampler in order to delete the not needed file:
 

File file = new File(vars.get("jmsBytesMessageFullPath"));
file.delete();

 
That results in the following structure: