目次


WebSphere MQが提供するデータ変換機能 概説

第9章 メッセージ本体の構造の変換

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: WebSphere MQが提供するデータ変換機能 概説

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:WebSphere MQが提供するデータ変換機能 概説

このシリーズの続きに乞うご期待。

前章までは文字コードや数値の変換処理によるメッセージの変換について説明してきましたが、本章ではメッセージ本体のデータ構造を全般的に変換することができる、あるいは必然性に基づいてデータ構造が全般的に変換されることがあるというお話しをしたいと思います。

メッセージの長さが大幅に増加することがあるため、キューやチャネルに定義されている最大メッセージ長に近いサイズのメッセージを取り扱うときは注意が必要です。

RFH2形式の基礎

まず、本章の中で繰り返し出てくるRFH2(Rules and Formatting Header 2)形式について簡単に説明します。

これまでに何度か説明してきたとおり、WebSphere MQのメッセージ・プロパティーはバージョン7から新たに追加でサポートされましたが、その前のバージョンにおいては、各メッセージは

  • メッセージ記述子(MQMD)
  • メッセージ本体

の2つの部分のみから構成され、MQMDに定義されていない属性は全てメッセージ本体に含めるのが唯一の方法でした。これを実現するための標準的なデータ形式としてWebSphere MQではRFH2形式を定義し、その定義に従ってMQMDに含めることのできないメッセージ本体の先頭部分として保管し、本来メッセージ・データとして扱われるべき部分をRFH2に続くデータとしてメッセージ本体に含めることができるようにしたのです。

この形式のときにMQMD内のFormatに設定される値は表 3の中の「MQHRF2」となります。(アルファベットの順序に注意してください。途中が「RFH」ではなくて「HRF」になっています。間違えないように。)
このFormat名にしておけば、要求に応じてMQが標準でデータ変換を実行してくれます。これも前の章で何度か説明したとおりです。

ではここでも例を1つ示しておきましょう。

最初の128バイト(offset 0 - 127)がRFH2データでその中にmcd.Msd, mcd.Set, mcd.Type, mcd.Fmtの4つの情報を含み、後続の129バイト目(offset 128)以降が元々メッセージ本体として送りたいデータとなります。

図11. RFH2形式ファイルの例
図11. RFH2形式ファイルの例
図11. RFH2形式ファイルの例

RFH2形式を使用しているアプリケーション・プログラムは多数存在します。いくつかリスト・アップしてみます。

  • WebSphere Message Brokerに渡すメッセージで、処理で使用するメッセージ・セットをMQメッセージの一部として含めたい場合。
  • JAVAメッセージ・サービス(JMS)で送受信するメッセージにおいて、MQMDに含めることのできないプロパティー情報をMQメッセージの一部として含めたい場合。
  • WebSphere MQにおいてパブリッシュ/サブスクライブの処理を実行する際のメッセージ。
  • WebSphere MQバージョン7から送られたプロパティー付きのメッセージを、メッセージ・プロパティーがサポートされないバージョン6またはそれ以前のバージョンのキューマネージャーに転送する場合。

もちろんユーザー・プログラムがこの形式を使用することは何ら問題ありませんし、本トピックで説明しているMQのデータ変換機能を活用したい場合にはお薦めの形式となります。

メッセージ・プロパティー付きのメッセージからRFH2形式へ変換

アプリケーション・プログラムがMQGETを呼び出してメッセージをキューから受信する際に、3種類のメッセージ・プロパティーの受け取り形式があることを「MQメッセージ・プロパティーの受信における変換処理で」説明しましたが、この中の1つである

  • メッセージ本体の先頭部分としてRFH2形式で取得する。(MQGMO_PROPERTIES_FORCE_MQRFH2)を選択した場合はRFH2形式のデータの分だけメッセージ本体の長さが長くなることになります
図12. メッセージ・プロパティー付きのメッセージからRFH2形式へ変換
図12. メッセージ・プロパティー付きのメッセージからRFH2形式へ変換
図12. メッセージ・プロパティー付きのメッセージからRFH2形式へ変換

例として次の属性を持つメッセージをキューにMQPUTします。

  • Formatは「MQSTR」
  • メッセージ本体の長さは12バイト
  • プロパティーは24バイトのstringと64ビット整数の2つ
図13. プロパティー付きのメッセージの
図13. プロパティー付きのメッセージの
図13. プロパティー付きのメッセージの

このメッセージをMQGMO_PROPERTIES_FORCE_MQRFH2オプションを指定してRFH形式でMQGETした場合のデータを示します。

  • Formatは「MQHRF2」に変更される
  • 元のEncoding, CodedCharSetId, FormatはRFH2の中にセットされる
  • メッセージ本体の長さは180バイトに増加
  • プロパティーの文字列の値はUnicode(UTF-8)で返されている。
