【クイックスタート&チュートリアル】令和に生きるエンジニアのためのIBM MQ入門

いわゆるDXのお仕事で調査する機会があり、備忘録として。

# IBM MQとは
その名の通り、IBM製のMessage Queue(MQ)であり、結構歴史のあるミドルウェア製品のようです。

https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=mq-introduction

※来年で30周年⁉︎らしいです…

# ローカル検証環境の構築

今回はDockerコンテナでIBM MQを起動します。
大まかな構築の流れは公式ドキュメントに記載されているので、ここでは各コマンドの詳細等を補足しながら説明していきます。

https://developer.ibm.com/tutorials/mq-connect-app-queue-manager-containers/

## 前提環境

- Mac/Windows PC
- Dockerを利用可能であること
- curlコマンドを利用可能であること

## 1. IBM公式のDockerイメージを取得

IBM MQ構築用の便利な公式Dockerイメージが利用可能なので、ローカル環境にPullします。

```bash
# 執筆時点での最新イメージ(9.2.4.0-r1)にバージョンを固定して取得
docker pull icr.io/ibm-messaging/mq:9.2.4.0-r1

# 正常にイメージがPullされていることを確認
docker image ls icr.io/ibm-messaging/mq
# <実行結果例>
# REPOSITORY                TAG          IMAGE ID       CREATED        SIZE
# icr.io/ibm-messaging/mq   9.2.4.0-r1   5211ea6323b7   9 months ago   928MB
```

## 2. Dockerボリュームの作成

Dockerコンテナ停止後もIBM MQのデータを保持できるように、Dockerコンテナにマウント可能な追加記憶領域であるDockerボリュームを作成します。

```bash
# Dockerボリュームをqm1dataという名称で作成
docker volume create qm1data

# 正常にボリュームが作成されたことを確認
docker volume ls --filter name=qm1data
# <実行結果例>
# DRIVER    VOLUME NAME
# local     qm1data
```

## 3. 取得したDockerイメージからDockerコンテナを起動

PullしたDockerイメージからDockerコンテナをバックグラウンドで起動し、IBM MQ用サーバを構築します。
なお、Dockerコンテナには、先ほど作成したDockerボリュームをマウントしておきます。

```bash
# Pullしたイメージ(icr.io/ibm-messaging/mq:9.2.4.0-r1)からコンテナを起動
docker run \
    --name QM1 \
    --detach \
    --rm \
    --env LICENSE=accept \
    --env MQ_QMGR_NAME=QM1 \
    --env MQ_APP_PASSWORD=passw0rd \
    --publish 1414:1414 \
    --publish 9443:9443 \
    --volume qm1data:/mnt/mqm \
    icr.io/ibm-messaging/mq:9.2.4.0-r1

# 正常にコンテナが起動されていることを確認
docker ps --filter name=QM1
# <実行結果例>
# CONTAINER ID   IMAGE                                COMMAND            CREATED          STATUS          PORTS                                                                                            NAMES
# c7db9337091c   icr.io/ibm-messaging/mq:9.2.4.0-r1   "runmqdevserver"   17 seconds ago   Up 13 seconds   0.0.0.0:1414->1414/tcp, :::1414->1414/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9157/tcp   QM1
```

補足情報として、Dockerコンテナ起動時に指定した各パラメータの詳細は、以下の通りです。

```bash
# docker run \
#     --name QM1 \                     # 起動するコンテナ名をQM1として定義
#     --detach \                       # コンテナをバックグラウンドで起動
#     --rm \                           # コンテナの停止と共に利用済みコンテナを自動削除
#     --env LICENSE=accept \           # IBM MQ の利用規約に承諾
#     --env MQ_QMGR_NAME=QM1 \         # IBM MQ のキュー・マネージャー名をQM1として定義
#     --env MQ_APP_PASSWORD=passw0rd \ # IBM MQ の起動時に自動作成されるappユーザ及びadminユーザの初期パスワードを定義
#     --publish 1414:1414 \            # IBM MQ 接続エンドポイントのポート開放: Webコンソール及びクライアントアプリケーション用
#     --publish 9443:9443 \            # IBM MQ 接続エンドポイントのポート開放: REST API用
#     --volume qm1data:/mnt/mqm \      # 事前に作成したDockerボリューム(qm1data)をコンテナ内の特定パス(/mnt/mqm)にマウント
#     icr.io/ibm-messaging/mq:9.2.4.0-r1
```

## 4. Dockerコンテナ内のIBM MQを確認

