IBM MQのインストール～お役立ちコマンドなどのまとめ

# 0.はじめに

普段はQiitaを使用させていただいてばかりで、記事を書くことはなかったのですが、
転職を機に金融業界のジャンルから離れることとなりました。

当分触れなくなるであろう金融業界おなじみのMWの知識を忘れないため、
個人の備忘としても残しておこうかと思い記事にいたしました。
本記事のMQ以外のMWの知識も随時更新していきたいと思います。

# 1.ダウンロード

IBM MQは[こちら][ibmMqDownloadLink]のサイトからダウンロード可能です。

本記事記載時は、最新版の9.3および9.2がダウンロード可能で、いずれも試用版は90日間という制約がついています。
今回は「IBM MQ 9.3 Trial for Linux x86-64」を使用いたします。

# 2.インストール

## 2-1.OS情報

今回はVMWare上に構築した、CentOS8を使用しています。

```bash
cat /etc/os-release

NAME="CentOS Stream"
VERSION="8"
ID="centos"
# 以下省略
```

## 2-2.mqmユーザ/グループ作成

手動で作成しなくてもインストール時に自動で作成してくれるのですが、
実務だとOSのユーザやグループも基本的に管理されており、
作成するまでがセットになってるので、手順を記載しておきます。

```bash:
# グループ作成(gidは任意の値で)
groupadd -g 2000 mqm

# ユーザ作成(uidも任意の値で)
useradd -m -u 2000 -g mqm mqm
```

mqmユーザの`~/.bash_profile`に以下の情報を追記しておきましょう。

```bash:
export PATH=/opt/mqm/bin:/opt/mqm/samp/bin:/opt/mqm/gskit8/bin:$PATH
export LD_LIBRARY_PATH=/opt/mqm/gskit8/lib64:/opt/mqm/lib64:$LD_LIBRARY_PATH
```

## 2-3.ファイル確認&解凍

先ほどダウンロードしたファイルをサーバへアップロードし、解凍を行います。
ファイルが大量に表示されますが、使用するのは末尾にでてくるrpm形式のファイルのみです。

```bash:
ls -l "9.3.0.0-IBM-MQTRIAL-LinuxX64.tar.gz"
-rw-r--r-- 1 root root 784177682  3月 24 23:34 9.3.0.0-IBM-MQTRIAL-LinuxX64.tar.gz

tar -xvzf "9.3.0.0-IBM-MQTRIAL-LinuxX64.tar.gz"
MQServer/
#途中省略
MQServer/MQSeriesJRE-9.3.0-0.x86_64.rpm
```

## 2-4.ライセンス認証

解凍したファイルの中に`MQServer`というディレクトリがありますので、移動後ライセンス認証を行います。
`-accept`オプションを付けるとライセンスを表示せず許可できます。

```bash:
cd MQServer
./mqlicense.sh -accept
```

## 2-5.インストール

ここから実際のインストールです。
rpmコマンドで必要なパッケージを指定して、インストールを行うだけです。

必須パッケージ以外で個人的に導入した方が良いと感じる物は以下の3つです。
インストールコマンドは分けて記載していますが、実際は1つにまとめて問題ありません。

- **Samples**：sampleコマンドを使用してMQに対しPUT/GETすることが可能
- **Man**：マニュアル用のパッケージ
- **Msg_ja**：日本語化用パッケージ

```bash:
# MQのServer関連の必須パッケージ
rpm -ivh \
  MQSeriesServer-9.3.0-0.x86_64.rpm \
  MQSeriesGSKit-9.3.0-0.x86_64.rpm \
  MQSeriesRuntime-9.3.0-0.x86_64.rpm

# おすすめパッケージ
rpm -ivh \
  MQSeriesSamples-9.3.0-0.x86_64.rpm \
  MQSeriesMan-9.3.0-0.x86_64.rpm \
  MQSeriesMsg_ja-9.3.0-0.x86_64.rpm
```

無事ここまでインストールできれば、以下のようにパッケージが表示されると思います。

```bash:
rpm -aq | sort | grep MQ

MQSeriesGSKit-9.3.0-0.x86_64
MQSeriesMan-9.3.0-0.x86_64
MQSeriesMsg_ja-9.3.0-0.x86_64
MQSeriesRuntime-9.3.0-0.x86_64
MQSeriesSamples-9.3.0-0.x86_64
```

インストールが終わったら`mqm`ユーザに切り替えて確認をしてみましょう。

```bash:
# バージョン確認コマンド
dspmqver

Name:        IBM MQ
Version:     9.3.0.0
Level:       p930-L220607.TRIAL
BuildType:   IKAP - (Production)
Platform:    IBM MQ for Linux (x86-64 platform)
Mode:        64-bit
O/S:         Linux 4.18.0-536.el8.x86_64
O/S Details: CentOS Stream 8
InstName:    Installation1
InstDesc:
Primary:     No
InstPath:    /opt/mqm
DataPath:    /var/mqm
MaxCmdLevel: 930
LicenseType: Trial
```

# 3.各種オブジェクト作成

## 3-1.キューマネージャ作成

```bash:
# 今回はTEST01.QMという名前で作成
crtmqm TEST01.QM

この IBM MQ のコピーの残りの試行期間は 90 日です。
IBM MQ キュー・マネージャー 'TEST01.QM' が作成されました。
ディレクトリー '/var/mqm/qmgrs/TEST01!QM' が作成されました。
キュー・マネージャーはインストール済み環境 'Installation1' に関連付けられています。
キュー・マネージャー 'TEST01.QM' のデフォルト・オブジェクトを作成または置換しています。
デフォルト・オブジェクトの統計 : 作成 83、置換 0、失敗 0
設定を完了中です。
設定が完了しました。
```

## 3-2.キューマネージャ起動

