IBM Developer

Tutorial

Setting up AMQP for your MQ apps

Customize the MQ container to communicate with MQ through the AMQP channel

By Soheel Chughtai, Avinash V G, Aslihan Ilgin Okan, Richard J. Coppen

AMQP is a non-proprietary messaging protocol that provides an open standard wire protocol for messaging. Apache Qpid is an open-source project that provides messaging tools for AMQP as core libraries. They don’t claim it, but think of it as a development kit for AMQP-based apps.

IBM MQ provides support for AMQP APIs through an AMQP channel that accepts connections from AMQP client applications. Using IBM MQ, Apache Qpid applications can perform publish/subscribe messaging and point-to-point messaging. Messaging is not just confined to AMQP client applications, as intercommunication with client applications based on other IBM MQ API stacks is possible.

Prerequisites

To complete this tutorial, you’ll need to install:

  • Git command line
  • Docker or Podman. Podman commands shown in these tutorial steps can be replaced with Docker commands.
  • Optionally for TLS keytool which is included in Java JDKs. I use SDKMAN to install and manage versions of Java and Maven on my machine.
  • Optionally for TLS openssl in most cases you will already have it.

Steps

First, you need to enable and run the IBM MQ AMQP service, and then, if desired, enable TLS over AMQP.

Enable and run the IBM MQ AMQP service

For AMQP client applications to successfully communicate with IBM MQ, the IBM MQ AMQP service needs to be running. To enable the AMQP service, you will clone and customize the MQ Container.

  1. Clone the MQ Container repository by running this command:

     git clone -b 9.4.2 https://github.com/ibm-messaging/mq-container.git
    

    CD to the cloned repository, mq-container.

  2. Enable AMQP in the MQ container by editing the Dockerfile-server file, scrolling down to the “Build stage to reduce MQ packages using genmqpkg” section, navigating to the line that starts with "ENV” and changing the third line from genmqpkg_incamqp=0 to genmqpkg_incamqp=1.

  3. Set up AMQP authority, channel, and service properties by adding the contents of the add-dev.mqsc.tpl file to the bottom of the /incubating/mqadvanced-server-dev/10-dev.mqsc.tpl file in your cloned repository.

  4. Build a developer Docker image.

    Make sure you are in the mq-container directory. Then, build a development server image.

     make build-devserver
    

    If you are building your container on windows, then set up WSL 2 using the blog Building a customised IBM MQ Container on WSL 2 as a guide.

    If you are running on an Apple Silicon ARM based MacOS machine then, you can run the AMD64 image in emulation mode, but will need to be on at least MacOS Sequoia Version 15. On MacOS, build the image using the command:

     ARCH=amd64 make build-devserver
    

    If you see this error Error response from daemon: network mode "build" not supported by buildkit, then run this command:

     DOCKER_BUILDKIT=0 make build-devserver
    

    Then, check the image ID:

     podman image ls
    

    You should see output similar to this output:

    Output of docker image command

  5. Start the customized MQ container.

     podman run --env LICENSE=accept --env MQ_QMGR_NAME=QM1 --env MQ_APP_PASSWORD=passw0rd --env MQ_ADMIN_PASSWORD=passw0rd --publish 1414:1414 --publish 9443:9443 --publish 5672:5672 --detach ibm-mqadvanced-server-dev:9.4.2.1-amd64
    
  6. Verify that the AMQP port is indeed enabled at port 5672 in your MQ queue manager by running:

     podman ps
    

    You should see output similar to this output:

    Output of podman ps command

Enabling TLS over AMQP

  1. Create a server keystore

    If you want to enable TLS then you will need a .p12 keystore for the server and a truststore for the client. Fortunately the container contains a test script which will generate them.

    Go to the directory mq-container/test/tls. You can use the keystore in this directory with the default password or generate your own using the generate-test-cert.sh script.

    If you chose to generate your own. Create a working directory eg mq-container/keys and copy the generate-test-cert.sh to that directory.

     mkdir <path to mq-container directory>/keys
     cd <path to mq-container directory>/keys
     cp ../test/tls/*.sh .
    

    Edit the generate-test-cert.sh file, and change password that will be used for the keystore. For example:

     PASSWORD=<Any secure password you want>
    

    In our examples we set the password to PASSWORD=SecureKeySt0re

    Save the file, and run the script.

     ./generate-test-cert.sh
    

    A directory listing should show the new keystore and client trust store. You will use the server.p12 keystore in the next step.

    Output of keystore directory listing

    You can use the client-trust.jks client trust store for any Java clients that want to connect to your AMQP Queue Manager server over TLS.

  2. Create MQSC instructions to configure AMQP for TLS.

    Create a new file tls-amqp.mqsc and add the contents of add-tls-amqp.mqsc to it.

    Modify the keystore password to the password you used to create the keystore in step 5.

     ALTER QMGR KEYRPWD('SecureKeySt0re')
    

    Leave the location of the server.p12 as is. You will map the location of the server.p12 to this value when you start the Queue Manager.

     ALTER QMGR SSLKEYR('/amqp-tls/server.p12')
    
  3. Start the customized MQ container.

     podman run --env LICENSE=accept --env MQ_QMGR_NAME=QM1 --env MQ_APP_PASSWORD=passw0rd --env MQ_ADMIN_PASSWORD=passw0rd --volume <path_to_tls_folder>:/amqp-tls --volume <path_to_tls-amqp.mqsc>:/etc/mqm/tls-amqp.mqsc --publish 1414:1414 --publish 9443:9443 --publish 5672:5672 --detach ibm-mqadvanced-server-dev:9.4.2.1-amd64
    

    Note: There is no TLS build; you are using the same build from the previous step. In this run, you have added two extra volumes to enable TLS.

     --volume <path_to_tls_folder>:/amqp-tls
    

    This maps the location of the keystore as the volume /amqp-tls. In our case this was set to:

     --volume ./keys:/amqp-tls
    

    Recall that amqp-tls/server.p12 in turn was the path that we added to the MQSC, which brings us to the second additional volume.

     path_to_tls-amqp.mqsc
    

    In our case, this was set to:

     --volume ./tls-amqp.mqsc:/etc/mqm/tls-amqp.mqsc
    

    This maps to the AMQP TLS MQSC file you created in step 6. The MQSC with the associated keystore are provided together on the podman run command that started the container. This allows the container to successfully configure TLS for the AMQP channel.

    On MacOS the container will start although you will see the following warning:

     WARNING: image platform (linux/amd64) does not match the expected platform (linux/arm64)
    
  4. Verify that the AMQP port is indeed enabled at port 5672 in your MQ queue manager by running.

     podman ps
    

    You should see output similar to this output:

    Output of podman ps command

  5. Verify that TLS is configured.

    Open a terminal on your container by running the following command:

     podman exec -ti <container_id> /bin/bash
    

    Start the MQSC command line:

     runmqsc
    

    Run the MQSC command.

     DISPLAY QMGR SSLKEYR
    

    A response showing SSLKEYR(/amqp-tls/server.p12) as below confirms that the key store registry has been successfully configured.

    Output of display qmgr command

    Exit runmqsc.

     quit
    

    Exit out of the container.

     exit
    

Summary and next steps

With this tutorial, we customized our MQ container to be able to communicate with MQ through the AMQP channel. We did this by customizing the MQ container and enabling AMQP. MQ can now recognize communications attempted by applications using the AMQP port.

With AMQP for MQ enabled, you can incorporate various AMQP based toolkits and frameworks into your MQ applications. For example, you can create a simple Vert.x reactive application or develop JMS applications with Quarkus and GraalVM.