実践習得 IBM MQの基本
メッセージ記述子(MQMD V2)(1)
※本連載は最新のmqpgf/mqpcfに基づいて改定されることがあります。常に最新バージョンをダウンロードしてご使用ください。
MQMD V2の概要
MQを使用した通信で、複数のメッセージで順序付けを行ったり、複数のメッセージを同一のマシンで処理する必要のある場合などに、「論理メッセージのグループ化」という機能を使用します。 また、大きなサイズのデータをMQメッセージで転送する要件などで、そのメッセージを一定のサイズに分割したい場合の為に「メッセージのセグメント化」という機能が提供されています。 これらの機能は、MQMDのV2で追加されたフィールドに関連付けられています。 MQで取り扱える物理メッセージの最大長には制約があり、キューマネージャー、キュー、チャネルのそれぞれのMAXMSGLで設定されます。 キューマネージャー全体で取り扱える物理メッセージの最大長はキューマネージャーのプロパティのMAXMSGLで、個別のキューで取り扱える物理メッセージの 最大長はキューのプロパティのMAXMSGL、チャネルで伝送可能な最大メッセージ長はチャネルのプロパティのMAXMSGLで設定します。 デフォルトはそれぞれ4MBで、100MBまで設定可能です。(設定可能な値はプラットフォームやバージョンによって異なる場合があります。) これらのサイズを超えるメッセージを取り扱う必要がある場合、「メッセージのセグメント化」を検討します。 MAXMSGLは通常、キューマネージャー >= チャネル >= キューになるように設定する場合が一般的ですが、キューマネージャーのMAXMSGLでセグメント化したい場合などは、この限りではありません。 「論理メッセージのグループ化」と「メッセージのセグメント化」の両方を組み合わせて使用することも可能です。
MQのV2の各フィールドを理解する為に、MQでのメッセージの単位ついて整理しておきます。
グループ: | グループは1つまたは複数の論理メッセージからなっています。 MQメッセージの一番大きな概念です。 全ての論理メッセージが同じGroupIdを持ちます。 |
論理メッセージ: | 同じグループ内の論理メッセージ毎に異なるMsgSeqNumberが使用されます。 論理メッセージは複数のセグメントに分割されている場合があります。 グループ内のMsgSeqNumberは1から始まり、論理メッセージの数まで存在します。 |
セグメント: | メッセージを通常特定のサイズでさらに分割したものです。 同じGroupId、同じMsgSeqNumberを持っている場合でも、それぞれのセグメントでOffsetフィールドに設定される値が相違します。 |
物理メッセージ: | 1つのセグメントは、1 つの物理メッセージです。 1つの論理メッセージは、セグメントに分割されない限りは1つの物理メッセージです。 |
MQMD V2で追加されたフィールド
MQMD V2で追加されたフィールドについて概略説明します。
[ GroupId ]
タイプ: MQBYTE24
サイズ: 24バイト
初期値: MQGI_NONE_ARRAY(全てNULL(0x00))
入出力: 入出力
メッセージが属しているメッセージ・グループを示します。 メッセージのセグメント化を使用する場合にもこのフィールドは使用されます。 MQPUT呼び出しで、MQPMO_LOGICAL_ORDER が指定されている場合は、キューマネージャーが自動的にIDを生成します。 MQGET呼び出し時に、MQGMO_VERSION_2を使用し、MQMO_MATCH_GROUP_IDと共にGroupIdを指定すると、MsgId、CorrelIdの場合と同様に指定したGroupIdを持つメッセージをGETすることができます。
[ MsgSeqNumber ]
タイプ: MQLONG
サイズ: 4バイト
初期値: 1
入出力: 入出力
メッセージ・グループ内の論理メッセージの番号です。 MQPUT呼び出しで、MQPMO_LOGICAL_ORDER が指定されている場合は、キューマネージャーが自動的に適切な順序番号を設定します。 MQGET呼び出し時に、MQGMO_VERSION_2を使用し、MQMO_MATCH_MSG_SEQ_NUMBERと共にMsgSeqNumberを指定すると、指定したMsgSeqNumberを持つメッセージをGETすることができます。
[ Offset ]
タイプ: MQLONG
サイズ: 4バイト
初期値: 0
入出力: 入出力
論理メッセージの先頭からのオフセット(バイト数)を示します。 アプリケーションでセグメント分割を行う場合に、MQPUT呼び出しで、MQPMO_LOGICAL_ORDER が指定されている場合は、キューマネージャーが自動的に適切なオフセットを設定します。 MQGET呼び出し時に、MQGMO_VERSION_2を使用し、MQMO_MATCH_OFFSET と共にOffsetを指定すると、指定したOffsetを持つメッセージをGETすることができます。
[ MsgFlags ]
タイプ: MQLONG
サイズ: 4バイト
初期値: MQMF_NONE
入出力: 入出力
キューマネージャーによるセグメント分割を制御する「セグメント化フラグ」と、物理メッセージのグループ、セグメントに属する状態を示す「状況フラグ」の2つの目的で使用されます。
それぞれ、下記のフラグ(値)を持ちます。
セグメント化フラグ: | |
MQMF_SEGMENTATION_INHIBITED | 0x00000000 |
MQMF_SEGMENTATION_ALLOWED | 0x00000001 |
状況フラグ: | |
MQMF_MSG_IN_GROUP | 0x00000008 |
MQMF_LAST_MSG_IN_GROUP | 0x00000010 |
MQMF_SEGMENT | 0x00000002 |
MQMF_LAST_SEGMENT | 0x00000004 |
キューマネージャーにセグメント分割を許可する場合は、MQMF_SEGMENTATION_ALLOWEDをセットしてメッセージをPUTします。 メッセージを論理メッセージに分割する場合、MQMF_MSG_IN_GROUPを設定し、最後の論理メッセージにはMQMF_LAST_MSG_IN_GROUPを設定します。 MQMF_LAST_MSG_IN_GROUPを設定すると、MQMF_MSG_IN_GROUPも自動的にONになります。 アプリケーションでセグメント分割をする場合は、MQMF_SEGMENTを設定し、最後のセグメントにはMQMF_LAST_SEGMENTを設定します。 MQMF_LAST_SEGMENTを設定すると、MQMF_SEGMENTも自動的にONになります。 MQMF_SEGMENTATION_ALLOWEDおよびMQMF_*GROUP、MQMF_*SEGMENTを複数設定する必要がある場合は、その算術ORで設定します。
[ OriginalLength ]
タイプ: MQLONG
サイズ: 4バイト
初期値:MQOL_UNDEFINED(-1)
入出力: 入出力
レポート・メッセージの場合、レポートの対象である元のメッセージの長さを示します。 MQMD.MsgTypeがMQMT_REPORTの場合、アプリケーションから指定することが可能です。 セグメントでレポート・メッセージ以外の場合は、そのセグメント(アプリケーション・データ)の長さがキューマネージャーによって設定されます。 それ以外の場合は初期値MQOL_UNDEFINED(-1)がセットされます。
MQMD V2の各フィールドの概要についてのご説明は以上です。
メッセージのセグメント化
それでは、「メッセージのセグメント化」についてご説明します。
「メッセージのセグメント化」には、「キューマネージャーによるセグメント化」と「アプリケーションによるセグメント化」の2種類の方法があります。 また、受信側にもセグメント化されたメッセージをキューマネージャーによって再組立てする方法と、アプリケーションによって再組立てする方法があります。 通常は「キューマネージャーによるセグメント化」を使用しますが、チャネルで文字コード変換を行う場合などは問題が発生する場合があります。 チャネルでマルチバイトの文字コードを含むメッセージをコード変換させる場合、セグメント単位でコード変換されますので、文字の境界を意識しなければ変換エラーまたは誤変換が発生します。 この場合は、アプリケーションによるセグメント化が必要になります。 受信側のアプリケーションでコード変換する場合には、キューマネージャーで再組立てさせる場合に一つの論理メッセージでGETできますので、MQGMO_CONVERTで変換することが可能です。
それでは、「メッセージのセグメント化」について実際に検証してみます。
キューマネージャーによるセグメント化
キューマネージャーのMAXMSGLと書き込むキューのMAXMSGLのうちの小さい設定値がセグメント分割に使用されます。 チャネルのMAXMSGLについては、キューマネージャーによるセグメント分割には関与しません。
※もしも、チャネルがMAXMSGLより大きなサイズのメッセージを転送しようとした場合、理由コードMQRC_MSG_TOO_BIG_FOR_CHANNEL(2218)で失敗します。
キューマネージャーにセグメント分割させる場合には、MQMD.MsgFlagsにMQMF_SEGMENTATION_ALLOWEDを指定します。 MQMD.GroupIdは指定しても構いませんが、MQGI_NONEを設定すればキューマネージャーが自動的にグループIDを採番します。 セグメント化されたメッセージには全て、同じグループIDが設定されます。 当然MQMDはVersion 2を指定(使用)する必要があります。
Ex. 4.1 キューマネージャーにセグメント化を実行させる
キューのMAXMSGLでセグメント分割させてみます。 テストを容易にするためにキューのMAXMSGLを100に設定します。
※キューマネージャーによるセグメント分割は正確にMAXMSGLの値では分割されない場合があります。 例えば、MQ9.0 for WindowsやMQ8.0 for HPNonStopで確認した結果ではMAXMSGLを超えない最大の8の倍数等で分割されます。
$ echo "alter ql('SampleQ') maxmsgl(100)" | runmqsc SampleQM
※WindowsのDOSプロンプトやHP NonStopのOSS環境ではダブルクォートは不要です。UNIX系のシェルでは必要な場合があります。
128バイト以上の任意のテキストファイルを用意します。
$ ls -l largemsg.txt
-rw-r--r-- 1 MQM.MANAGER MQM 315 Apr 25 17:34 largemsg.txt
$ cat largemsg.txt
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
MQMF_SEGMENTATION_ALLOWEDを指定してファイルのデータをPUTします。
$ mqpgf -qm SampleQM -q SampleQ -f largemsg.txt MQMF_SEGMENTATION_ALLOWED MQMD_VERSION_2
[18/05/09 15:12:05] 1: put from largemsg.txt
-f: ファイル内のメッセージをキューにPUT
MQMF_SEGMENTATION_ALLOWED: MQMD.MsgFlagsにMQMF_SEGMENTATION_ALLOWEDを設定
MQMD_VERSION_2: MQMD.VersionにMQMD_VERSION_2を設定
テスト結果4.1
$ mqpgf -qm SampleQM -q SampleQ -dpv -r
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205AF2892120002A02] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180509] PutTime[06120565] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205AF2892120002A03] MsgSeqNumber[1] Offset[0] MsgFlags[3] OriginalLength[96]
data length: 96
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 6566 6768 696A 6B6C 'WXYZabcdefghijkl'
00000030: 6D6E 6F70 7172 7374 7576 7178 797A 0A31 'mnopqrstuvqxyz.1'
00000040: 3233 3435 3637 3839 3041 4243 4445 4647 '234567890ABCDEFG'
00000050: 4849 4A4B 4C4D 4E4F 5051 5253 5455 5657 'HIJKLMNOPQRSTUVW'
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205AF2892120002A04] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180509] PutTime[06120565] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205AF2892120002A03] MsgSeqNumber[1] Offset[96] MsgFlags[3] OriginalLength[96]
data length: 96
00000000: 5859 5A61 6263 6465 6667 6869 6A6B 6C6D 'XYZabcdefghijklm'
00000010: 6E6F 7071 7273 7475 7671 7879 7A0A 3132 'nopqrstuvqxyz.12'
00000020: 3334 3536 3738 3930 4142 4344 4546 4748 '34567890ABCDEFGH'
00000030: 494A 4B4C 4D4E 4F50 5152 5354 5556 5758 'IJKLMNOPQRSTUVWX'
00000040: 595A 6162 6364 6566 6768 696A 6B6C 6D6E 'YZabcdefghijklmn'
00000050: 6F70 7172 7374 7576 7178 797A 0A31 3233 'opqrstuvqxyz.123'
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205AF2892120002A05] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180509] PutTime[06120565] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205AF2892120002A03] MsgSeqNumber[1] Offset[192] MsgFlags[3] OriginalLength[96]
data length: 96
00000000: 3435 3637 3839 3041 4243 4445 4647 4849 '4567890ABCDEFGHI'
00000010: 4A4B 4C4D 4E4F 5051 5253 5455 5657 5859 'JKLMNOPQRSTUVWXY'
00000020: 5A61 6263 6465 6667 6869 6A6B 6C6D 6E6F 'Zabcdefghijklmno'
00000030: 7071 7273 7475 7671 7879 7A0A 3132 3334 'pqrstuvqxyz.1234'
00000040: 3536 3738 3930 4142 4344 4546 4748 494A '567890ABCDEFGHIJ'
00000050: 4B4C 4D4E 4F50 5152 5354 5556 5758 595A 'KLMNOPQRSTUVWXYZ'
message number: 4
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205AF2892120002A06] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180509] PutTime[06120565] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205AF2892120002A03] MsgSeqNumber[1] Offset[288] MsgFlags[7] OriginalLength[27]
data length: 27
00000000: 6162 6364 6566 6768 696A 6B6C 6D6E 6F70 'abcdefghijklmnop'
00000010: 7172 7374 7576 7178 797A 0A 'qrstuvqxyz. '
no message available : SampleQ CompCd=02 ReasonCd=2033
100以下の8の倍数である96でセグメント分割されています。 GroupIdは自動採番され、全て同じ値です。 MsgSeqNumberも全て"1"が設定されています。 つまり、論理メッセージは1つです。 Offsetは、"0"から始まり分割されたサイズ(今回のテストでは96Byte)を加算した値が以降のメッセージに設定されています。 MsgFlagsは最後のセグメント以外は"3"で、最後のセグメントは"7"が設定されています。
"3"はMQMF_SEGMENTATION_ALLOWEDとMQMF_SEGMENTのORで、"7"はさらにMQMF_LAST_SEGMENTでORされた値です。
MQMF_SEGMENTATION_ALLOWED | 0x00000001 |
MQMF_SEGMENT | 0x00000002 |
MQMF_LAST_SEGMENT | 0x00000004 |
OriginalLengthにはセグメント分割されたメッセージサイズと同じ値が設定されています。
※OriginalLengthの値は、レポートメッセージが生成される場合に意味を持ちます。
レポートメッセージで設定されているOriginalLengthはレポートメッセージ自体の長さではなく、レポートの対象である元のメッセージの長さを示します。
テストが終わったら、キューの設定をもとに戻しておきます。
$ echo "alter ql('SampleQ') maxmsgl(4194304)" | runmqsc SampleQM
アプリケーションによるセグメント化
mqpgfは"-as"に続いてセグメントのサイズを指定することで、アプリケーション的にセグメント分割を行います。 具体的には、指定されたサイズでメッセージを分割し、分割したセグメントのMsgFlagsにMQMF_SEGMENT、最後のセグメントの場合はMQMF_LAST_SEGMENTを指定します。 MQPMO.OptionsにMQPMO_LOGICAL_ORDER(後述)が指定されていない場合は、GroupId、Offsetをアプリケーションで設定することが必要です。 mqpgfは引数にMQPMO_LOGICAL_ORDERが指定されていない場合、Offsetを設定しますが、GroupIdについては最初のセグメントに自動採番された値を後続のセグメントに使用することをしません。 GroupIdが相違すると、MQGET時にMQGMO_COMPLETE_MSG(後述)やMQGMO_ALL_SEGMENTS_AVAILABLE(後述)が使用できません。 メッセージの再組立てを可能にするには、mqpgfの引数にGroupIdを指定するか、MQPMO_LOGICAL_ORDERを指定します。 mqpgfは"-gi"でGroupIdを手動で指定した場合、全てのセグメントにそのGroupIdを設定します。 アプリケーションがMQPMO_LOGICAL_ORDERを指定した場合は、キューマネージャーがGroupId、MsgSeqNumberおよびOffsetに適切な値を自動的に設定します。 アプリケーションは、MsgFlagsにMQMF_SEGMENT、最後のセグメントの場合はMQMF_LAST_SEGMENTを指定することのみが必要です。 mqpgfもMQPMO_LOGICAL_ORDERが引数で与えられた場合は、MsgFlagsのみを設定します。
Ex. 4.2 アプリケーションでのセグメント化の実行
"-as"とMQPMO_LOGICAL_ORDERを指定してアプリケーション(mqpgf)でセグメント分割してみます。 入力メッセージには先程と同じファイルを使用します。 ここでは、MQPMO_SYNCPOINTを指定してセグメント化された一連のメッセージを一つのUOW(Unit Of Work)で処理(Commit/Backout)します。 mqpgfはMQPMO_SYNCPOINTを引数で指定すると、MQCMIT()を自動的に呼び出します。
※MQ for HP NonStopではMQPMO_SYNCPOINTがデフォルトですので、MQPMO_SYNCPOINTは指定する必要はありません。
$ mqpgf -qm SampleQM -q SampleQ -f largemsg.txt -as 100 MQMD_VERSION_2 MQPMO_LOGICAL_ORDER MQPMO_SYNCPOINT
[18/05/23 17:55:16] 1: put from: largemsg.txt
[18/05/23 17:55:16] 1: logical message: 1 length: 315 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.12
[18/05/23 17:55:16] 1: segment: 1 length: 100 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZa
[18/05/23 17:55:16] 1: segment: 2 length: 100 put message: bcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890A
[18/05/23 17:55:16] 1: segment: 3 length: 100 put message: BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl
[18/05/23 17:55:16] 1: segment: 4 length: 15 put message: mnopqrstuvqxyz.
MQCMIT success : CompCd=00 ReasonCd=00
-f: ファイル内のメッセージをキューにPUT
-as: 指定したサイズでメッセージをセグメントに分割
MQPMO_LOGICAL_ORDER: MQPMO.OptionsにMQPMO_LOGICAL_ORDERを設定
MQMD_VERSION_2: MQMD.VersionにMQMD_VERSION_2を設定
上の青字の部分が物理メッセージです。
テスト結果4.2
$ mqpgf -qm SampleQM -q SampleQ -dpv -r
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002A0D] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[08551656] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002A0E] MsgSeqNumber[1] Offset[0] MsgFlags[2] OriginalLength[100]
data length: 100
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 6566 6768 696A 6B6C 'WXYZabcdefghijkl'
00000030: 6D6E 6F70 7172 7374 7576 7178 797A 0A31 'mnopqrstuvqxyz.1'
00000040: 3233 3435 3637 3839 3041 4243 4445 4647 '234567890ABCDEFG'
00000050: 4849 4A4B 4C4D 4E4F 5051 5253 5455 5657 'HIJKLMNOPQRSTUVW'
00000060: 5859 5A61 'XYZa '
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002A0F] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[08551657] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002A0E] MsgSeqNumber[1] Offset[100] MsgFlags[2] OriginalLength[100]
data length: 100
00000000: 6263 6465 6667 6869 6A6B 6C6D 6E6F 7071 'bcdefghijklmnopq'
00000010: 7273 7475 7671 7879 7A0A 3132 3334 3536 'rstuvqxyz.123456'
00000020: 3738 3930 4142 4344 4546 4748 494A 4B4C '7890ABCDEFGHIJKL'
00000030: 4D4E 4F50 5152 5354 5556 5758 595A 6162 'MNOPQRSTUVWXYZab'
00000040: 6364 6566 6768 696A 6B6C 6D6E 6F70 7172 'cdefghijklmnopqr'
00000050: 7374 7576 7178 797A 0A31 3233 3435 3637 'stuvqxyz.1234567'
00000060: 3839 3041 '890A '
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002A10] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[08551657] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002A0E] MsgSeqNumber[1] Offset[200] MsgFlags[2] OriginalLength[100]
data length: 100
00000000: 4243 4445 4647 4849 4A4B 4C4D 4E4F 5051 'BCDEFGHIJKLMNOPQ'
00000010: 5253 5455 5657 5859 5A61 6263 6465 6667 'RSTUVWXYZabcdefg'
00000020: 6869 6A6B 6C6D 6E6F 7071 7273 7475 7671 'hijklmnopqrstuvq'
00000030: 7879 7A0A 3132 3334 3536 3738 3930 4142 'xyz.1234567890AB'
00000040: 4344 4546 4748 494A 4B4C 4D4E 4F50 5152 'CDEFGHIJKLMNOPQR'
00000050: 5354 5556 5758 595A 6162 6364 6566 6768 'STUVWXYZabcdefgh'
00000060: 696A 6B6C 'ijkl '
message number: 4
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002A11] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[08551657] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002A0E] MsgSeqNumber[1] Offset[300] MsgFlags[6] OriginalLength[15]
data length: 15
00000000: 6D6E 6F70 7172 7374 7576 7178 797A 0A 'mnopqrstuvqxyz. '
no message available : SampleQ CompCd=02 ReasonCd=2033
指定したセグメントサイズ(100)で分割されています。(アプリケーション) GroupIdは自動採番され、全て同じ値が設定されています。(キューマネージャー) MsgSeqNumberも全て"1"が設定されています。(キューマネージャー) Offsetは、"0"から始まり分割されたサイズを加算した値が以降のメッセージに設定されています。(キューマネージャー) MsgFlagsは最後のセグメント以外は"2"で、最後のセグメントは"6"が設定されています。
"2"はMQMF_SEGMENTで、"6"はMQMF_SEGMENTとMQMF_LAST_SEGMENTでORした値です。 アプリケーションで分割したので、今回はMQMF_SEGMENTATION_ALLOWEDは設定されていません。
MQMF_SEGMENTATION_ALLOWED | 0x00000001 |
MQMF_SEGMENT | 0x00000002 |
MQMF_LAST_SEGMENT | 0x00000004 |
ここで、mqpgfは最後のセグメントにはMQMF_LAST_SEGMENTのみを指定しています。 MQMF_LAST_SEGMENTが指定された場合、キューマネージャーによって自動的にMQMF_SEGMENTがオン(OR)されてメッセージが送信されます。(アプリケーション+キューマネージャー) OriginalLengthにはセグメント分割されたメッセージサイズと同じ値が設定されています。(キューマネージャー)
キューマネージャーによる論理メッセージの再組立て
キューマネージャーにセグメント化されたメッセージを再組立てさせるには、MQGMO.OptionsにMQGMO_COMPLETE_MSGを設定してMQGET()を呼び出します。
Ex. 4.3 キューマネージャーにセグメントを組立てさせる
アプリケーションでセグメント化したメッセージをキューマネージャーによって再組立てさせてみます。
キューが空であることを確認。
$ mqpcf ques -qm SampleQM -q SampleQ CURDEPTH -t
[18/05/09 17:59:25] 1: QUEUE(SampleQ) TYPE(QUEUE) CURDEPTH(0)
アプリケーションで100バイト毎にセグメント分割したメッセージをPUTしておきます。
$ mqpgf -qm SampleQM -q SampleQ -f largemsg.txt -as 100 MQMD_VERSION_2 MQPMO_LOGICAL_ORDER
[18/05/23 17:57:48] 1: put from: largemsg.txt
[18/05/23 17:57:48] 1: logical message: 1 length: 315 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.12
[18/05/23 17:57:48] 1: segment: 1 length: 100 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZa
[18/05/23 17:57:48] 1: segment: 2 length: 100 put message: bcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890A
[18/05/23 17:57:48] 1: segment: 3 length: 100 put message: BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz.1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl
[18/05/23 17:57:48] 1: segment: 4 length: 15 put message: mnopqrstuvqxyz.
$ mqpcf ques -qm SampleQM -q SampleQ CURDEPTH -t
[18/05/09 17:59:54] 1: QUEUE(SampleQ) TYPE(QUEUE) CURDEPTH(4)
4件(CURDEPTH)にセグメント化されています。(青字部分)
MQGMO_COMPLETE_MSGを指定し、キューマネージャーにセグメント化されたメッセージを再組立てさせます。
テスト結果4.3
$ mqpgf -qm SampleQM -q SampleQ -dpv MQGMO_COMPLETE_MSG
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002B03] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[08574840] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002B04] MsgSeqNumber[1] Offset[0] MsgFlags[6] OriginalLength[315]
data length: 315
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 6566 6768 696A 6B6C 'WXYZabcdefghijkl'
00000030: 6D6E 6F70 7172 7374 7576 7178 797A 0A31 'mnopqrstuvqxyz.1'
00000040: 3233 3435 3637 3839 3041 4243 4445 4647 '234567890ABCDEFG'
00000050: 4849 4A4B 4C4D 4E4F 5051 5253 5455 5657 'HIJKLMNOPQRSTUVW'
00000060: 5859 5A61 6263 6465 6667 6869 6A6B 6C6D 'XYZabcdefghijklm'
00000070: 6E6F 7071 7273 7475 7671 7879 7A0A 3132 'nopqrstuvqxyz.12'
00000080: 3334 3536 3738 3930 4142 4344 4546 4748 '34567890ABCDEFGH'
00000090: 494A 4B4C 4D4E 4F50 5152 5354 5556 5758 'IJKLMNOPQRSTUVWX'
000000A0: 595A 6162 6364 6566 6768 696A 6B6C 6D6E 'YZabcdefghijklmn'
000000B0: 6F70 7172 7374 7576 7178 797A 0A31 3233 'opqrstuvqxyz.123'
000000C0: 3435 3637 3839 3041 4243 4445 4647 4849 '4567890ABCDEFGHI'
000000D0: 4A4B 4C4D 4E4F 5051 5253 5455 5657 5859 'JKLMNOPQRSTUVWXY'
000000E0: 5A61 6263 6465 6667 6869 6A6B 6C6D 6E6F 'Zabcdefghijklmno'
000000F0: 7071 7273 7475 7671 7879 7A0A 3132 3334 'pqrstuvqxyz.1234'
00000100: 3536 3738 3930 4142 4344 4546 4748 494A '567890ABCDEFGHIJ'
00000110: 4B4C 4D4E 4F50 5152 5354 5556 5758 595A 'KLMNOPQRSTUVWXYZ'
00000120: 6162 6364 6566 6768 696A 6B6C 6D6E 6F70 'abcdefghijklmnop'
00000130: 7172 7374 7576 7178 797A 0A 'qrstuvqxyz. '
再組立てされて1件の物理メッセージとしてGETされています。
$ mqpcf ques -qm SampleQM -q SampleQ CURDEPTH -t
[18/05/09 18:04:18] 1: QUEUE(SampleQ) TYPE(QUEUE) CURDEPTH(0)
4件のセグメントが1回のGETで全て削除されています。
アプリケーションによる論理メッセージの再組立て
アプリケーションで論理メッセージを組み立てる場合の推奨のMQGMOオプションは下記です。
MQGMO_SYNCPOINT、MQGMO_LOGICAL_ORDER、MQGMO_ALL_SEGMENTS_AVAILABLE
MQGMO_SYNCPOINTを指定してセグメント化された一連のメッセージを一つのUOW(Unit Of Work)で処理(Commit/Backout)します。
mqpgfはMQGMO_SYNCPOINTを引数で指定すると、MQCMIT()を自動的に呼び出します。
※MQ for HP NonStopではMQPMO_SYNCPOINTがデフォルトですので、MQPMO_SYNCPOINTは指定する必要はありません。
複数の経路が存在する場合やアプリケーションのスレッド化などの影響で、セグメントが順序通りに到着しないケースを考慮し、MQGMO_LOGICAL_ORDERを指定して必ずセグメントが順序どおりに取り出されるようにします。
さらに、MQGMO_ALL_SEGMENTS_AVAILABLEを指定して、全てのセグメントが受信キューに到着するまでMQGET()処理を実施しないように指定します。
Ex. 4.4 セグメントの論理順序での読み込み
MQGMO_LOGICAL_ORDERとMQGMO_ALL_SEGMENTS_AVAILABLEの挙動が分かるように、ここでは、手動で一つ々々のセグメント・メッセージをキューに作成してみます。
3つにセグメント分割された24バイトの論理メッセージを想定します。 分割されたセグメントのサイズは8バイトです。 同じ論理メッセージですので、GroupIdとMsgSeqNumberは全てのセグメントで同じです。
最後(3番目)のセグメントを最初にキューにPUTします。 MQMF_LAST_SEGMENTを指定します。 Offsetは16です。
$ mqpgf -qm SampleQM -q SampleQ -m Segment3 -gi GID -ms 1 -of 16 MQMD_VERSION_2 MQMF_LAST_SEGMENT
[18/05/23 18:01:58] 1: message length: 8 put message: Segment3
続いて、先頭のセグメントをキューにPUTします。 MQMF_SEGMENTを指定します。 Offsetは0です。
$ mqpgf -qm SampleQM -q SampleQ -m Segment1 -gi GID -ms 1 -of 0 MQMD_VERSION_2 MQMF_SEGMENT
[18/05/23 18:02:12] 1: message length: 8 put message: Segment1
*オプションの説明
MQMD_VERSION_2: MQMD.VersionにMQMD_VERSION_2を設定します。
-gi: MQMD.GroupIdに指定された値を設定します。
-ms: MQMD.MsgSeqNumberに指定された値を設定します。
-of: MQMD.Offsetに指定された値を設定します。
MQMF_SEGMENT: MQMD.MsgFlagsにMQMF_SEGMENTを設定します。
MQMF_LAST_SEGMENT: MQMD.MsgFlagsにMQMF_LAST_SEGMENTを設定します。
キューのCURDEPTHは当然2件です。
$ mqpcf ques -qm SampleQM -q SampleQ CURDEPTH
1: QUEUE(SampleQ) TYPE(QUEUE) CURDEPTH(2)
ここで、MQGMO_LOGICAL_ORDER、MQGMO_ALL_SEGMENTS_AVAILABLEを指定してGETしてみます。 MQGMO_LOGICAL_ORDERを指定する場合は、MQGMO_VERSION_2以上とMQMD_VERSION_2の指定が必要です。 mqpgfで"-dp"を指定する場合は、MQMD_VERSION_2がデフォルトで使用されます。
$ mqpgf -qm SampleQM -q SampleQ -dp -r MQGMO_VERSION_2 MQGMO_LOGICAL_ORDER MQGMO_ALL_SEGMENTS_AVAILABLE
no message available : SampleQ CompCd=02 ReasonCd=2033
$ mqrc 2033
2033 0x000007f1 MQRC_NO_MSG_AVAILABLE
全てのセグメントが受信キューに到着していないので、MQGET()からはMQRC_NO_MSG_AVAILABLEが返却され、メッセージは一つもGETされません。
残りの2番目のセグメントをPUTします。 MQMF_SEGMENTを指定します。 Offsetは8です。
$ mqpgf -qm SampleQM -q SampleQ -m Segment2 -gi GID -ms 1 -of 8 MQMD_VERSION_2 MQMF_SEGMENT
[18/05/23 18:03:35] 1: message length: 8 put message: Segment2
念のためこの時点でキューの中のメッセージを、物理順序/FIFO(デフォルト)の順序でブラウズして確認します。
$ mqpgf -qm SampleQM -q SampleQ -br -r
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C09] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09015893] ApplOriginData[ ]
GroupId[0x474944000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[16] MsgFlags[6] OriginalLength[8]
data length: 8
00000000: 5365 676D 656E 7433 'Segment3 '
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C0B] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09021276] ApplOriginData[ ]
GroupId[0x474944000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[2] OriginalLength[8]
data length: 8
00000000: 5365 676D 656E 7431 'Segment1 '
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C11] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09033505] ApplOriginData[ ]
GroupId[0x474944000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[8] MsgFlags[2] OriginalLength[8]
data length: 8
00000000: 5365 676D 656E 7432 'Segment2 '
no message available : SampleQ CompCd=02 ReasonCd=2033
3番目、先頭、2番目のセグメントの順になっています。
MQGMO_LOGICAL_ORDER、MQGMO_ALL_SEGMENTS_AVAILABLEを指定して繰り返しGETしてみます。
テスト結果4.4
$ mqpgf -qm SampleQM -q SampleQ -dp -r MQGMO_VERSION_2 MQGMO_LOGICAL_ORDER MQGMO_ALL_SEGMENTS_AVAILABLE MQGMO_SYNCPOINT
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C0B] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09021276] ApplOriginData[ ]
GroupId[0x474944000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[2] OriginalLength[8]
data length: 8
00000000: 5365 676D 656E 7431 'Segment1 '
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C11] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09033505] ApplOriginData[ ]
GroupId[0x474944000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[8] MsgFlags[2] OriginalLength[8]
data length: 8
00000000: 5365 676D 656E 7432 'Segment2 '
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C09] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09015893] ApplOriginData[ ]
GroupId[0x474944000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[16] MsgFlags[6] OriginalLength[8]
data length: 8
00000000: 5365 676D 656E 7433 'Segment3 '
no message available : SampleQ CompCd=02 ReasonCd=2033
MQCMIT success : CompCd=00 ReasonCd=00
*オプションの説明
-dp: メッセージをGETし、"-br"と同様の形式でメッセージをダンプします。
-r: キュー上のメッセージを繰り返しGET
MQGMO_VERSION_2: MQGMO.VersionにMQGMO_VERSION_2を設定
MQGMO_LOGICAL_ORDER: MQGMO.OptionsにMQGMO_LOGICAL_ORDERを設定
MQGMO_ALL_SEGMENTS_AVAILABLE: MQGMO.OptionsにMQGMO_ALL_SEGMENTS_AVAILABLEを設定
MQGMO_SYNCPOINT: MQGMO.OptionsにMQGMO_SYNCPOINTを設定
セグメントがOffsetの値に従い、正しく論理順序でGETされています。
※mqpgfは実際の論理メッセージの再組立てまでは行いません。 意図した順序でセグメントが受信できることまでを確認できます。
論理メッセージのグループ化
論理メッセージのグループ化
論理メッセージのグループ化は、メッセージのセグメント化の様にキューマネージャーで自動的に行うことはできません。 mqpgfは"-dl"に続いて、指定されたメッセージまたはファイルからグループ化された論理メッセージを作成する為に使用するデリミタを指定できます。 具体的には、デリミタを除いた論理メッセージに分割し、分割した論理メッセージのMsgFlagsにMQMF_MSG_IN_GROUP、最後の論理メッセージの場合はMQMF_LAST_MSG_IN_GROUPを指定します。 MQPMO_LOGICAL_ORDERは、論理メッセージのグループ化の場合にも機能します。 MQPMO.OptionsにMQPMO_LOGICAL_ORDERが指定されていない場合は、GroupId、MsgSeqNumberをアプリケーションで設定することが必要です。 引数にMQPMO_LOGICAL_ORDERが指定されず、かつGroupIdも指定されていない場合、論理メッセージ毎に別々のGroupIdが採番され、MsgSeqNumberもインクリメントされません。 アプリケーションがMQPMO_LOGICAL_ORDERを指定した場合は、キューマネージャーがGroupId、MsgSeqNumber(およびOffset)に適切な値を自動的に設定します。 その場合は、アプリケーションは、MsgFlagsにMQMF_MSG_IN_GROUP、最後の論理メッセージの場合はMQMF_LAST_MSG_IN_GROUPを指定することのみが必要です。 また、セグメントの再組立てはMQGMO_COMPLETE_MSGを指定することでキューマネージャーに実行させることができましたが、論理メッセージからのメッセージの再組立ては、キューマネージャーに実行させることはできません。
Ex. 4.5 グループ化された論理メッセージの生成
下記のような複数行の任意のテキストファイルを用意します。
$ cat largemsg2.txt
1234567890
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
この複数行のファイル(改行はLF:0x0a)を0x0a(LF)をデリミタに指定して、行ごとに論理メッセージに分割してメッセージをPUTしてみます。
MQPMO_LOGICAL_ORDERも指定します。
※Windowsの場合は通常改行は0x0d0a(CRLF)ですので、"-dl 0x0d0a"の様に指定してください。
Unix系のOSやHP NonStopのOSS環境では改行は0x0a(LF)です。
$ mqpgf -qm SampleQM -q SampleQ -f largemsg2.txt -dl 0x0a MQMD_VERSION_2 MQPMO_LOGICAL_ORDER MQPMO_SYNCPOINT
[18/05/23 18:05:31] 1: put from: largemsg2.txt
[18/05/23 18:05:31] 1: logical message: 1 length: 10 put message: 1234567890
[18/05/23 18:05:31] 1: logical message: 2 length: 62 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
[18/05/23 18:05:31] 1: logical message: 3 length: 62 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
[18/05/23 18:05:31] 1: logical message: 4 length: 36 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
[18/05/23 18:05:31] 1: logical message: 5 length: 62 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
MQCMIT success : CompCd=00 ReasonCd=00
*オプションの説明
-f: ファイル内のメッセージをキューにPUT
-dl: 論理メッセージに分割する為のデリミタを文字列もしくは16進表記で指定
MQGMO_VERSION_2: MQGMO.VersionにMQGMO_VERSION_2を設定
MQPMO_LOGICAL_ORDER: MQPMO.OptionsにMQPMO_LOGICAL_ORDERを設定
MQPMO_SYNCPOINT: MQPMO.OptionsにMQGMO_SYNCPOINTを設定
青字の部分が物理メッセージです。
分割されたメッセージを確認してみます。 このケースでは論理メッセージ=物理メッセージです。
テスト結果4.5
$ mqpgf -qm SampleQM -q SampleQ -dp -r
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C18] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09053189] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002C19] MsgSeqNumber[1] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 10
00000000: 3132 3334 3536 3738 3930 '1234567890 '
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C1A] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09053190] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002C19] MsgSeqNumber[2] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 62
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 6566 6768 696A 6B6C 'WXYZabcdefghijkl'
00000030: 6D6E 6F70 7172 7374 7576 7178 797A 'mnopqrstuvqxyz '
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C1B] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09053190] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002C19] MsgSeqNumber[3] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 62
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 6566 6768 696A 6B6C 'WXYZabcdefghijkl'
00000030: 6D6E 6F70 7172 7374 7576 7178 797A 'mnopqrstuvqxyz '
message number: 4
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C1C] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09053190] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002C19] MsgSeqNumber[4] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 36
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 'WXYZ '
message number: 5
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B05070120002C1D] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180523] PutTime[09053190] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B05070120002C19] MsgSeqNumber[5] Offset[0] MsgFlags[24] OriginalLength[-1]
data length: 62
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 6566 6768 696A 6B6C 'WXYZabcdefghijkl'
00000030: 6D6E 6F70 7172 7374 7576 7178 797A 'mnopqrstuvqxyz '
no message available : SampleQ CompCd=02 ReasonCd=2033
行ごと(LF:0x0aごと)に論理メッセージに分割されています。(アプリケーション) GroupIdは自動採番され、全て同じ値です。(キューマネージャー) MsgSeqNumberも全て"1"から順にインクリメントされています。(キューマネージャー) MsgFlagsは最後のセグメント以外は"8"で、最後のセグメントは"24"が設定されています。
"3"はMQMF_MSG_IN_GROUPで、"24"はMQMF_MSG_IN_GROUPとMQMF_LAST_MSG_IN_GROUPをORした値です。
MQMF_MSG_IN_GROUP | 0x00000008 |
MQMF_LAST_MSG_IN_GROUP | 0x00000010 |
※MQMF_MSG_IN_GROUP | MQMF_LAST_MSG_IN_GROUP = 0x00000008 | 0x00000010 = 0x00000018(Hexadecimal) = 24(Decimal)
mqpgfは最後のセグメントにはMQMF_MSG_IN_GROUPのみを指定しています。 MQMF_LAST_MSG_IN_GROUPが指定された場合、キューマネージャーによって自動的にMQMF_MSG_IN_GROUPがオン(OR)されてメッセージが送信されます。(アプリケーション+キューマネージャー)
論理メッセージのグループ化と論理メッセージのセグメント化
論理メッセージのグループ化と論理メッセージのセグメント化を組み合わせることも可能です。
Ex. 4.6 グループ化とセグメント化を組み合わせる
先ほどと同じファイルを使用し、引数に"-as 40"を追加指定して40バイトを超える論理メッセージをアプリケーションでセグメント化してみます。
$ mqpgf -qm SampleQM -q SampleQ -f largemsg2.txt -dl 0x0a -as 40 MQMD_VERSION_2 MQPMO_LOGICAL_ORDER MQPMO_SYNCPOINT
[18/05/25 15:12:29] 1: put from: largemsg2.txt
[18/05/25 15:12:29] 1: logical message: 1 length: 10 put message: 1234567890
[18/05/25 15:12:29] 1: logical message: 2 length: 62 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
[18/05/25 15:12:29] 1: segment: 1 length: 40 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcd
[18/05/25 15:12:29] 1: segment: 2 length: 22 put message: efghijklmnopqrstuvqxyz
[18/05/25 15:12:29] 1: logical message: 3 length: 62 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
[18/05/25 15:12:29] 1: segment: 1 length: 40 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcd
[18/05/25 15:12:29] 1: segment: 2 length: 22 put message: efghijklmnopqrstuvqxyz
[18/05/25 15:12:29] 1: logical message: 4 length: 36 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
[18/05/25 15:12:29] 1: logical message: 5 length: 62 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz
[18/05/25 15:12:29] 1: segment: 1 length: 40 put message: 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcd
[18/05/25 15:12:29] 1: segment: 2 length: 22 put message: efghijklmnopqrstuvqxyz
MQCMIT success : CompCd=00 ReasonCd=00
*オプションの説明
-f: ファイル内のメッセージをキューにPUT
-dl: 論理メッセージに分割する為のデリミタを文字列もしくは16進表記で指定
-as: 指定したサイズでメッセージをセグメントに分割
MQMD_VERSION_2: MQMD.VersionにMQMD_VERSION_2を設定
MQPMO_LOGICAL_ORDER: MQPMO.OptionsにMQPMO_LOGICAL_ORDERを設定
MQPMO_SYNCPOINT: MQPMO.OptionsにMQGMO_SYNCPOINTを設定
青字の部分が物理メッセージです。
分割されたメッセージを確認してみます。
テスト結果4.6
$ mqpgf -qm SampleQM -q SampleQ -dp -r
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002302] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122950] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[1] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 10
00000000: 3132 3334 3536 3738 3930 '1234567890 '
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002304] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122951] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[2] Offset[0] MsgFlags[10] OriginalLength[40]
data length: 40
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 'WXYZabcd '
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002305] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122951] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[2] Offset[40] MsgFlags[14] OriginalLength[22]
data length: 22
00000000: 6566 6768 696A 6B6C 6D6E 6F70 7172 7374 'efghijklmnopqrst'
00000010: 7576 7178 797A 'uvqxyz '
message number: 4
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002306] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122951] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[3] Offset[0] MsgFlags[10] OriginalLength[40]
data length: 40
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 'WXYZabcd '
message number: 5
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002307] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122951] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[3] Offset[40] MsgFlags[14] OriginalLength[22]
data length: 22
00000000: 6566 6768 696A 6B6C 6D6E 6F70 7172 7374 'efghijklmnopqrst'
00000010: 7576 7178 797A 'uvqxyz '
message number: 6
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002308] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122952] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[4] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 36
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 'WXYZ '
message number: 7
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002309] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122952] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[5] Offset[0] MsgFlags[26] OriginalLength[40]
data length: 40
00000000: 3132 3334 3536 3738 3930 4142 4344 4546 '1234567890ABCDEF'
00000010: 4748 494A 4B4C 4D4E 4F50 5152 5354 5556 'GHIJKLMNOPQRSTUV'
00000020: 5758 595A 6162 6364 'WXYZabcd '
message number: 8
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F82000230A] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[06122952] ApplOriginData[ ]
GroupId[0x414D512053616D706C65514D202020205B07A8F820002303] MsgSeqNumber[5] Offset[40] MsgFlags[30] OriginalLength[22]
data length: 22
00000000: 6566 6768 696A 6B6C 6D6E 6F70 7172 7374 'efghijklmnopqrst'
00000010: 7576 7178 797A 'uvqxyz '
no message available : SampleQ CompCd=02 ReasonCd=2033
MQCMIT success : CompCd=00 ReasonCd=00
2、3、5番目の論理メッセージ(MsgSeqNumberが2, 3, 5)の物理メッセージにOffsetが設定され複数にセグメント分割されていることが確認できます。
グループ・メッセージの読み込み
MQGMO_COMPLETE_MSGを指定して、セグメントから論理メッセージの再組立てをキューマネージャーに実行させます。 MQGMO_LOGICAL_ORDERを指定すると、論理メッセージも順序通りに読み出せるようになります。 MQGMO_ALL_MSGS_AVAILABLEを指定して、グループ内のすべてのメッセージが到着してから初めて処理が開始されるようにします。 MQGMO_ALL_SEGMENTS_AVAILABLEも指定して、論理メッセージのすべてのセグメントが到着しない限り、セグメントの処理を開始しないようにします。
Ex. 4.7 グループ・メッセージの論理順序での読み込み
各オプションの挙動が分かりやすくなるように、ここでは、手動で一つづつ物理メッセージをキューに作成してみます。
下記の様に分割された2種類のグループメッセージを想定します。
グループ1 論理メッセージ1 セグメント1
グループ1 論理メッセージ1 セグメント2
グループ1 論理メッセージ2
グループ1 論理メッセージ3 セグメント1
グループ1 論理メッセージ3 セグメント2
グループ2 論理メッセージ1
グループ2 論理メッセージ2 セグメント1
グループ2 論理メッセージ2 セグメント2
これらの対応するコマンド・ラインは下記です。
mqpgf -qm SampleQM -q SampleQ -m Group1Logical1Segment1 -gi GroupId1 -ms 1 -of 0 MQMD_VERSION_2 MQMF_SEGMENT MQMF_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group1Logical1Segment2 -gi GroupId1 -ms 1 -of 22 MQMD_VERSION_2 MQMF_LAST_SEGMENT MQMF_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group1Logical2 -gi GroupId1 -ms 2 MQMD_VERSION_2 MQMF_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group1Logical3Segment1 -gi GroupId1 -ms 3 -of 0 MQMD_VERSION_2 MQMF_SEGMENT MQMF_LAST_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group1Logical3Segment2 -gi GroupId1 -ms 3 -of 22 MQMD_VERSION_2 MQMF_LAST_SEGMENT MQMF_LAST_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group2Logical1 -gi GroupId2 -ms 1 MQMD_VERSION_2 MQMF_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group2Logical2Segment1 -gi GroupId2 -ms 2 -of 0 MQMD_VERSION_2 MQMF_SEGMENT MQMF_LAST_MSG_IN_GROUP
mqpgf -qm SampleQM -q SampleQ -m Group2Logical2Segment2 -gi GroupId2 -ms 2 -of 22 MQMD_VERSION_2 MQMF_LAST_SEGMENT MQMF_LAST_MSG_IN_GROUP
*オプションの説明
-gi: MQMD.GroupIdに指定された値を設定します。
-ms: MQMD.MsgSeqNumberに指定された値を設定します。
-of: MQMD.Offsetに指定された値を設定します。
MQMD_VERSION_2: MQMD.VersionにMQMD_VERSION_2を設定します。
MQMF_SEGMENT: MQMD.MsgFlagsにMQMF_SEGMENTを設定します。
MQMF_MSG_IN_GROUP: MQMD.MsgFlagsにMQMF_MSG_IN_GROUPを設定します。
MQMF_LAST_SEGMENT: MQMD.MsgFlagsにMQMF_LAST_SEGMENTを設定します。
MQMF_LAST_MSG_IN_GROUP: MQMD.MsgFlagsにMQMF_LAST_MSG_IN_GROUPを設定します。
まず、別のターミナル/コマンド・プロンプトで下記引数で受信の為のmqpgfを起動しておきます。
$ mqpgf -qm SampleQM -q SampleQ -dp -r MQMD_VERSION_2 MQGMO_VERSION_2 MQGMO_COMPLETE_MSG MQGMO_LOGICAL_ORDER MQGMO_ALL_MSGS_AVAILABLE MQGMO_ALL_SEGMENTS_AVAILABLE MQGMO_WAIT MQWI_UNLIMITED MQGMO_NO_SYNCPOINT
*オプションの説明
MQMD_VERSION_2: MQMD.VersionにMQMD_VERSION_2を設定します。
MQGMO_VERSION_2: MQGMO.VersionにMQGMO_VERSION_2を設定します。
MQGMO_COMPLETE_MSG: MQGMO.OptionsにMQGMO_COMPLETE_MSGを設定します。
MQGMO_LOGICAL_ORDER: MQGMO.OptionsにMQGMO_LOGICAL_ORDERを設定します。
MQGMO_ALL_MSGS_AVAILABLE: MQGMO.OptionsにMQGMO_ALL_MSGS_AVAILABLEを設定します。
MQGMO_ALL_SEGMENTS_AVAILABLE: MQGMO.OptionsにMQGMO_ALL_SEGMENTS_AVAILABLEを設定します。
MQGMO_WAIT: MQGMO.OptionsにMQGMO_WAITを設定します。
MQWI_UNLIMITED: MQGMO.WaitIntervalにMQWI_UNLIMITEDを設定します。
MQGMO_NO_SYNCPOINT: MQGMO.OptionsにMQGMO_NO_SYNCPOINTを設定します。
MQGMO_WAITとMQWI_UNLIMITEDの指定によって、グループのメッセージが全てキューに到着するまで、無期限で待ちます。 すべて到着した時点でそれぞれのグループのメッセージの処理が開始されるはずです。 さらに"-r"オプションの指定により複数のグループでそれを繰り返します。
それでは、ランダムな順序でメッセージをPUTしていきます。
$ mqpgf -qm SampleQM -q SampleQ -m Group2Logical2Segment2 -gi GroupId2 -ms 2 -of 22 MQMD_VERSION_2 MQMF_LAST_SEGMENT MQMF_LAST_MSG_IN_GROUP
[18/05/25 16:45:38] 1: message length: 22 put message : Group2Logical2Segment2
$ mqpgf -qm SampleQM -q SampleQ -m Group1Logical3Segment2 -gi GroupId1 -ms 3 -of 22 MQMD_VERSION_2 MQMF_LAST_SEGMENT MQMF_LAST_MSG_IN_GROUP
[18/05/25 16:45:44] 1: message length: 22 put message : Group1Logical3Segment2
$ mqpgf -qm SampleQM -q SampleQ -m Group2Logical2Segment1 -gi GroupId2 -ms 2 -of 0 MQMD_VERSION_2 MQMF_SEGMENT MQMF_LAST_MSG_IN_GROUP
[18/05/25 16:45:49] 1: message length: 22 put message : Group2Logical2Segment1
$ mqpgf -qm SampleQM -q SampleQ -m Group1Logical3Segment1 -gi GroupId1 -ms 3 -of 0 MQMD_VERSION_2 MQMF_SEGMENT MQMF_LAST_MSG_IN_GROUP
[18/05/25 16:45:55] 1: message length: 22 put message : Group1Logical3Segment1
$ mqpgf -qm SampleQM -q SampleQ -m Group1Logical2 -gi GroupId1 -ms 2 MQMD_VERSION_2 MQMF_MSG_IN_GROUP
[18/05/25 16:46:01] 1: message length: 14 put message : Group1Logical2
$ mqpgf -qm SampleQM -q SampleQ -m Group1Logical1Segment2 -gi GroupId1 -ms 1 -of 22 MQMD_VERSION_2 MQMF_LAST_SEGMENT MQMF_MSG_IN_GROUP
[18/05/25 16:46:06] 1: message length: 22 put message : Group1Logical1Segment2
$ mqpgf -qm SampleQM -q SampleQ -m Group2Logical1 -gi GroupId2 -ms 1 MQMD_VERSION_2 MQMF_MSG_IN_GROUP
[18/05/25 16:46:11] 1: message length: 14 put message : Group2Logical1
この時点で、グループ2のメッセージを全て書き込んだので、別ターミナルでMQGET()待機していたmqpgfがメッセージを処理し、それを表示させたはずです。
テスト結果4.7.1
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002F0C] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[08070964] ApplOriginData[ ]
GroupId[0x47726F757049643200000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 14
00000000: 4772 6F75 7032 4C6F 6769 6361 6C31 'Group2Logical1 '
message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002F04] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[08065027] ApplOriginData[ ]
GroupId[0x47726F757049643200000000000000000000000000000000] MsgSeqNumber[2] Offset[0] MsgFlags[30] OriginalLength[44]
data length: 44
00000000: 4772 6F75 7032 4C6F 6769 6361 6C32 5365 'Group2Logical2Se'
00000010: 676D 656E 7431 4772 6F75 7032 4C6F 6769 'gment1Group2Logi'
00000020: 6361 6C32 5365 676D 656E 7432 'cal2Segment2 '
論理メッセージ順にGETされ、分割されたセグメントが一つの論理メッセージになっていることが確認できます。
最後にグループ1のメッセージの残りの1件を書き込みます。
$ mqpgf -qm SampleQM -q SampleQ -m Group1Logical1Segment1 -gi GroupId1 -ms 1 -of 0 MQMD_VERSION_2 MQMF_SEGMENT MQMF_MSG_IN_GROUP
[18/05/25 16:46:16] 1: message length: 22 put message : Group1Logical1Segment1
この時点で、グループ1のメッセージも全て書き込んだので、別ターミナルでMQGET()待機していたmqpgfがメッセージを処理し、それが表示されます。
テスト結果4.7.2
message number: 3
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002F0E] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[08074051] ApplOriginData[ ]
GroupId[0x47726F757049643100000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[14] OriginalLength[44]
data length: 44
00000000: 4772 6F75 7031 4C6F 6769 6361 6C31 5365 'Group1Logical1Se'
00000010: 676D 656E 7431 4772 6F75 7031 4C6F 6769 'gment1Group1Logi'
00000020: 6361 6C31 5365 676D 656E 7432 'cal1Segment2 '
message number: 4
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002F08] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[08065979] ApplOriginData[ ]
GroupId[0x47726F757049643100000000000000000000000000000000] MsgSeqNumber[2] Offset[0] MsgFlags[8] OriginalLength[-1]
data length: 14
00000000: 4772 6F75 7031 4C6F 6769 6361 6C32 'Group1Logical2 '
message number: 5
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[943] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205B07A8F820002F06] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180525] PutTime[08065488] ApplOriginData[ ]
GroupId[0x47726F757049643100000000000000000000000000000000] MsgSeqNumber[3] Offset[0] MsgFlags[30] OriginalLength[44]
data length: 44
00000000: 4772 6F75 7031 4C6F 6769 6361 6C33 5365 'Group1Logical3Se'
00000010: 676D 656E 7431 4772 6F75 7031 4C6F 6769 'gment1Group1Logi'
00000020: 6361 6C33 5365 676D 656E 7432 'cal3Segment2 '
※グループ1のメッセージについても、論理メッセージ順にGETされ、分割されたセグメントが一つの論理メッセージになっていることが確認できます。 この例では、1つのファイルのデータを分割してグループ化した論理メッセージを作成しましたが、mqpgfはそれらを読み取った時に一つのメッセージまたはファイルに再組立てはしません。 意図した順序で論理メッセージが受信できることが確認できるのみです。
次回も、引き続きMQMD Version 2で追加されたフィールドについてのご説明をします。