```bash:
strmqm TEST01.QM

この IBM MQ のコピーの残りの試行期間は 90 日です。
システム・リソース RLIMIT_NOFILE が、IBM MQ には異常に低いレベルに設定されています。
IBM MQ キュー・マネージャー 'TEST01.QM' を開始しています。
キュー・マネージャーはインストール済み環境 'Installation1' に関連付けられています。
ログのやり直しフェーズ中に、キュー・マネージャー 'TEST01.QM' で 6 ログ・レコード がアクセスされました。
キュー・マネージャー 'TEST01.QM' のログのやり直しが完了しました。
キュー・マネージャー 'TEST01.QM' のトランザクション・マネージャーの状態が 回復されました。
プレーン・テキスト通信が有効になっています。
IBM MQ キュー・マネージャー 'TEST01.QM' が V9.3.0.0
を使用して開始されました。
```

## 3-3.リスナー起動

```bash:
# そのまま実行すると帰ってこないため、&でバックグラウンド起動
nohup runmqlsr -m TEST01.QM -t TCP -p 1414 &
```

## 3-4.キューマネージャーの状態確認

```bash:
dspmq
QMNAME(TEST01.QM)                                         STATUS(実行中)
```

## 3-5.MQプロンプト起動

```bash:
runmqsc TEST01.QM
5724-H72 (C) Copyright IBM Corp. 1994, 2022.
キュー・マネージャー TEST01.QM に対して MQSC を始動中です。
```

## 3-6.送信チャネル作成

```bash:
# CONNAME：ホスト名(ポート)で記載
# XMITQ：チャネルに紐づける伝送キューを記載
DEFINE CHANNEL('01_TO_02.CH') CHLTYPE(SDR) CONNAME('VM-TEST02(1414)') XMITQ('TEST01_TO_TEST02_XMIT.Q') REPLACE
     1 : DEFINE CHANNEL('01_TO_02.CH') CHLTYPE(SDR) CONNAME('VM-TEST02(1414)') XMITQ('TEST01_TO_TEST02_XMIT.Q') REPLACE
AMQ8014I: IBM MQ チャネルが作成されました。
```

## 3-7.受信チャネル作成

```bash:
DEFINE CHANNEL('02_TO_01.CH') CHLTYPE(RCVR) REPLACE
     2 : DEFINE CHANNEL('02_TO_01.CH') CHLTYPE(RCVR) REPLACE
AMQ8014I: IBM MQ チャネルが作成されました。
```

## 3-8.ローカルキュー作成

```bash:
DEFINE QLOCAL('TEST01_LOCAL.Q') REPLACE
     3 : DEFINE QLOCAL('TEST01_LOCAL.Q') REPLACE
AMQ8006I: IBM MQ キューが作成されました。
```

## 3-9.伝送キュー作成

```bash:
DEFINE QLOCAL('TEST01_TO_TEST02_XMIT.Q') USAGE(XMITQ) REPLACE
     4 : DEFINE QLOCAL('TEST01_TO_TEST02_XMIT.Q') USAGE(XMITQ) REPLACE
AMQ8006I: IBM MQ キューが作成されました。
```

## 3-10.リモートキュー作成

```bash:
# RQMNAME：接続先システムのキューマネージャ名を記載
# RNAME：接続先システムのローカルキューを記載
# XMITQ：チャネル作成時に記載した伝送キューを指定

DEFINE QREMOTE('TEST01_TO_TEST02_REMOTE.Q') RQMNAME('TEST02.QM') RNAME('TEST02_LOCAL.Q') XMITQ('TEST01_TO_TEST02_XMIT.Q') REPLACE
     5 : DEFINE QREMOTE('TEST01_TO_TEST02_REMOTE.Q') RQMNAME('TEST02.QM') RNAME('TEST02_LOCAL.Q') XMITQ('TEST01_TO_TEST02_XMIT.Q') REPLACE
AMQ8006I: IBM MQ キューが作成されました。
```

# 4.チャネル接続

今回はVMで作成したOSをコピーして、`VM-TEST02`というホスト名で接続先を作りました。
キューマネージャ名は`TEST02.QM`としています。

## 4-1.チャネルシーケンスリセット

```bash:
RESET CHANNEL('01_TO_02.CH')
     2 : RESET CHANNEL('01_TO_02.CH')
AMQ8023I: IBM MQ チャネルのリセット。
```

## 4-2.チャネル接続

```bash:
START CHANNEL('01_TO_02.CH')
     6 : START CHANNEL('01_TO_02.CH')
AMQ8018I: IBM MQ チャネルの開始が受け入れられました。
```

## 4-3.チャネル状態確認(SNDチャネル側)

こちらはSNDチャネル側から見たステータスです。

```bash:
# STATUSが「RUNNING」となっていれば接続成功
DISPLAY CHSTATUS('01_TO_02.CH')
     7 : DISPLAY CHSTATUS('01_TO_02.CH')
AMQ8417I: チャネル状況の内容を表示します。
   CHANNEL(01_TO_02.CH)                    CHLTYPE(SDR)
   CONNAME(192.168.179.131(1414))          CURRENT
   RQMNAME(TEST02.QM)                      STATUS(RUNNING)
   SUBSTATE(MQGET)                         XMITQ(TEST01_TO_TEST02_XMIT.Q)
```

## 4-4.チャネル状態確認(RCVチャネル側)

一方こちらはRCV側から見たステータスです。

```bash:
# STATUSが「RUNNING」となっていれば接続成功
DISPLAY CHSTATUS('01_TO_02.CH')
     1 : DISPLAY CHSTATUS('01_TO_02.CH')
AMQ8417I: チャネル状況の内容を表示します。
   CHANNEL(01_TO_02.CH)                    CHLTYPE(RCVR)
   CONNAME(192.168.179.130)                CURRENT
   RQMNAME(TEST01.QM)                      STATUS(RUNNING)
   SUBSTATE(RECEIVE)
```

