Tutorial

Take the coding challenge: Code, build, and deploy an IBM MQ app to AWS Cloud

Get hands-on with the code behind the messaging playground sample app

By

Richard J. Coppen,

Francesco Rinaldi

To continue building your messaging skills, you’ll develop a messaging application modelled on the messaging playground sample app that you deployed in the Build and deploy an IBM MQ app to AWS Cloud tutorial.

By getting hands on with the code, you will be able to develop, deploy, and debug a new feature in a messaging app.

Prerequisites

The challenge

You will develop a University Donations application for a fictional university research project that will allow the academic team to accept donations in multiple currencies for its brand-new global research program. Sponsors can visit the program website and make a contribution in a currency of their choice. In the initial version of the solution, three currencies will be supported (USD, EUR and GBP).

The solution PoC will be modelled within the messaging playground sample app platform (which you previously deployed).

Your code will:

  • Produce and consume a message on a donation queue (‘DEV.QUEUE.1’).
  • Set a message property (‘currency’) to represent the currency in which the donation has been made. The message payload will represent the value of the donation only.
  • Route the funds to the university’s bank accounts allowing the researchers to optimize their processing and accounting functions.

You will work with the message-session-manager.js JavaScript file. It uses the IBM MQ MQI API with Node.js to connect to and exchange messages with IBM MQ.

To keep things simple and ensure developers with a range of experiences can complete the coding challenge, we’ve provided three ways to engage with the challenge:

  • Option 1: Just show me the code The message-session-manager-model-answer.js file has been provided with full working code. You can review the code in this file to see how this challenge has been solved.
  • Option 2: I want to get familiar with the code The message-session-manager-broken-model-answer.js includes the code for an implementation for the new feature, but there’s a catch: there’s a bug in the solution that you need to solve to get the right behavior from the application.
  • Option 3: I’m ready to code the solution The message-session-manager.js file is ready for you to get creative with and develop your own solution to the challenge.

If you are new to coding, then you might want to start at the beginning and work up to building your own implementation. Alternatively, if you are an experienced developer, you might want to jump straight into coding your own implementation.

Architecture of the client app

The proposed system architecture will enable sponsors to donate funds to the university. Building the full end-to-end solution will require multiple microservices and presentation tiers to be developed. To keep things simple, we will focus this coding challenge on the message and message property that will be exchanged between the various microservices. We will also borrow the presentation layer from the showcase application to minimize the coding effort. To visualize both the producer (donation) and consumer (funds received) messaging actions, the roles of both parties are presented on a single web page.

Architecture of the university donations sample app

The webpages for making and receiving donations are part of the Presentation Layer, which sends PUT or GET requests to the Message Session Manager (MSM). The Message Session Manager then processes these requests by completing the MQ PUT and GET operation requests.

The entire messaging playground application is built on three layers (Presentation Layer, Message Session Manager, and Queue Manager), and each layer will be deployed as individual Docker containers.

We’ve already implemented the changes to the Presentation Layer. You just need to enable this new tab and it’s ready to integrate with your newly coded features once you have developed them.

The code needed to deploy the architecture is in the mq-dev-patterns GitHub repo.

This repository also includes a wide range of samples for some of the many APIs, frameworks, and programming languages that IBM MQ supports.

The only directory you will use for this coding challenge is ibm-messaing-mq-cloud-showcase-app. If you’ve decided to code the solution yourself, you might find useful hints on how to solve this coding challenge in the other projects!

The ibm-message-mq-cloud-showcase-app directory is structured as follows:

Directory structure fot the messaging playground sample app

  • The frontend directory contains the code for the presentation layer.
  • The backend directory contains the code for the Message Session Manager. The msms subdirectory contains the message-session-manager.js source files that you will need for this challenge.
  • The .env file contains environment variables and deployment parameters.
  • The aws-docker-compose.yaml file is used by docker-compose to build the container images for the front end, the Message Session Manager, and the queue manager and deploy them out on Amazon Elastic Container Registry (AWS ECS).
  • The docker-compose.yml file is used by docker-compose to build the front end, Message Session Manager, and the queue manager and deploy them locally.

Run the playground app locally

For this coding challenge, you need to prepare and run the messaging playground application locally. To streamline debugging and deployment, the code changes you make will be tested on your local machine before being published to AWS ECR.

With the mq-dev-patterns repository cloned to your local machine, open the subdirectory ibm-messaging-mq-cloud-showcase-app with your favorite editor.

