About cookies on this site Our websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising. For more information, please review your options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.
Tutorial
Take the IBM MQ messaging app coding challenge
Develop a real world messaging solution with IBM MQ
On this page
Dive in and see how simple a real-world messaging solution can be.
Follow the step-by-step instructions to develop a messaging app that interacts with a queue manager and apps that we've provided in a container. Along the way, you'll master new messaging concepts and skills that you'll need to pass the quiz to earn the IBM MQ Developer Essentials badge.
Prerequisites
To complete this challenge, you'll need the following in your local environment:
- Java Development Kit (JDK) to develop and run applications. You need a minimum of JDK 9 installed. JDK 11 is recommended. If you don't have Java installed, go to the IBM Semeru Runtime Downloads page, select Java 11 and your platform. On some platforms, you can pull in and install it using the command line. Just make sure to get the JDK (Java Development Kit), for developing, not just the JRE (Java Runtime Environment).
- Sample code for this MQ Developer Challenge, in the
mq-dev-badge-sample
repo. - Maven to manage all the
*.jar
files.
You can use either Docker or Podman to build images and run containers. This tutorial uses the Docker commands. If you are using Podman, then replace docker
with podman
in the commands.
The challenge
Congratulations! You’ve just started a new job as a developer for a conference ticket reseller.
Your team lead has tasked you with creating a new messaging application that integrates with an MQ conference booking service and automates the ticket allocation process. This will ensure your new organization keeps pace with customer demand. We’ve already built the event booking service, including a queue manager, and made it available as a Docker image. You just need to build the image and run it.
Then, for this challenge, you will be coding the reseller application. We have provided a Java application template in GitHub with comments and code stubs. You just need to fill in the gaps by coding the JMS and message processing parts of the scenario.
Your code will:
- Connect to a queue manager (the one we provided)
- Subscribe to the
newTickets
topic - Send a
request message
to purchase a batch of tickets, set areply-to destination
andmessage expiry
of 15 minutes (we don’t want to commit to a purchase indefinitely) - Get a
response message
from the confirmation queue specified as thereply-to destination
- Print out the result
If you get stuck along the way, we’ve included a cheat sheet and packaged a model answer for reference.
We've provided three ways to engage with the challenge:
- Write the code right now, as you go
- Review the model answer application
- Have a go at fixing a simple defect
Messaging service architecture of the client app
When tickets become available for sale, the third-party service generates a reseller message to notify its subscribers (that’s you!).
Ticket resellers then request a batch of tickets for the conference event. Once tickets are allocated, the reseller is free to distribute to their customers.
Let’s take a look at the architecture diagram. Your will be building the reseller application.
Messages are published on the newTickets
topic every 30 seconds by the event booking service.
The message payload contains an EventId
and the number of available tickets.
The Reseller application uses the received payload to construct a request message.
Finally, the booking service consumes from the purchase queue and responds to each message on the JMSReplyTo
destination (confirmation queue) with a payload set, as follows:
Accepted - <number_of_tickets_allocated>
or
Rejected - Sold out
Highlighting the client messaging app you'll create
You are creating the ticket reseller app, which is an IBM MQ client application.
To help you focus on your MVP (minimum viable product), this diagram shows the elements of the IBM MQ JMS app that you have to create in relation to the MQ server and the reseller service we’ve provided in a Docker container. The main client app actions are named and numbered.
When you've completed coding your application, your application will:
- Connect to a queue manager
Subscribe to a topic
- Receive a publication
- Process a publication
On receiving a publication, construct and send a request message to the purchase queue to purchase zero or more tickets. Request message has properties:
- says how many tickets to ask for
- for a given
EventID
- sets a
reply-to destination
for the confirmation (the response) - sets
message expiry
to 15 minutes
Puts the request message to a purchase (request) queue
- (The ticket purchase coordinator app does a get from this queue)
- (Processes the message and allocates a number of tickets, if any are available)
- (Put a message to the confirmation (response) queue. Response message has properties:
- says how many tickets have been allocated, if any
- for a given
EventID
)
- Does a get from the response queue
- Prints how many event tickets have been purchased
The following behavior is required from the client messaging app:
- Handle a published a message on the
newTickets
topic every 30 seconds. - Provide the prompt to ask the user how many of the available tickets they want to purchase.
- Handle the response that the conference event booking service provides after processing your request message.
- Print the outcome of the response to
stdout
.
Check your prerequisites
First, let's check that you have the Java Development Kit installed. Issue this command:
java -version
You should see output similar to:
If you completed the first tutorial in this learning path, you should already have the JDK (Java Development Kit) and the MQClient directory with the com.ibm.mq.allclient.jar
and javax.jms-api-2.0.1.jar
files. You will not need these .jar
files to run the challenge app. If you have the JDK and .jar
files in the MQClient
directory, you can still keep them but for this tutorial all the .jar
files required are managed by Maven (which you installed as part of the prerequisites).
If you did not complete that tutorial, let's get you set up:
Create the MQClient directory to save the files needed for the sample, for example in your home directory:
mkdir MQClient
Get the challenge code
You need to download the badge challenge code, which is stored in the ibm/messaging/mq-dev-badge-sample GitHub repository.
Go to our ibm/messaging/mq-dev-badge-sample
repository in GitHub, and click the clone or download button. You can choose to clone with SSH, use HTTPS, or download a ZIP with the code. Clone or unzip the repository into the MQClient directory.
Once you have the code locally, change to the sample code directory:
cd mq-dev-badge-sample
If you downloaded the .zip file, the sample code directory will be
mq-dev-badge-sample-master
.Run the print-working-directory command to make sure you’re in the right place:
pwd
You should see your path ending in:
~/MQClient/mq-dev-badge-sample
On Windows, you should see your path ending in:
~\MQClient\mq-dev-badge-sample
Type ls to list the contents of the directory:
ls
You should see these directories and files:
├-- MQTicketService
│ ├-- Dockerfile
│ .
│ .
│ └-- TicketGenerator
├-- ModelAnswer
├-- ModelAnswerWithDefectToFix
└-- TicketReseller
The MQTicketService
directory has the Dockerfile
with the definition for building an image and standing up a container with the MQ server (queue manager). It also has the TicketGenerator
directory with the Java code for the apps/services that will interact with your app when you code and run it. The server-side apps get started inside the container at the same time as the queue manager.
Standing up the Event Booking system
Before you get started coding your reseller app, let’s see how the server-side or the event booking service works.
First, we’ll build a Docker image and run the container with MQ and the app that publishes ticket availability and responds to requests from your app.
Once we see it work, we’ll let it end and restart it later once we’re ready to test the challenge app.
Follow these steps to stand up the event booking service:
We need to create a queue manager for the application to work. We do this by running an IBM MQ Advanced to Developers container, onto which we will deploy the Ticket Service application.
First change to the
MQTicketService
directory.cd MQTicketService
Build the image using the Dockerfile located in the directory. On Windows, Linux, or Mac computers (but not MacOS Silicon ARM64 computers), run this command:
docker build . -t mqbadge:latest
Important: If you are using a MacOS Silicon ARM64 computer, you will need to build and run an IBM MQ container image natively, if you have not done so already. Use these instructions to build and run this image natively.
Then, check which image you have:
docker images
Your
baseImageRunStage
argument uses this formatrepository/ImageName:tag
, which will be used when building your docker image. For example:baseImageRunStage="localhost/ibm-mqadvanced-server-dev:9.4.0.0-arm64"
.Execute the following code(for MacOS Silicon ARM64 computers):
docker build --build-arg platformArch=arm64 --build-arg buildImageRunStage="localhost/ibm-mqadvanced-server-dev:9.4.0.0-arm64". -t mqbadge:latest
Next, go back to the TicketGenerator directory.
cd TicketGenerator
Then, run a container with the image created.
docker run -e LICENSE=accept -e MQ_QMGR_NAME=QM1 -e LOG_FORMAT=json -e MQ_APP_PASSWORD=passw0rd -p 1414:1414 -p 9443:9443 --detach -ti --name mqebs mqbadge:latest
You should now have a container running.
To see the events being published, you can attach to the container and view its output.
docker attach mqebs
You should start to see events being published along with the container logs.
The container process includes:
- The publisher app, which sends a publication about available tickets every 30 seconds
- Ticket purchase coordinator, which processes purchase requests and allocates a batch of tickets.
Important: This is the core of the event booking business where purchase requests are processed, and tickets are allocated. IBM MQ Messaging performs a crucial role within the conference event processing code, providing assured delivery of high value messages between the conference event booking service and ticket resellers. It’s vital that the conference event booking business get this right as overselling tickets or failing to respond to requests would be damaging to their reputation. IBM MQ server, which is the queue manager that hosts the subscription topic
newTickets
, the purchase queue for request messages, and the confirmation queue for response messages.Queues were created administratively by running MQSC commands when the Docker container started. Queue objects can also be created with the MQ Console, using the MQ REST interface or programmatically.
Optionally, if you would like to run the application outside of the container and without the logs, you will need to re-build the application outside of the container and run it.
All dependencies (that is, the jar files) are pulled by Maven using the
pom.xml
file stored in the directory which tells Maven which.jar
files to download. Build the application by running the following command:mvn clean package
Then, execute the code.
On Linux and Mac:
java -cp target/TicketGenerator-1.4.jar: com.ibm.mq.badge.Manager
On Windows:
java -cp target\TicketGenerator-1.4.jar com.ibm.mq.badge.Manager
Very quickly you’ll see the output from the container starting in your command line. Look out for events starting to be published:
The event booking system is now running inside the container. Note that the container was started with the --detach
option so that the logs are not displayed to the screen while the container is running.
If you encounter an error, as shown below, it is likely due to the queue manager not being properly initialized yet. Wait a bit longer for the container to initialize before you run the Java command.
You are now ready to start developing your reseller application. But first, let's see how the ModelAnswer app works with the event booking service.
Run the ModelAnswer app to see it in action
Open another terminal, and change to the ModelAnswer
directory.
cd MQClient/mq-dev-badge-sample/ModelAnswer
You can override the default MQ connection settings using environment variables on the system where you run your Reseller application code.
- MQ_BADGE_QM_HOSTNAME - Specify the Host name or IP address of your queue manager
- MQ_BADGE_QM_NAME - Set the queue manager name
- MQ_BADGE_QM_PORT - Listener port for your queue manager
- MQ_BADGE_CHANNEL - MQ Channel name
- MQ_BADGE_USER - Username that application uses to connect to MQ
MQ_BADGE_PASSWORD - Password that the application uses to connect to MQ
This is the default configuration. Run the following in your command terminal.
On Linux and Mac:
export MQ_BADGE_QM_HOSTNAME="localhost"
export MQ_BADGE_QM_NAME="QM1"
export MQ_BADGE_QM_PORT=1414
export MQ_BADGE_CHANNEL="DEV.APP.SVRCONN"
export MQ_BADGE_USER="app"
export MQ_BADGE_PASSWORD="passw0rd"
On Windows:
set MQ_BADGE_QM_HOSTNAME="localhost"
set MQ_BADGE_QM_NAME="QM1"
set MQ_BADGE_QM_PORT=1414
set MQ_BADGE_CHANNEL="DEV.APP.SVRCONN"
set MQ_BADGE_USER="app"
set MQ_BADGE_PASSWORD="passw0rd"
Arrange the two terminal windows side by side so that you can easily interact with both.
In the container terminal on the left, if the container has stopped running, you need to restart the container and see the output from the server and the app running. Start the container:
docker restart mqebs
Get the output from the container in the terminal by attaching to it.
docker attach mqebs
Or to see output without logs, go to Step.3 in ‘Standing up the Event Booking system’
In the terminal on the right, run the following command to create the .jar file with the dependencies required for the application:
mvn clean package
In the terminal on the right, get the command ready to run the ModelAnswer application, but wait for the events in the server terminal to start appearing before entering the commands.
From that directory, run the command to compile the application:
On Linux and Mac:
java -cp target/ModelAnswer-1.4.jar: com.ibm.mq.demo.Reseller
On Windows:
java -cp target\ModelAnswer-1.4.jar com.ibm.mq.demo.Reseller
Now when you run the command to start the ModelAnswer application you should see:
Once the next set of available tickets is published, you should see the prompt in the ModelAnswer terminal asking for a number of tickets you want to secure:
Enter a number of tickets you want to reserve in the ModelAnswer app terminal. You should see the exchange messages in both the terminals.
The container will exit once there are no more ticket events to publish.
The ModelAnswer app will not exit till you enter a number of tickets for the last event advertised. You should then see the app disconnect because apps in the container also disconnected and the MQ queue manager stopped threads and closed connections.
Now that you've seen how the app and the service interact, go ahead and write your own Java code in the TicketReseller
directory, or fix the defect and get things to work in the ModelAnswerWithDefectToFix
directory.
Coding your reseller application
For convenience, you might want to use a Java IDE such as Eclipse. Alternatively, you can develop your code in your favorite editor such as Atom.
In the editor of your choice, open either the TicketReseller
or the ModelAnswerWithDefectToFix
directory.
The sample code is broken down into multiple classes. To complete the challenge, you need to make code updates to these classes:
SessionBuilder.java
TicketSubscriber.java
TicketRequester.java
The comments in the stubs of these classes should guide you on what needs to be done. Refer to the previous sections for what your app needs to do, for help in compiling, and for examples of how the apps work.
Need to debug?
Did something go wrong? Take a look at the cheat sheet.
Enhancing your application
To learn more about production-ready client messaging applications, you need to consider security and message persistence. You might also consider the transactionality of your messages.
Why use messaging?
The conference event system and reseller applications are loosely coupled. Asynchronous messaging allows us to integrate these components and build in a buffer, or shock absorber. Should either component lose connectivity, fail or experience fluctuations in throughput, the messaging layer will deal with any instability. Our application code is simplified as the messaging layer takes care of the difficult stuff like security, recovery and persistence of message exchange between the components.
The messaging API provides a framework so that our reseller application logic is driven when a message is delivered rather than continually polling the server to check for work. This removes unnecessary load from the network and conference event application. IBM MQ allows the solution to scale as demand increases.
Publish/subscribe messaging style
Publish/subscribe is one of the messaging styles that IBM MQ implements. The other is point-to-point. In point-to-point, messages are exchanged between two single applications. In publish/subscribe, one or many publishers can publish to one or many subscribers to a topic.
Here's how the publish/subscribe messaging style is implemented in our solution:
The event booking service is the publisher, and your reseller app is one of the subscribers. Let's talk through the other components in this messaging style:
- Topics are objects and they have properties.
- The key property of a topic is a topic string.
- Messages are published to a topic string by a publisher.
- Each publication is to a single topic string. Subscribers register an interest in, or subscribe to, a topic string.
- When a publisher publishes a message to a topic string, one or more subscribers for that topic string receives the publication message.
- A JMS application can use the JMS destination object which maps to a topic in the same way as it would use the destination to map to a queue, in a point to point scenario. For the publication to reach the subscriber successfully, both the publisher and the subscriber must match same topic string. The subscriber will get publications only from the time they subscribe to a topic.
- If a publication is sent before the subscription by a specific application is created, that application will not get it.
Request/Response messaging pattern
Request response or request reply is an integration or messaging pattern where the application that sends a message to another application, requires a reply of some sort from the receiving application. This is often based on the point to point messaging style and can be synchronous (the sending application waits for the response before it times out) and asynchronous (also called request/callback, where the sending application disconnects but sets up a callback to handle a reply).
Your reseller app is the sender app, and the event booking service is the receiver app.
The sending application usually sets a reply-to-destination and a correlation-id so that a response can get back to the right sender application.
For the event booking service the reply-to destination has been defined administratively on the queue manager. However, the requester could dynamically create a temporary destination from its JMS session to complete the exchange.
Securing your application
TLS is great for securing your messages while in transit. Solution security, however, is an end-to-end problem. You will want to keep your messages safe when they are stored on a queue? IBM MQ provides a compressive access control model to help IBM MQ Administrators restrict access to queues as well as the browsing, consumption and sending of messages. Some solutions require finer grained security control to ensure that producers and consumers can only exchange messages read messages based on set of certificates and keys. IBM MQ AMS (Advanced Message Security) provides a high level of protection for sensitive data flowing through the MQ network encrypting messages at rest, and ensuring that the message date is only viewable to the intended message recipients. AMS message signing applies a digital signature on the message, allowing the identity of the sender and the authenticity of the message to be confirmed.
Find out how you can configure your queue manager and client application to use TLS to encrypt messages as they flow between the server and the client, over the internet.
Setting message persistence in your application
It is important to consider message persistence when designing an application. IBM MQ supports persistent and non-persistent messaging. In our event booking scenario, we use persistent messaging as the default setting on the pre-defined MQ queues.
Critically, in the event of a system outage, non-persistent messages may be lost following recovery. While in most cases non-persistent messaging might provide for faster exchange of messages, it’s not the right solution for all applications.
For example, persistence might be of importance for a high value message, but less so for a scenario where information messages are transmitted continually. In the latter cases, the system design might tolerate some level of message loss.
You can read more about message persistence in the IBM MQ Docs.
What about the transactionality of my messages?
Often production applications are more sophisticated than our sample, with each interaction involving multiple resources, such as messages or database updates, being coordinated as a single atomic operation. Resources that are managed in this way are said to occur within a unit of work, or a transaction.
For example, a simple banking transaction might require one account to be debited by $100 and another credited by the same amount. A transactional coordinator is used to ensure that either both operations complete successfully, or none of them complete at all.
As application complexity increases, enterprise scale frameworks are used to coordinate transactions across multiple applications or back end systems. Enterprise scale frameworks such as those provided by:
- Open Liberty, which is an IBM Open Source Project
- IBM WebSphere Application Server
- Spring
Focusing on app performance
If you want to make sure your application is going to perform reliably and well, have a look at these best practices for developers.
Summary
Congratulations! You've checked out our GitHub repository with three ways to engage with our sample. Be sure that you've checked out the MQ developer cheat sheet, because it's packed full of ninja moves that every MQ developer should know.