## 4-5.チャネル切断

```bash:
STOP CHANNEL('01_TO_02.CH')
     8 : STOP CHANNEL('01_TO_02.CH')
AMQ8019I: IBM MQ チャネルの停止が受け入れられました。
```

この状態でチャネルのステータスを確認すると、`STOPPED`となっています。

```bash:
DISPLAY CHSTATUS('01_TO_02.CH')
     9 : DISPLAY CHSTATUS('01_TO_02.CH')
AMQ8417I: チャネル状況の内容を表示します。
   CHANNEL(01_TO_02.CH)                    CHLTYPE(SDR)
   CONNAME(192.168.179.131(1414))          CURRENT
   RQMNAME(TEST02.QM)                      STATUS(STOPPED)
   SUBSTATE( )                             XMITQ(TEST01_TO_TEST02_XMIT.Q)
```

## 4-6.キュー操作

### 4-6-1.プット

使用方法は`amqsput [キュー] [キューマネージャ]`となります。
今回は「TEST」という文字列を入力しました。
空行でEnterをすると終了とみなされます。

```bash:
which amqsput
/opt/mqm/samp/bin/amqsput

amqsput TEST01_LOCAL.Q TEST01.QM

Sample AMQSPUT0 start
target queue is TEST01_LOCAL.Q
TEST

Sample AMQSPUT0 end
```

この状態で`runmqsc`コマンドでキューの滞留件数(CURDEPTH)を確認すると、
件数が1となっていることがわかります。

```bash:
DISPLAY QLOCAL('TEST01_LOCAL.Q') CURDEPTH
     1 : DISPLAY QLOCAL('TEST01_LOCAL.Q') CURDEPTH
AMQ8409I: キューの内容を表示します。
   QUEUE(TEST01_LOCAL.Q)                   TYPE(QLOCAL)
   CURDEPTH(1)
```

### 4-6-2.ゲット

プットと同じく`amqsget [ローカルキュー] [キューマネージャ]`となります。
先ほど投入した「TEST」という文字列が表示されるかと思います。

```bash:
amqsget TEST01_LOCAL.Q TEST01.QM
Sample AMQSGET0 start
message <TEST>
no more messages
Sample AMQSGET0 end
```

キューの中身をゲットしてますので、滞留件数を確認すると0件になっています。

```bash:
DISPLAY QLOCAL('TEST01_LOCAL.Q') CURDEPTH
     1 : DISPLAY QLOCAL('TEST01_LOCAL.Q') CURDEPTH
AMQ8409I: キューの内容を表示します。
   QUEUE(TEST01_LOCAL.Q)                   TYPE(QLOCAL)
   CURDEPTH(0)
```

## 4-7.チャネル接続先へのデータの送受信

### 4-7-1.メッセージ送信

先ほど記載した、チャネル接続とamqsputを使用し接続先システム(今回は「VM-TEST02」)へ実際にデータを送信します。
メッセージは「TEST01 to TEST02 Message!」と送ってみます。

メッセージを送る際に気を付けるポイントとしては、先ほど作成したリモートキューを指定してメッセージを書き込んでください。

```bash:
amqsput TEST01_TO_TEST02_REMOTE.Q TEST01.QM

Sample AMQSPUT0 start
target queue is TEST01_TO_TEST02_REMOTE.Q
TEST01 to TEST02 Message!

Sample AMQSPUT0 end
```

### 4-7-2.メッセージ確認

受け手側で、リモートキューに紐づけたローカルキューを確認してみます。
1件メッセージが入ってるのがわかります。

```bash:
DISPLAY QLOCAL('TEST02_LOCAL.Q') CURDEPTH
     2 : DISPLAY QLOCAL('TEST02_LOCAL.Q') CURDEPTH
AMQ8409I: キューの内容を表示します。
   QUEUE(TEST02_LOCAL.Q)                   TYPE(QLOCAL)
   CURDEPTH(1)
```

`amqsget`コマンドで実際にメッセージを確認すると、先ほど送ったメッセージが届いているのがわかります。

```bash:
amqsget TEST02_LOCAL.Q TEST02.QM

Sample AMQSGET0 start
message <TEST01 to TEST02 Message!>
no more messages
Sample AMQSGET0 end
```

# 5.MQ構成情報取得

MQの中のオブジェクトを1コマンドでバックアップすることができます。
必要ない情報も大量に出てくるため、grepで `dmpmqcfg -x all -a -z -t all -o 1line -m TEST01.QM | 
grep "DEFINE" | grep -v "('SYSTEM"`のようにすると自身で作成したオブジェクトなどが表示できて便利です。

