Migrating from ActiveMQ to WebSphere MQ

Overview

A side-project I’ve been playing with in the evening: Writing a JMX layer to allow apps written for ActiveMQ to migrate to WebSphere MQ with minimal modifications

Background

This came out of working on something that uses a JMS messaging provider. It uses it internally to allow components to communicate with each other, even when spread across multiple machines.

It uses Apache ActiveMQ – an open-sourced implementation of JMS. I wanted to try and get it working using WebSphere MQ – IBM’s implementation of JMS that I used to work on until five years ago.

As a messaging standard, the fact that both ActiveMQ and WebSphere MQ (WMQ) are JMS providers means that the way it puts and gets messages should just work.

But the JMS standard doesn’t cover administration (how queue managers are created and configured, how they’re started, how queues and topics are created, etc.) or monitoring (getting statistics about how many messages have been put or got, how many messages are on a queue, etc.)

All of this was done in an ActiveMQ-specific ways. This was what needed to be ported if I was going to get this to work with WebSphere MQ.

The project I’m porting is actually a bit of a black box. Rather than make a significant rewrite to get it to go from being ActiveMQ-specific to WMQ-specific, I wanted to see what I could add so that as much of the existing code could just work transparently.

I wanted to write a layer to sit between the ActiveMQ-app and WebSphere MQ, so that the app needn’t realise it’s not talking to the ActiveMQ broker it was written for.

JMX – How ActiveMQ enables administration and monitoring

ActiveMQ has a JMX API.

Java Management Extensions (JMX) is a part of Java, and provides a standard way of monitoring and managing resources in Java apps. If you’re not familiar with it, give it a try now.

Run ‘jconsole‘ at a command line (assuming you have Java installed). It will list the Java apps you have running. You can choose one and connect to it.

If that app has implemented the MBeans (managed beans) interface, then jconsole will show the objects in that Java app, with some of their attributes and invokable operations.

ActiveMQ have implemented the MBean objects for queues, topics, and so on. These objects have public methods returning attributes such as the number of messages on a queue. And they have invokable methods to administer them, such as being able to create a queue.

It means jconsole can be used as a basic UI for ActiveMQ. It displays all the MBean objects that are registered on the left, and if you select one, it can display:

attributes


click to enlarge

invokable methods – with a button to launch each


click to enlarge

It shows a text box for each method parameter. You can fill in a queue name, click the ‘addQueue’ button, and you’ve got a new queue.

jconsole makes for a nice, quick-and-easy UI, but it isn’t the only thing that can use this API. The MBean interface provides a standard way of interacting with resources in the broker. It means you can write a JMX client to administer your ActiveMQ broker.

For example, to create a new queue on ActiveMQ, you can do something like this:

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();

String operationName="addQueue";
String parameter="MyNewQueueFromJMX";
ObjectName activeMQ = new ObjectName("org.apache.activemq:BrokerName=localhost,Type=Broker");
if(parameter != null) {
    Object[] params = {parameter};
    String[] sig = {"java.lang.String"};
    conn.invoke(activeMQ, operationName, params, sig);
} 
else{
    conn.invoke(activeMQ, operationName,null,null);
}

This is the sort of code that exists throughout the project that I was looking to port.

But instead of rewriting all of that, what about getting WebSphere MQ to understand these commands, so that this project, and jconsole, and any other JMX client could interact with it?

PCF – How WebSphere MQ enables administration and monitoring

WebSphere MQ has a PCF API, which is a way to build messages with commands and put them on the queue manager’s command queue. These can be used for a variety of administration and monitoring tasks, covering most of what is available in ActiveMQ’s JMX API.

A JMX agent for WMQ

My idea was to write a JMX agent that receives the JMX commands from a client, and sends the corresponding PCF commands on to a WMQ queue manager. It collects the responses, and translates them into the relevant MBeans formats for returning to the JMX client.

I wanted a small, lightweight layer that could allow any ActiveMQ app that uses the JMX API for administration to work as-is with WebSphere MQ instead.

To create a queue on WMQ, the above example would change to:

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();

String operationName="addQueue";
String parameter="MyNewQueueFromJMX";
ObjectName wmq = new ObjectName("com.ibm.webspheremq:BrokerName=localhost,Type=Broker");
if(parameter != null) {
    Object[] params = {parameter};
    String[] sig = {"java.lang.String"};
    conn.invoke(wmq, operationName, params, sig);
} 
else{
    conn.invoke(wmq, operationName,null,null);
}

A minor change from the previous example is in bold. I could’ve copied the domain from ActiveMQ precisely, implementing my agent to register MBeans with the domain org.apache.activemq but that didn’t seem appropriate.

What can it do?

This is probably obvious, but let me give you some examples.

I’ve recorded a one-minute demo going through creating queues and topics, putting and getting messages, and monitoring statistics about WMQ objects and clients.

Why?

The point of this isn’t because I want to use jconsole as a WMQ administration tool. It’s a little clunky for regular use!

jconsole is a demo of the JMX API in action. It’s an easy way to show that with no modifications, a JMX client that works with ActiveMQ now works in virtually the same way with WebSphere MQ.

An app written for ActiveMQ can use the same API that it uses for administering and monitoring ActiveMQ to administer and monitor a WebSphere MQ queue manager, without needing to be rewritten to use the WMQ-specific PCF APIs.

Not bad for a bit of evening tinkering.

Tags: , , ,

4 Responses to “Migrating from ActiveMQ to WebSphere MQ”

  1. Andy Piper says:

    Nice idea. Seems like the sort of thing that would be a handy SupportPac. Have you posted a link about this over on mqseries.net?

  2. dale says:

    Thanks, Andy. Been a few years since I went through the SupportPac process. Wonder how onerous it is nowadays…?

  3. […] mentioned JMX before. Basically, a Java app can expose information and methods through a standard interface. […]