図14. プロパティー付きのメッセージをRFH2形式でMQGETした例
図14. プロパティー付きのメッセージをRFH2形式でMQGETした例
図14. プロパティー付きのメッセージをRFH2形式でMQGETした例

RFH2形式のデータからメッセージ・プロパティー付きのデータへ変換

前節とは逆に、こんどはMQGETでRFH2形式のメッセージをメッセージ・プロパティー付きで受信してみましょう。

MQGETのオプションに

  • 各メッセージ・プロパティーをメッセージ本体とは別に取得する。(MQGMO_PROPERTIES_IN_HANDLE)

をセットしてメッセージを取り出します。

前節の結果とは逆に、RFH2内に含まれていたデータがメッセージ・プロパティーとして別枠で取り出されることになります。

図15. RFH2形式のデータからメッセージ・プロパティー付きのデータへ変換
図15. RFH2形式のデータからメッセージ・プロパティー付きのデータへ変換
図15. RFH2形式のデータからメッセージ・プロパティー付きのデータへ変換

例として、「図11 RFH2形式ファイルの例」で示したファイルをMQGETした際の結果を示してみます。次のようになります。

  • FormatはRFH2内にあった元の「MQSTR」に変更される
  • メッセージ本体の長さは元々のメッセージ本体のみの46バイトに減少
図16. RFH2形式のメッセージをプロパティー付きの形式でMQGETした例
図16. RFH2形式のメッセージをプロパティー付きの形式でMQGETした例
図16. RFH2形式のメッセージをプロパティー付きの形式でMQGETした例

グループ化メッセージまたはセグメント化メッセージにおける構造の変換

本章では、メッセージ本体のデータ構造が変わる例として、ここまでメッセージ・プロパティーとRFH2形式相互間の例を示してみましたが、これと似た観点でグループ化あるいはセグメント化されたメッセージの内容がメッセージ記述子(MQMD)のバージョンによって変動する場合があります。

メッセージ記述子(MQMD)のバージョンによる違い

「図 2 MQMD内に含まれる情報」に示したMQMDの例をいまいちど見てみましょう。
最初の4バイトに識別子(ID, eye catcher)である「MD 」があり、その次の4バイト(offset 4-7)にこの構造体のバージョン番号が保管されています。この値は、MQMDに含めるデータが将来増えたときにバージョンの値を増やすことにより上位互換性を維持できるよう考慮されています。

MQMD以外の多くの構造体でも同様の手法をとっています。

(再掲)図2. MQMD内に含まれる情報
(再掲)図2. MQMD内に含まれる情報
(再掲)図2. MQMD内に含まれる情報

このMQMDにおけるバージョンは5-8バイト目(offset 4-7)に 02000000と示されているとおり、little endianで2となっています。もしこの値が1(01000000)になっていれば、MQMDのデータ長は上記364バイトより40バイト短い、先頭からApplOriginData までの324バイトとなります。

将来新しい属性値がMQMDに付加されたときは、バージョンの値が3またはそれ以上となり、既存データの位置はそのままで後続のデータが新たに追加されることになるはずです。

また、この構造体をよく見て考察すると、おそらく初期バージョンのWebSphere MQ(旧名MQSeries)ではメッセージのグループ化やセグメント化はサポートされていなかったのではないかと推測することができます。

メッセージ記述子(MQMD)のバージョンの変更

グループ化またはセグメント化されたメッセージにおいては、MQMDバージョン2の部分のデータが必須となりますが、MQGETの時に渡すMQMDのバージョンを1とした場合、受信するメッセージの内容はどうなるか見てみましょう。

本章をここまで読んでこられた方なら答えは容易に想像がつくと思います。メッセージ本体の先頭の部分にMQMDバージョン2の部分が構造体MQMDEとしてセットされ、後続の部分に元のデータがセットされることになります。

図17. メッセージ記述子(MQMD)のバージョンの変更
図17. メッセージ記述子(MQMD)のバージョンの変更
図17. メッセージ記述子(MQMD)のバージョンの変更
  • Formatは「MQHMDE」に変更される。
  • 元のEncoding, CodedCharSetId, FormatはMQMDEの中にセットされる。
  • メッセージ本体の先頭72バイトにMDEの構造体がセットされている。
    この分だけメッセージが長くなっている。
図18. グループ化メッセージをMQMDバージョン1でMQGETした例
図18. グループ化メッセージをMQMDバージョン1でMQGETした例
図18. グループ化メッセージをMQMDバージョン1でMQGETした例