```bash:
dmpmqcfg -x all -a -z -t all -o 1line -m TEST01.QM

*******************************************************************************
* Script generated on 2024-03-25   at 21.53.01
* Script generated by user 'mqm' on host 'VM-CETNOS01'
* Queue manager name: TEST01.QM
* Queue manager platform: UNIX
* Queue manager command level: (930/930)
* Command issued: dmpmqcfg -x all -a -z -t all -o 1line -m TEST01.QM
*******************************************************************************
ALTER QMGR ACCTCONO(DISABLED) ACCTINT(1800) ACCTMQI(OFF) ACCTQ(OFF) ACTIVREC(MSG) ACTVCONO(DISABLED) ACTVTRC(OFF) AUTHOREV(DISABLED) CCSID(1208) CERTLABL('ibmwebspheremqtest01.qm') CERTVPOL(ANY) CHAD(DISABLED) CHADEV(DISABLED) CHADEXIT(' ') CHLEV(DISABLED) CHLAUTH(ENABLED) CLWLDATA(' ') CLWLEXIT(' ') CLWLLEN(100) CLWLMRUC(999999999) CLWLUSEQ(LOCAL) CMDEV(DISABLED) CONFIGEV(DISABLED) CONNAUTH('SYSTEM.DEFAULT.AUTHINFO.IDPWOS') CUSTOM(' ') DEADQ(' ') DEFCLXQ(SCTQ) DEFXMITQ(' ') DESCR(' ') IMGINTVL(60) IMGLOGLN(OFF) IMGRCOVO(YES) IMGRCOVQ(YES) IMGSCHED(MANUAL) INHIBTEV(DISABLED) INITKEY(' ') IPADDRV(IPV4) LOCALEV(DISABLED) LOGGEREV(DISABLED) MARKINT(5000) MAXHANDS(256) MAXMSGL(4194304) MAXPROPL(NOLIMIT) MAXUMSGS(10000) MONACLS(QMGR) MONCHL(OFF) MONQ(OFF) PARENT(' ') PERFMEV(DISABLED) PSMODE(ENABLED) PSCLUS(ENABLED) PSNPMSG(DISCARD) PSNPRES(NORMAL) PSRTYCNT(5) PSSYNCPT(IFPER) REMOTEEV(DISABLED) REPOS(' ') REPOSNL(' ') REVDNS(ENABLED) ROUTEREC(MSG) SCHINIT(QMGR) SCMDSERV(QMGR) SSLCRLNL(' ') SSLCRYP(' ') SSLEV(DISABLED) SSLFIPS(NO) KEYRPWD(' ') SSLKEYR('/var/mqm/qmgrs/TEST01!QM/ssl/key') SSLRKEYC(0) STATACLS(QMGR) STATCHL(OFF) STATINT(1800) STATMQI(OFF) STATQ(OFF) STRSTPEV(ENABLED) SUITEB(NONE) TREELIFE(1800) TRIGINT(999999999) FORCE
# 以下省略
```

# 6.オブジェクト権限

Javaのプログラムなど、mqmユーザやグループに所属していないユーザがMQのオブジェクトにアクセスしようとすると、エラーが発生します。
その際は、オブジェクト権限付与のコマンドなどで必要な権限を与えてあげるとアクセス可能になります。

- **-m**：キューマネージャ名
- **-t**：オブジェクトタイプ
- **-p**：権限付与ユーザ

末尾の`+connect`などはそのユーザに対しどのようなオブジェクト権限を付与するか記載します。
詳細は[こちら][ibmMqsetmqaut]の権限についてのページを参照ください。

## 6-1.キューマネージャへのオブジェクト権限付与

```bash:
setmqaut -m TEST01.QM -t qmgr -p testuser +connect
setmqaut コマンドが正常に完了しました。
```

付与された権限は以下のコマンドで確認することが可能です。

```bash:
dspmqaut -m TEST01.QM -t qmgr -p testuser
エンティティー testuser はオブジェクト TEST01.QM について次の許可を持っています:
        connect
```

## 6-2.キューへのオブジェクト権限付与
キューへの付与は以下のようになります。

```bash:
setmqaut -m TEST01.QM -t queue -n TEST01_LOCAL.Q -p mqadmin +get +put +dsp +browse +inq
setmqaut コマンドが正常に完了しました。
```

```bash:
dspmqaut -m TEST01.QM -t queue -n TEST01_LOCAL.Q -p mqadmin
エンティティー mqadmin はオブジェクト TEST01_LOCAL.Q について次の許可を持っています:
        get
        browse
        put
        inq
        dsp
```


# 7.MQ WebのインストールとREST APIによるオブジェクトの作成・表示
2024年12月12日 本項目追記しました。
元々この記事を投稿時にMQ Webについて記載したかったのですが、時間が無く記載できませんでした。
久しぶりにふとMQを触りたくなったのでついでに検証と記事のアップデートをしました。

元々CentOS8とIBM MQ9.3の組み合わせでしたが、MQ Webの検証はRHEL9とIBM MQ9.4の組み合わせに変わっています。
コマンドや設定に差異は無いため大丈夫かと思います。

## 7-1.MQ Webインストール
MQ Webに必要なパッケージはWeb本体と、JavaおよびJREだったかと思います。
以下のコマンドでインストールします。

```bash:
# MQ Webに必要なパッケージインストール
rpm -ivh \
  MQSeriesJRE-9.4.0-0.x86_64.rpm \
  MQSeriesJava-9.4.0-0.x86_64.rpm \
  MQSeriesWeb-9.4.0-0.x86_64.rpm 
```

## 7-2.MQ Webユーザ設定ファイルの更新
MQ WebはIBMのlibertyがベースとして動いています。
デフォルトのままだと認証用のユーザの設定が何もないので、サンプルからコピーしてきます。
詳細は`basic_registry.xml`ファイルに記載がありますが、ユーザ名・パスワードともに`mqadmin`でアクセスできます。

```bash:
# サンプルの認証ファイルは「/opt/mqm/web/mq/samp/configuration」に存在
[mqm@VM-RHEL01 mqweb]$ ls -l /opt/mqm/web/mq/samp/configuration/basic_registry.xml
-r--r-----. 1 mqm mqm 8785  6月  6  2024 /opt/mqm/web/mq/samp/configuration/basic_registry.xml
```

Libertyのベースディレクトリに移動し、サンプルファイルをコピーしてきます。
```bash:
[mqm@VM-RHEL01 mqweb]$ cd /var/mqm/web/installations/Installation1/servers/mqweb;pwd
/var/mqm/web/installations/Installation1/servers/mqweb
[mqm@VM-RHEL01 mqweb]$ cp -p /opt/mqm/web/mq/samp/configuration/basic_registry.xml .
[mqm@VM-RHEL01 mqweb]$ chmod 640 basic_registry.xml
[mqm@VM-RHEL01 mqweb]$ ls -l basic_registry.xml
-rw-r-----. 1 mqm mqm 8785  6月  6  2024 basic_registry.xml
```