起動したDockerコンテナにログイン後、コマンドをいくつか実行して、Dockerコンテナ内部に存在する IBM MQ の状態を確認します。

```bash
# 起動済みコンテナにログイン
docker exec -it QM1 bash
# ログインに成功すると以下のようにコンテナ内のbashが起動される
# bash-4.4$
```

Dockerコンテナ内部のbashから、IBM MQ のバージョン・起動ステータスを確認します。

```bash
# IBM MQのバージョンを表示 (display mq version)
dspmqver
# <実行結果例>
# Name:        IBM MQ
# Version:     9.2.4.0
# Level:       p924-L211105.DE
# BuildType:   IKAP - (Production)
# Platform:    IBM MQ for Linux (x86-64 platform)
# Mode:        64-bit
# O/S:         Linux 5.10.47-linuxkit
# O/S Details: Red Hat Enterprise Linux 8.5 (Ootpa)
# InstName:    Installation1
# InstDesc:    IBM MQ V9.2.4.0 (Unzipped)
# Primary:     N/A
# InstPath:    /opt/mqm
# DataPath:    /mnt/mqm/data
# MaxCmdLevel: 924
# LicenseType: Developer

# IBM MQの起動ステータスを確認 (display mq)
dspmq
# <実行結果例>
# QMNAME(QM1)                                               STATUS(Running)
```

確認後は、Dockerコンテナからログアウトします。

```bash
# コンテナ内のbashからログアウト
exit
```

## 5. IBM MQのWebコンソールにログイン

Chrome等のブラウザから`https://localhost:9443/ibmmq/console/`にアクセスすると、以下のようなIBM MQのWebコンソールが表示されます。

![IBM_MQ_web_console.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357086/45a7da53-0a52-2297-99fe-710b06e9fb1e.gif)
※上記の画像は公式ドキュメント「新規 Web コンソール のクイック・ツアー」より引用

https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=console-quick-tour-new-web

# IBM MQの利用

ここからは、ローカル環境に構築したIBM MQとメッセージを送受信してみます。

## REST API経由でのメッセージ送受信

curlコマンドを使用して、IBM MQのREST APIを叩きます。

https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=mrar-rest-api-resources

```bash
# メッセージ'Hello, MQ!'をIBM MQに送信 (Enqueue)
curl \
    -i \
    -k \
    https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message \
    -X POST \
    -u app:passw0rd \
    -H 'ibm-mq-rest-csrf-token: blank' \
    -H 'Content-Type: text/plain;charset=utf-8' \
    -d 'Hello, MQ!'

# <実行結果例>
# HTTP/1.1 201 Created
# Content-Language: en-US
# Content-Length: 0
# Content-Type: text/plain; charset=utf-8
# ibm-mq-md-messageId: 414d5120514d31202020202020202020ea361363012d0040
# Date: Sat, 03 Sep 2022 14:04:10 GMT
# 

# IBM MQからメッセージを受信 (Dequeue)
curl \
    -i \
    -k \
    https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message \
    -X DELETE \
    -u app:passw0rd \
    -H 'ibm-mq-rest-csrf-token: blank'

# <実行結果例>
# HTTP/1.1 200 OK
# Content-Type: text/plain; charset=utf-8
# Content-Language: en-US
# ibm-mq-md-expiry: unlimited
# ibm-mq-md-messageId: 414d5120514d31202020202020202020ea361363012d0040
# ibm-mq-md-persistence: nonPersistent
# Content-Length: 9
# Date: Sat, 03 Sep 2022 14:08:13 GMT
# 
# Hello, MQ!
```

## クライアントアプリケーションによるメッセージ送受信

Javaライブラリ等を利用することで、IBM MQと直接やり取り可能なクライアントアプリケーションを開発できます。

https://mvnrepository.com/artifact/com.ibm.mq/com.ibm.mq.allclient

クライアントアプリケーションの具体的なコードについては、以下の公式サンプルが有用です。

https://github.com/ibm-messaging/mq-dev-samples/blob/master/gettingStarted/jms/com/ibm/mq/samples/jms/JmsPutGet.java

# [補足] ローカル検証環境の停止・削除

```bash
# 起動中のDockerコンテナを停止 (起動時のオプション指定により停止後に自動削除される)
docker container stop QM1

# 作成したDockerボリュームを削除
docker volume rm qm1data
```

# 参考リンク

- 公式ラーニングパス「IBM MQ Developer Essentials」

https://developer.ibm.com/learningpaths/ibm-mq-badge/

- IBM MQ 公式ドキュメント

https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=mq-about