To change from the ticket reseller and management system that you deployed in the previous tutorial to this university donations system, you need to change the docker-compose.yml and aws-docker-compose.yaml files. Open the file and change the REACT_APP_IS_FOR_CODING_CHALLENGE property from false to true:

Setting the `REACT_APP_IS_FOR_CODING_CHALLENGE` property to true

To deploy and run the messaging playground app the following variables must be set in the .env file located at /ibm-messaging-mq-cloud-showcase-app/.env:

  1. Set the APP_PASSW0RD and ADMIN_PASSW0RD variables to the passwords you will use for interacting (as a messaging user and as an admin) on the queue manager.
  2. Set the IMAGES_ECS_REGISTRY_URI and CLUSTER_NAME to a value suitable for your AWS ECS environment. If you are running the messaging playground application in your local environment, you still need to set a value to these variables in order to start your application.

For example:

Example of setting the environment variables

Your messaging playground application is now configured for this challenge and ready to be tested on your local machine using Docker containers.

Note: For ARM64 Apple Silicon machines, you will need to build the queue manager image and edit the docker-compose.yaml file to refer to the image. Go to these instructions, "Running on apple silicon arm64."

To build the three containers (Presentation Layer, Message Session Manager, and queue manager) underpinning the messaging playground application, open a terminal from the ibm-messaging-mq-cloud-showcase-app directory open and type in your terminal window:

docker-compose build

After the containers have been built successfully, you can start the messaging playground application by typing:

docker-compose up

You can now open the messaging playground application by browsing: http://localhost:3000

The MQ web console is also reachable locally by browsing: http://localhost:9443/ibmmq/console

Learn more about using the IBM MQ Web Console in this tutorial.

In the messaging playground app, you have the flexibility to add multiple producers and consumers as needed. For each producer application, you can specify the amount of the donation and its currency. This is modelled as a message produced by the producer and consumed by a consumer. Consumers can only receive donations in the assigned currency.

After the amount and the currency have been selected, a donation can be sent by a producer by clicking on the Send Cash button.

Screen capture of sender, sending cash

For each university consumer account, you can choose the currency for which donations should be filtered.

Screen capture of filtering payments by currency

Coding the university donations application

The default "message-session-manager.js" file contains the implementation for the "I'm ready to code the solution" version. However, you can use a different version by:

  • Renaming "message-session-manager.js" to message-session-manager-model-answer.jsfor the Just show me the code! version (option 1).
  • Renaming “message-session-manager.js" to message-session-manager-broken-model-answer.js for the I want to get familiar with the code! version (option 2).

These are the functions the messaging playground application should support to handle the university donations application:

  • Set the currency of the donation as a message property on the PUT requests.
  • Set a filter on the messages based on the University Bank Account selected currency.
  • GET and return the message payload (donation amount) and the message property that assigns a currency to the front end.

Consuming applications must read both the payload and the currency property to establish the correct donation amount and its currency.

An IBM MQ message broadly consists of three parts: a descriptor, message properties, and the payload:

  • Each message contains a message descriptor (MQMD) with control information. The descriptor contains information related to the routing and control of the message. For example, it will contain a unique message ID and datestamp.
  • Message properties are used by the application programmer to store data related to the message. In this case, we are using a message property to store the currency of a donation. This allows messages to be routed to the appropriate university bank account processing stage without the routing application needing to inspect the payload.
  • The payload of the message contains the core application content, which in this case is the donation amount. The solution might optionally encrypt the payload for privacy and security reasons.

Solve the coding challenge using option 1 - "Just show me the code"

For this option, review the code in the message-session-manager-model-answer.js file. The challenge is to find the lines of code that permit setting messages’ properties, and filtering by properties.

This version contains the full working solution for the coding challenge. The methods to PUT, GET, and filter messages have all been coded correctly. If you are struggling with option 2 or option 3, you can review this code to see how to solve the coding challenge.

Solve the coding challenge using option 2 - "I want to get familiar with the code"

For this option, work with the message-session-manager-brokenModelAnswer.js file. This version already contains the code, but the code contains bugs that you must fix.

For this coding challenge, the methods you should focus on debugging are:

  • performPutWithProperties
  • getSingleMessageWithProperties