Libertyの`server.xml`に`basic_registry.xml`をIncludeするように設定を追加します。
```diff_xml:server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed Materials - Property of IBM

      5724-H72

Copyright IBM Corp. 2016, 2017 All Rights Reserved.

US Government Users Restricted Rights - Use, duplication or
disclosure restricted by GSA ADP Schedule Contract with
IBM Corp.

 -->
<!--
This file defines the configuration for the mqweb server. Please do not 
make changes to this file. Any changes made by users should be in the 
referenced mqwebuser.xml file. 
 -->
<server>
    <include location="${wlp.install.dir}/mq/etc/mqweb.xml"/>
    <include location="mqwebuser.xml"/>
+   <include location="basic_registry.xml"/>
</server>
```
## 7-3.MQ Webの起動とアクセス
`strmqweb`コマンドでMQ Webを起動できます。
```bash:
[mqm@VM-RHEL01 mqweb]$ strmqweb

サーバー mqweb を始動中です。
サーバー mqweb がプロセス ID 11145 で始動しました。
```

また、`dspmqweb`コマンドでMQ Webの起動状態、アクセスURLも確認できます。

```bash:
[mqm@VM-RHEL01 mqweb]$ dspmqweb

MQWB1124I: Server 'mqweb' is running.
URLS:
  https://localhost:9443/ibmmq/rest/
  https://localhost:9443/ibmmq/console/
```

実際にブラウザでアクセスすると以下のように表示されるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566232/197b9bc2-c3ac-521c-3640-bc84b15b448d.png)

`mqadmin`でログインすると、以下のようなページが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566232/8816c759-0790-ac28-ad3c-658cc2626016.png)

## 7-4.MQ Webの機能紹介
機能紹介とは書いていますが、実際そこまで使ったことがないため、個人で触ってこんなことできるんだレベルのメモ書きになります…。

### 7-4-1.キューマネージャの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566232/84724fb3-a023-9318-e329-077fe07e7f89.png)

### 7-4-2.キューの確認
キューの使用率とか接続一覧見れるのは便利だと感じました(小並感)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566232/d91f7c91-4c03-edf7-8df2-65d5108862e9.png)

### 7-4-3.キューのメッセージ確認
これも便利だと思いましたが、メッセージのタイムスタンプ、インプット元、データなども見れます。
更にメッセージ内容をテキストベースでダウンロードも可能でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566232/13588daf-4f26-7d95-ac1f-a62a627d88a5.png)

## 7-5.REST APIによるMQ操作
これが今回の目玉？更新です。ずっとやりたかったのですが、やっと実機で触って色々できました…。
MQ Webインストール時に`https://localhost:9443/ibmmq/rest/`というURLも表示されていたかと思いますが、REST APIを使用することで、MQの状態表示やrunmqscコマンドの発行もできるようなります。
いくつか試して見たのでそのコマンドも一緒に載せておきます。

基本構文は以下の通りです。
```bash:
curl -k https://localhost:9443/ibmmq/rest/v1/admin/qmgr \
-X [GET|POST] \
-u mqadmin:mqadmin \ # MQ Webのユーザ情報を記載
-H "ibm-mq-rest-csrf-token: value" # CSRFヘッダーが必須のため入れる物
```

### 7-5-1.キューマネージャの状態確認
`TEST01.QM`部分に関しては、適宜環境に応じたキューマネージャ名を入れてください。

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v1/admin/qmgr/TEST01.QM \
-X GET \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value"
```

```bash:レスポンス
{"qmgr": [{
  "name": "TEST01.QM",
  "state": "running"
}]}
```

### 7-5-2.キューの一覧表示

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v1/admin/qmgr/TEST01.QM/queue \
-X GET \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value"
```

```bash:レスポンス
{"queue": [
  {
    "name": "SYSTEM.ADMIN.STATISTICS.QUEUE",
    "type": "local"
  },
# 途中省略
  {
    "name": "TEST01_TO_TEST02_REMOTE.Q",
    "type": "remote",
    "remote": {
      "queueName": "TEST02_LOCAL.Q",
      "qmgrName": "TEST02.QM"
    }
  },
  {
    "name": "TEST01_LOCAL.Q",
    "type": "local"
  },
  {
    "name": "TEST01_TO_TEST02_XMIT.Q",
    "type": "local"
  },
```

### 7-5-3.キューの個別表示

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v1/admin/qmgr/TEST01.QM/queue/TEST01_LOCAL.Q \
-X GET \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value"
```

```bash:レスポンス
{"queue": [{
  "name": "TEST01_LOCAL.Q",
  "type": "local"
}]}
```

### 7-5-3.キューの作成
[こちら][restapi]の公式ドキュメントに記載のコマンドでキューを作成してみました。

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v1/admin/qmgr/TEST01.QM/queue \
-X POST \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value" \
-H "Content-Type: application/json" \
-d "{\"name\":\"Q1\"}"
```

ちゃんとできています。

```bash:curl
[mqm@VM-RHEL01 ~]$ curl -k https://localhost:9443/ibmmq/rest/v1/admin/qmgr/TEST01.QM/queue/Q1 \
-X GET \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value"

{"queue": [{
  "name": "Q1",
  "type": "local"
}]}
```

### 7-5-4.メッセージのPUT/GET
そのままメッセージのPUT/GETをAPIで実行すようとするとエラーとなりました。
先にユーザ作成・権限付与などが必要なため、そちらも載せておきます。
ログを見ると、`put`に対しては`put`権限、`get`に対しては`get` `browse` `inq`がそれぞれ足りないと出ています。

