This blog is a guide for developers that are looking to get started with IBM message queues. By the end of this blog, you should be able to:
- Have a basic understanding of how message queues work
- How to set up your application to use an IBM MQ
- Spin up a docker container to host the message queue
- How to switch queues your application writes to without re-deploying your application
A basic understanding of Java and Spring is recommended for this tutorial.
Before discussing the specifics and requirements to set up IBM MQs, let’s discuss what problem message queues are solving and what type of application can benefit the most from a message queue architecture.
In the ever-growing use of microservice architecture, the ability for multiple services to communicate with each other in a fast and asynchronous way is very useful. Using message queues enables two applications to communicate with each other asynchronously by writing to a queue instead of calling each other. By doing so, message queues additionally make the two applications less coupled.
Alternative methods to using message queues like using REST APIs make the message processing a blocking process which makes asynchronous processing difficult.
The advantage of using queues is that due to the option for asynchronous communication, they’re always available to process the next available “message” in the queue. Unfortunately, alternative methods like REST API and GraphQL are naturally unable to accommodate the message blocking issues, making MQ the better solution. Another advantage of using an MQ between services is that if one of the services goes down, it allows the service to process the requests when it comes back up. In other words, it essentially decouples the services.
What is MQ?
A Message Queue (MQ) is a component of messaging middleware that makes asynchronous communication between applications easier. Message queue temporarily stores messages by providing an intermediary platform that allows software components to access the queue. In this tutorial, we will be using IBM MQ specifically.
Some of the key features and benefits of IBM MQ are:
- High availability
- Deployment flexibility
- Compatibility with various languages and frameworks
- Extensive documentation and support
The MQ setup consists of two main parts:
- Setting up a docker container for IBM MQ
- Java Messaging Service to use the MQ
The first part of setting up comprises of creating a docker compose file and a shell script. The docker compose file will be used by the shell script to spin up the docker container that will allow the applications to use message queues locally. The following code snippet shows a basic docker compose code that is used to define the docker image.
The following script spins up the docker container and creates the queues that will be used by our application. This script only creates two queues, but this command can be used multiple times based on how many queues the application needs to read and write from.
That concludes the first part of the setup.
For the second part, the first step is creating a spring application. For this, we will use a spring initializer. We’ll be using Java Messaging Service (JMS) for this tutorial. JMS lets Java applications use messaging systems – like IBM MQ in our case – to communicate. We’ll also need to add the required dependencies for JMS.
Next, we’ll create a class called JmsConfig.java where we’ll inject the necessary properties required to connect the Java application to the message queues using Spring Framework’s @Value annotation. These properties can be added to the application.yaml file under the resources folder of your application.
Important things to note in the above snippet:
- The properties that we inject using here are used by the JmsConnectionFactory Bean to establish a connection to the message queues.
Next, we want to make sure our application is also able to receive messages. To do this, we can add another class called QueueConfig.java that will let our application receive messages. We’ll use SimpleJmsListenerEndpoint to do that. We set each queue we create as a destination to a SimpleJmsListenerEndpoint which lets JMS read messages from that queue.
Now, we need to add a class called MessageHandler.java that we’ll use to process the received message from and send messages to the queue.
That concludes the basic setup required for the application to be able to read and write messages from the queue. Note that this is just the basic setup. The next step would be to create a class that will process, and store information passed in the message based on the purposes of your application.
When the application is deployed in different environments, we can run into situations where we want to use different sets of queues for different purposes such as testing where we don’t want to send a test message to a real queue. This next part of the blog will help us do that.
Inject the following JMS-related properties that we defined earlier in the tutorial.
Create a REST API controller called ContextController.java with a post endpoint that can be used to switch the queues programmatically.
The request body of this endpoint is of the same type as the JmsConfig bean we injected above. We can use BeanUtils.copyProperties method to copy the new JMSproperties to the JmsConfig bean.
Next, do the following to close the existing connections and update the connectionfactory with the new JMSproperties.
Finally, we need to make sure that the new set of queues is accepting messages by using SimpleJmsListenerEndpoint like we did when we first set up the application.
That concludes the context switch part of the tutorial.
To summarize, this tutorial went through the following things:
- Spinning up a docker container locally to host IBM MQ
- Using JMS to connect to, read, and write to the MQ
- Add a controller for the ability to programmatically switch queues in a deployed application
This guide is simply a skeleton framework that can be enhanced flexibly according to the needs of your project. In the future, I will create a separate tutorial for adding SSL and how MQ can be deployed to AWS.
We’re dedicated to creating an encouraging, inclusive, and fruitful work environment for all of our team members. Check out open opportunities on our Careers page.