通常のアプリケーション・プログラムの作成においては、MQPUT, MQPUT1, MQGETでパラメーターとして渡すMQMDは、最新バージョンである2にしておくことをお薦めします。WebSphere MQが提供しているヘッダー・ファイルのデフォルトの値を使用するようプログラミングされている場合は、バージョンは2になっています。

RFH2、DLHなどの構造体に含まれる属性情報

構造体の中に含まれるデータ変換関連の情報

本章で記述したとおり、メッセージ本体の先頭部分にRFH2、DLH、MDEなどのデータが含まれる場合、その内部にはデータ変換に関係する

  • Encoding
  • CodedCharSetId
  • Format

の3つのデータが含まれています。
また、RFH2、DLH、MDEと同様、第2章に記述されている「表3 WebSphere MQにあらかじめ定義されているフォーマットの値」に対応するその他の構造体の多くにおいても、上記3つのフィールドが含まれています。

これらのフィールドを使用して、メッセージ本体に含まれる構造体の後に続くデータの属性を保管することができるようになっています。

メッセージの構造とその中に含まれる数値データや文字データを正しく認識するためには、これらの値を正しく把握することが重要となります。

実例をいくつか示します。

RFH2 + (後続のデータ)

図19. RFH2 + 後続のデータ
図19. RFH2 + 後続のデータ
図19. RFH2 + 後続のデータ

本章の「図11 RFH2形式ファイルの例」がこのパターンのデータに該当します。

DLH + (後続のデータ)

図20. DLH + 後続のデータ
図20. DLH + 後続のデータ
図20. DLH + 後続のデータ

第4章の「図5 文字列と数値データを含むメッセージの例 (変換なし)」と「図6 文字列と数値データを含むメッセージの変換例」がこのパターンのデータに該当します。

MDE + (後続のデータ)

図21. MDE + 後続のデータ
図21. MDE + 後続のデータ
図21. MDE + 後続のデータ

本章の「図18 グループ化メッセージをMQMDバージョン1でMQGETした例」がこのパターンのデータに該当します。

少し複雑なサンプルとして、メッセージ本体内に構造体が複数個含まれる例も1つ示しておきます。

MDE + RFH2 + (後続のデータ)

図22. MDE + RFH2 + 後続のデータ
図22. MDE + RFH2 + 後続のデータ
図22. MDE + RFH2 + 後続のデータ

メッセージ本体の先頭部分に含まれる構造体が存在する場合のデータ変換

本節で紹介したような構造体を持つMQメッセージについても、「第4章 MQメッセージの受信における変換処理」に説明したとおり、MQGET処理において次の属性を指定することにより、データの変換を実行させることができます。

  • MQGMO内のOptionsにMQGMO_CONVERTをセット
  • MQMD内のフィールドCodedCharSetIdに希望する変換後の文字列のCCSIDを指定
  • MQMD内のフィールドEncodingに希望する変換後の数値データのEncodingを指定

変換が可能である場合は、MQGET処理において構造体の内容を解析し、含まれるそれぞれの数値と文字のデータを適切に変換することができます。第4章の「図6 文字列と数値データを含むメッセージの変換例」がこのケースに該当しますが、この例ではDLHと後続のデータ(DLH内のFormatの値が”MQSTR ”になっているので、後続のデータは全て文字データ)が適切に変換されています。

もし、メッセージ本体に含まれる構造体(「図6 文字列と数値データを含むメッセージの変換例」の例ではDLH)内のFormatの値が第2章の「表3  WebSphere MQにあらかじめ定義されているフォーマットの値」以外の値で、かつそのフォーマット名に対してデータ変換出口プログラムがユーザーにより提供されていない場合、MQはメッセージ本体内の後続の内容を認識することができず、処理結果は次のようになります。

  • 完了コードが1 (MQCC_WARNING)
  • 理由コードが2110 (MQRC_FORMAT_ERROR)
  • メッセージはキューから取り出される。
  • 変換処理は実行されずに、キュー内のデータがそのまま渡される。

後続のデータが変換できないのは必然ですが、Formatの値が含まれている構造体(上記の例ではDLH)自体も変換されずに元のままの状態で渡されますので、注意してください。

図23の例においては、メッセージ本体の先頭部分に含まれるDLH内のFormatの値が”FMTXX “となっているため、変換ができません。

図23. DLH + 後続のデータで変換エラーとなる例
図23. DLH + 後続のデータで変換エラーとなる例
図23. DLH + 後続のデータで変換エラーとなる例

ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=WebSphere
ArticleID=834244
ArticleTitle=WebSphere MQが提供するデータ変換機能 概説: 第9章 メッセージ本体の構造の変換
publish-date=09182012