PUTのエラー
```bash:curl
[mqm@VM-RHEL01 ~]$ curl -k https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/TEST01.QM/queue/TEST01_LOCAL.Q/message \
    -X POST \
    -u mqadmin:mqadmin \
    -H 'ibm-mq-rest-csrf-token: value' \
    -H 'Content-Type: text/plain;charset=utf-8' \
    -d 'API PUT!'
```

```bash:レスポンス
{"error": [{
  "msgId": "MQWB0103E",
  "action": "操作を実行するために必要な権限を取得して、要求を再実行依頼してください。",
  "completionCode": 2,
  "reasonCode": 2035,
  "type": "rest",
  "message": "MQWB0103E: 'TEST01_LOCAL.Q' にプットする権限がありません。",
  "explanation": "認証済みプリンシパルは、要求された  REST API 操作を実行する権限がありません。"
}]}
```

```bash:/var/mqm/qmgrs/TEST01!QM/errors/AMQERR01.LOG
2024年12月12日 15時16分55秒 - Process(3768.5) User(mqm) Program(amqzlsa0)
                    Host(VM-RHEL01) Installation(Installation1)
                    VRMF(9.4.0.0) QMgr(TEST01.QM)
                    Time(2024-12-12T06:16:55.491Z)
                    CommentInsert1(mqadmin)
                    CommentInsert2(TEST01_LOCAL.Q [queue])
                    CommentInsert3(put)

AMQ8077W: エンティティー 'mqadmin' には、オブジェクト
TEST01_LOCAL.Q [queue]
にアクセスするための十分な権限がありません。

説明:
指定されたエンティティーは、必要なオブジェクトにアクセスする権限がありません。
要求された次の権限が許可されていません: put
処置:
要求したオブジェクトに対する正しいレベルの権限がこのエンティティーに設定されていること、またはそのエンティティーが特権グループのメンバーであることを確認してください。
----- amqzfubx.c : 1693 -------------------------------------------------------
```

GETのエラー

```bash:curl
[mqm@VM-RHEL01 ~]$ curl -k https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/TEST01.QM/queue/TEST01_LOCAL.Q/message \
    -X DELETE \
    -u mqadmin:mqadmin \
    -H 'ibm-mq-rest-csrf-token: value'
```

```bash:レスポンス
{"error": [{
  "msgId": "MQWB0103E",
  "action": "操作を実行するために必要な権限を取得して、要求を再実行依頼してください。",
  "completionCode": 2,
  "reasonCode": 2035,
  "type": "rest",
  "message": "MQWB0103E: 'TEST01_LOCAL.Q' から取得する権限がありません。",
  "explanation": "認証済みプリンシパルは、要求された  REST API 操作を実行する権限がありません。"
}]}
```

```bash:/var/mqm/qmgrs/TEST01!QM/errors/AMQERR01.LOG
2024年12月12日 15時22分43秒 - Process(3783.6) User(mqm) Program(amqzlsa0)
                    Host(VM-RHEL01) Installation(Installation1)
                    VRMF(9.4.0.0) QMgr(TEST01.QM)
                    Time(2024-12-12T06:22:43.685Z)
                    CommentInsert1(mqadmin)
                    CommentInsert2(TEST01_LOCAL.Q [queue])
                    CommentInsert3(get/browse/inq)

AMQ8077W: エンティティー 'mqadmin' には、オブジェクト
TEST01_LOCAL.Q [queue]
にアクセスするための十分な権限がありません。

説明:
指定されたエンティティーは、必要なオブジェクトにアクセスする権限がありません。
要求された次の権限が許可されていません: get/browse/inq
処置:
要求したオブジェクトに対する正しいレベルの権限がこのエンティティーに設定されていること、またはそのエンティティーが特権グループのメンバーであることを確認してください。
----- amqzfubx.c : 1693 -------------------------------------------------------
```

#### 7-5-4-1.ユーザ作成
OS上にMQ Webでアクセスするユーザと同じ名前の`mqadmin`を作成します。
(設定などはだいぶ簡略化しています)

```bash:
[root@VM-RHEL01 ~]# useradd mqadmin
```

ちなみにですが、`mqm`グループに所属させれば権限が強めの自動で付いてるので以降の作業は不要だったりします。
```bash:
[root@VM-RHEL01 ~]# usermod -aG mqm mqadmin
[root@VM-RHEL01 ~]# id mqadmin
uid=2001(mqadmin) gid=2001(mqadmin) groups=2001(mqadmin),2000(mqm)
```

#### 7-5-4-2.権限付与
mqmユーザで対象のキューに対し権限を付与します。
「6.オブジェクト権限」の章で紹介した`setmqaut`でも内部では同じことをしていますが、せっかくなのでやり方を変えて`runmqsc`のコマンドで付与してみます。
`setmqaut`でのやり方は以下に記載しておきます。

<details><summary>setmqautによる権限付与</summary>

```bash:
[mqm@VM-RHEL01 ~]$ setmqaut -m TEST01.QM -t queue -n TEST01_LOCAL.Q -p mqadmin +get +put +browse +inq
setmqaut コマンドが正常に完了しました。
```

```bash:
[mqm@VM-RHEL01 ~]$ dspmqaut -m TEST01.QM -t queue -n TEST01_LOCAL.Q -p mqadmin
エンティティー mqadmin はオブジェクト TEST01_LOCAL.Q について次の許可を持っています:
        get
        browse
        put
        inq
```
</details>

<br>
確か名前はワイルドカード指定できたような気もします。

まずは権限の確認をします。