Although with this version of the challenge a producer can send messages to consumers and consumers can consume messages from producers, the property “currency” which enables messaging filtering it is not used in the right way. Due to this incorrect configuration of this property within the messages, consumers are receiving donations with the property set to “EUR” only. In addition, the value of the currency returned from the getSingleMessageWithProperties is incorrect.

Although the GET and PUT functions contain some bugs, you can still run the messaging playground application to observe the wrong behavior.

Solve the coding challenge using option 3 - "I’m ready to code the solution"

Congratulation for choosing the most challenging option!

The methods to PUT, GET, and filter messages have been not coded at all. For this option, you will work with the message-session-manager.js file.

Examples of how to set and read properties in and from a message in Node.js can be found in the mq-mqi-nodejs repository.

An example of how to select (filter) messages from a queue can be found in the IBM MQ docs.

You need to code the following functions to solve this coding challenge: the performPutWithProperties method, the getSingleMessageWithProperties method, and the performOpen method.

performPutWithProperties method

The performPutWithProperties method (currently empty) should contain the code for putting messages (donations for this university donations scenario) with properties to a queue. This function is triggered when a producer sends a donation, which means that the Send Cash button has been clicked from the front end component.

This method receives two parameters:

  • message and the amount of the donation
  • quantity and the number of donations per transaction (this is always 1 in this particular scenario).

Within this method you will need to use the following Class properties:

  • this.currency is the currency of the sent donations is not passed through as a parameter but is stored in the class property
  • this[_HCONNKEY] and this[_HOBJKEY] are values that store the connection with the queue and queue manager and are required to perform the PUT operation.

The data of the message to PUT into a queue should be a JSON object following this schema:

msgObject = {
  ‘Message’ : message,
  ‘Count’ : quantity,
  ‘Sent’ : ‘’ “+ new Date()
};

This method must return a Promise.

You need to find a way to set the currency as a parameter of a message to be PUT into a queue.

getSingleMessageWithProperties method

The getSingleMessageWithProperties method contains the instructions for getting one message (alongside its properties) from a queue and returning them to the front end.

This function does not receive any parameters.

Within this method you will need to use the following Class properties:

  • this[_HCONNKEY] and this[_HOBJKEY] are values that store the connection with the queue and queue manager that are required to perform the GET operation.
  • This method has to return a Promise which has to resolve: If a GET request has been performed with success resolve(msgObject) is returned. The msgObject is a JSON object with the following schema:
msgObject = {
  msgObject : contentOfTheMessageObtained,
  properties : {
currency : {
  currencyFromTheMessageProperty
    }
}
}
  • resolve(null) if some errors occurred.

performOpen method

The performOpen method creates a connection with a queue. In this method (which is not empty compared to the other two above), you need to make some changes to specify the currency that your messages should be selected for the GET requests.

Debugging the university donations application

The debugger will help you observe the Message Session Manager’s behavior from the MQ console.

To start the debugger, replace the last line of the /ibm-messaging-mq-cloud-showcase-app/backend/Dockerfile (CMD npm start) with this command: CMD npm debug.

The debugger by default is attached to all JavaScript files within the Message Session Manager directory that do have the debug_info variable that follows this pattern require('debug')('mqapp-[*]:info');.

If you want the debugger to be activated on a single file only, you can set the debug field in the package.json file (/ibm-messaging-mq-cloud-showcase-app/backend/AWS-showcase-backend/package.json) to the corresponding debug_info variable of that file. For example, if you need the debugger activated only for the worker.js file which does have the debug_info equal to let debug_info = require(‘debug’)(‘mqapp-mqclient:info’);, then you can set debug in the package.json as DEBUG = mqapp-mqclient node server.js.

Apply your changes

To apply your changes, you need to rebuild and redeploy the container images.
To do so, stop the previously running containers by typing in your terminal (from the path of the ibm-messaing-mq-cloud-showcase-app directory): docker-compose down.

After all the containers are stopped, type docker-compose build and then restart the containers by typing docker-compose up.

When you are happy with your changes and solution deployed locally, you can deploy the messaging playground application on AWS by following the same steps used in the previous tutorial.

Conclusion

With this challenge, you had the chance to get hands-on to familiarize yourself with the code behind the messaging playground sample application and understand how applications can put and get properties into and from an MQ message and how the message selection mechanism occurs.

The flexibility, scalability, and openness of IBM MQ will allow you, with minor changes in the message-session-manager.js file, to change the behavior of how messages are exchanged between your applications without having to change the business logic of your system.