```bash:
[mqm@VM-RHEL01 ~]$ echo "DISPLAY AUTHREC PROFILE('TEST01_LOCAL.Q') OBJTYPE(QUEUE)" | runmqsc TEST01.QM
5724-H72 (C) Copyright IBM Corp. 1994, 2024.
キュー・マネージャー TEST01.QM に対して MQSC を始動中です。


     1 : DISPLAY AUTHREC PROFILE('TEST01_LOCAL.Q') OBJTYPE(QUEUE)
AMQ8864I: 権限レコードの詳細を表示します。
   PROFILE(TEST01_LOCAL.Q)                 ENTITY(mqm)
   ENTTYPE(GROUP)                          OBJTYPE(QUEUE)
   AUTHLIST(BROWSE,CHG,CLR,DLT,DSP,GET,INQ,PUT,PASSALL,PASSID,SET,SETALL,SETID)
```

権限を付与します。
```bash:
[mqm@VM-RHEL01 ~]$ echo "SET AUTHREC PROFILE('TEST01_LOCAL.Q') OBJTYPE(QUEUE) PRINCIPAL('mqadmin') AUTHADD(PUT,GET,BROWSE,INQ)" | runmqsc TEST01.QM
5724-H72 (C) Copyright IBM Corp. 1994, 2024.
キュー・マネージャー TEST01.QM に対して MQSC を始動中です。


     1 : SET AUTHREC PROFILE('TEST01_LOCAL.Q') OBJTYPE(QUEUE) PRINCIPAL('mqadmin') AUTHADD(put)
AMQ8862I: IBM MQ 権限レコードが設定されました。
```

再度確認すると`mqadmin`に権限がついているのがわかります。
```bash:
[mqm@VM-RHEL01 ~]$ echo "DISPLAY AUTHREC PROFILE('TEST01_LOCAL.Q') OBJTYPE(QUEUE)" | runmqsc TEST01.QM
5724-H72 (C) Copyright IBM Corp. 1994, 2024.
キュー・マネージャー TEST01.QM に対して MQSC を始動中です。


     1 : DISPLAY AUTHREC PROFILE('TEST01_LOCAL.Q') OBJTYPE(QUEUE)
AMQ8864I: 権限レコードの詳細を表示します。
   PROFILE(TEST01_LOCAL.Q)                 ENTITY(mqm)
   ENTTYPE(GROUP)                          OBJTYPE(QUEUE)
   AUTHLIST(BROWSE,CHG,CLR,DLT,DSP,GET,INQ,PUT,PASSALL,PASSID,SET,SETALL,SETID)
AMQ8864I: 権限レコードの詳細を表示します。
   PROFILE(TEST01_LOCAL.Q)                 ENTITY(mqadmin)
   ENTTYPE(GROUP)                          OBJTYPE(QUEUE)
   AUTHLIST(BROWSE,GET,INQ,PUT)
```

#### 7-5-4-3.APIによるメッセージPUT
```bash:curl
[mqm@VM-RHEL01 ~]$ curl -k https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/TEST01.QM/queue/TEST01_LOCAL.Q/message \
    -X POST \
    -u mqadmin:mqadmin \
    -H 'ibm-mq-rest-csrf-token: value' \
    -H 'Content-Type: text/plain;charset=utf-8' \
    -d 'API PUT!'
```

#### 7-5-4-4.APIによるメッセージGET
```bash:curl
[mqm@VM-RHEL01 ~]$ curl -k https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/TEST01.QM/queue/TEST01_LOCAL.Q/message \
    -X DELETE \
    -u mqadmin:mqadmin \
    -H 'ibm-mq-rest-csrf-token: value'
```

ちゃんと取得できました！
```bash:レスポンス
API PUT!
```

### 7-5-5.runmqscの実行
公式ドキュメントによると、プレーンテキスト形式の実行とJSON形式の実行があるそうです。

#### 7-5-5-1.プレーンテキスト形式

基本的な書き方は今までと同じですが、データ部に以下のように記述します。

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v2/admin/action/qmgr/TEST01.QM/mqsc \
-X POST \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value" \
-H "Content-Type: application/json" \
-d '{
"type": "runCommand",
  "parameters": {
    "command": "DISPLAY QLOCAL(TEST01_LOCAL.Q)"
  }
}'
```
ちゃんとrunmqsc形式で帰ってきていますが、かなり見辛いので成形等が必須ですね。

```bash:レスポンス
{
  "commandResponse": [{
    "completionCode": 0,
    "reasonCode": 0,
    "text": ["AMQ8409I: キューの内容を表示します。   QUEUE(TEST01_LOCAL.Q)                   TYPE(QLOCAL)   ACCTQ(QMGR)                             ALTDATE(2024-12-11)   ALTTIME(16.32.20)                       BOQNAME( )   BOTHRESH(0)                             CAPEXPRY(NOLIMIT)   CLUSNL( )                               CLUSTER( )   CLCHNAME( )                             CLWLPRTY(0)   CLWLRANK(0)                             CLWLUSEQ(QMGR)   CRDATE(2024-12-11)                      CRTIME(16.32.20)   CURDEPTH(1)                             CUSTOM( )   DEFBIND(OPEN)                           DEFPRTY(0)   DEFPSIST(NO)                            DEFPRESP(SYNC)   DEFREADA(NO)                            DEFSOPT(SHARED)   DEFTYPE(PREDEFINED)                     DESCR( )   DISTL(NO)                               GET(ENABLED)   HARDENBO                                IMGRCOVQ(QMGR)   INITQ( )                                IPPROCS(0)   MAXDEPTH(5000)                          MAXMSGL(4194304)   MAXFSIZE(DEFAULT)                       MONQ(QMGR)   MSGDLVSQ(PRIORITY)                      NOTRIGGER   NPMCLASS(NORMAL)                        OPPROCS(0)   PROCESS( )                              PUT(ENABLED)   PROPCTL(COMPAT)                         QDEPTHHI(80)   QDEPTHLO(20)                            QDPHIEV(DISABLED)   QDPLOEV(DISABLED)                       QDPMAXEV(ENABLED)   QSVCIEV(NONE)                           QSVCINT(999999999)   RETINTVL(999999999)                     SCOPE(QMGR)   SHARE                                   STATQ(QMGR)   STREAMQ( )                              STRMQOS(BESTEF)   TRIGDATA( )                             TRIGDPTH(1)   TRIGMPRI(0)                             TRIGTYPE(FIRST)   USAGE(NORMAL)                        "]
  }],
  "overallReasonCode": 0,
  "overallCompletionCode": 0
}
```

#### 7-5-5-2.JSON形式

JSON形式は書き方に少し癖がありますね。
公式ドキュメントなどを見ないとなかなかわからないです。
[こちら][restapi-json]に出来ることなどが色々書いています。

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v2/admin/action/qmgr/TEST01.QM/mqsc \
-X POST \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value" \
-H "Content-Type: application/json" \
-d '{
   "type": "runCommandJSON",
   "command": "display",
   "qualifier": "qlocal",
   "name": "TEST01_LOCAL.Q"
}'
```
かなり長いですが、しっかり結果が返ってきています。
`jq`コマンドなどを使うとさらに見やすくなりそうです。

```bash:レスポンス
{
  "commandResponse": [{
    "completionCode": 0,
    "reasonCode": 0,
    "parameters": {
      "cluster": "",
      "curdepth": 1,
      "usage": "NORMAL",
      "notrigger": "YES",
      "trigdpth": 1,
      "clchname": "",
      "put": "ENABLED",
      "qdploev": "DISABLED",
      "defprty": 0,
      "statq": "QMGR",
      "initq": "",
      "qsvciev": "NONE",
      "deftype": "PREDEFINED",
      "capexpry": "NOLIMIT",
      "streamq": "",
      "clwluseq": "QMGR",
      "msgdlvsq": "PRIORITY",
      "imgrcovq": "QMGR",
      "trigmpri": 0,
      "bothresh": 0,
      "qdphiev": "DISABLED",
      "descr": "",
      "distl": "NO",
      "maxmsgl": 4194304,
      "maxfsize": "DEFAULT",
      "boqname": "",
      "acctq": "QMGR",
      "clwlrank": 0,
      "propctl": "COMPAT",
      "qsvcint": 999999999,
      "trigtype": "FIRST",
      "npmclass": "NORMAL",
      "maxdepth": 5000,
      "altdate": "2024-12-11",
      "hardenbo": "YES",
      "opprocs": 0,
      "crtime": "16.32.20",
      "trigdata": "",
      "alttime": "16.32.20",
      "defbind": "OPEN",
      "monq": "QMGR",
      "get": "ENABLED",
      "scope": "QMGR",
      "qdpmaxev": "ENABLED",
      "share": "YES",
      "clusnl": "",
      "strmqos": "BESTEF",
      "process": "",
      "defpresp": "SYNC",
      "q)                   type": "QLOCAL",
      "custom": "",
      "clwlprty": 0,
      "defreada": "NO",
      "retintvl": 999999999,
      "crdate": "2024-12-11",
      "ipprocs": 0,
      "defpsist": "NO",
      "qdepthlo": 20,
      "qdepthhi": 80,
      "defsopt": "SHARED"
    }
  }],
  "overallReasonCode": 0,
  "overallCompletionCode": 0
}
```

## 7-5-6.インストール情報の表示

```bash:curl
curl -k https://localhost:9443/ibmmq/rest/v2/admin/installation \
-X GET \
-u mqadmin:mqadmin \
-H "ibm-mq-rest-csrf-token: value"
```

```bash:レスポンス
{"installation": [{
  "name": "Installation1",
  "version": "9.4.0.0",
  "platform": "unix"
}]}
```

# おまけ
よく現場ではテストの際に、メッセージを受信したかキューの`curdepth`を定点監視していました。
1年位前に自宅で似たようなツールが欲しいと思って作ったツールが出てきましたので、以下に載せておきます。

使用方法は単純で、第一引数にキューマネージャ名を渡すと、システムキューを除いたローカルキューの一覧を表示してくれます。

```bash:qdep_chk.sh
[mqm@VM-RHEL01 ~]$ ./qdep_chk.sh TEST01.QM
    queue name                    ：message count
    Q1                            ：0
    TEST01_LOCAL.Q                ：0
    TEST01_TO_TEST02_XMIT.Q       ：0
```

以下に公開したのでもしよければ見てください。

https://github.com/motuneko253/mq-qdep

# 8.最後に
書きたかったことが一通り書け、内容もブラッシュアップできたので満足です！

## 参考サイト

・IBM MQ ダウンロード
https://www.ibm.com/docs/ja/ibm-mq/9.3?topic=roadmap-mq-downloads

・mqlicense (インストール後のライセンスの受け入れ)
https://www.ibm.com/docs/ja/ibm-mq/9.3?topic=reference-mqlicense-accept-license-post-installation

・setmqaut (権限の付与または取り消し)
https://www.ibm.com/docs/ja/ibm-mq/9.3?topic=reference-setmqaut-grant-revoke-authority

・REST API および IBM MQ Console でのクライアント証明書認証の使用
https://www.ibm.com/docs/en/ibm-mq/9.2?topic=mcras-using-client-certificate-authentication-rest-api-mq-console

・POST - JSON 形式のコマンド
https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=adminactionqmgrqmgrnamemqsc-post-json-formatted-command

[ibmMqDownloadLink]: https://www.ibm.biz/ibmmqtrial
[ibmMqsetmqaut]: https://www.ibm.com/docs/ja/ibm-mq/9.3?topic=reference-setmqaut-grant-revoke-authority
[restapi]: https://www.ibm.com/docs/en/ibm-mq/9.2?topic=mcras-using-client-certificate-authentication-rest-api-mq-console
[restapi-json]: https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=adminactionqmgrqmgrnamemqsc-post-json-formatted-command