EIP / Messaging Gateway


Messaging Gateway(メッセージングゲートウェイ)

一言要約

Messaging Gatewayを用いることで、アプリケーションは、メッセージ特有の コードを個別に実装することなく、カプセル化して疎結合な実装ができるようになる。

Context

1つのアプリケーションが、Messageingで他のシステムにアクセスする。

Problem

残りのアプリケーションからメッセージングシステムへのアクセスを、どうやってカプセル化するのか?

Detail

  • たいていのカスタムされたアプリケーションは、ベンダー提供のAPIを通じて、メッセージングの基盤にアクセスする。open channel, create message, send message のような 一般的に似たような機能を持っている。このAPIの種類は、アプリケーションが、いくつかのチャンネルの種類を通して、いくつかのメッセージデータの種類を送れるように許可している。送信するメッセージデータの中身が何かを伝えることは、ときどき難しいことがある。

  • メッセージングソリューションは、本質的には非同期である。このことは、メッセージングで外部のファンクションにアクセスするためのコードを、複雑にすることになる。 数値型のクレジットスコアを返すGetCreditStore?メソッドを呼び出すかわりに、アプリケーションはリクエストメッセージを送り、遅い時間に到着するための返信メッセージを予測しなければならない。(Request-Reply[154]を参照) アプリケーション開発者は、入ってくるメッセージイベントを扱うための同期の機能のシンプルな意味論を好むかもしれない。

  • アプリケーション間の疎結合は、メッセージフォーマット(フィールドを追加する)の中で小さな変更に耐えうるような、アーキテクチャの利点を提供してくれる。いつもは、疎結合はXMLドキュメントや、JavaやC#のクラスのような強力な片付けがない他のデータ構造を使うことで実現できる。この構造に反してコーディングすることは、くどい書き方でエラーを起こしやすくる。なぜなら、ミススペルしたフィールド名やミスマッチなデータ型を検知するためのコンパイルによる型付けがサポートされていないからである。なので、私たちはアプリケーション開発の効果の浪費しないように、よくデータフォーマットに柔軟性を持たせている。

  • たまに、メッセージング経由で実行されるシンプルなロジックの機能は、送信するメッセージを1つ以上要求することがある。
    • 例: 顧客情報を取得したい送信に対して、それぞれの想定受信は、住所、注文履歴、個人情報の場合。
  • 各これらのメッセージは、異なるシステムによって、処理されている。私たちは、3つの分かれたメッセージを送ったり受けたりすることが要求されている全てのロジックのアプリケーションコードを散らかしたくない。単一のメッセージを受け取って、3つの分かれたメッセージをを送信し、それらを単一の返信メッセージに集約するScatter-Gather(297)を使うことで、アプリケーションのいくつかの重荷を減らすことができる。しかし、いつもメッセージのミドルウェアにこのファンクションを追加する贅沢さは持ち合わせていない。


Solution

Messaging Gatewayを使う。1つのクラスは、メッセージ特定のメソッド呼び出しをラップしていて、ドメイン特定のメソッドをアプリケーションに公開している。



  • Messaging Gatwayは、メッセージ特定のコードをカプセル化する。(例えば、コードがメッセージを送信することや受信することを要求する) そして、アプリケーションコードの残りに分けられる。この方法は、Messaging Gatewayのコードだけは、メッセージングシステムについて知っている。アプリケーションコードの残りはしない。 Messaging Gateway が、アプリケーションの残りに対してビジネス機能を公開するため、Message.MessageReadProperyFileter?.Appspecifiのようなプロパティを設定するためにアプリケーションを要求することの代わりになる。Messaging Gatwayは、その他のメソッドのように強力に型付けされたパラメータを受付けるGetCreditScore?のような意味のあるメソッドを公開する。 Messaging Gatewayは、より一般的なGatewayパターン(EAA)のメッセージ特有のバージョンである。

  • アプリケーションとメッセージングシステムの間に、Messaging Gatewayは位置付けらていて、ドメイン特有のAPIを、アプリケーションに提供している(前の図を参照)。アプリケーションは、メッセージングシステムを利用することを意識しなくてもよくなるため、リモートプロシージャコールやもしくは、Webサービスのように、他の統合技術を使用した異なる実装でゲートウェイをスワップアウトさせることができる。

  • 多くのMessaging Gatewayはメッセージを他のコンポーネントに送信し、返信メッセージを予測する(Request-Reply[154]を参照)。 そのようなMessaging Gatewayは、2つの異なる方法で実装することができる。
  1. Blocking(同期的) Messaging Gateway
  2. Event-Driven(非同期) Messaging Gateway

Blocking(同期的) Messaging Gateway

  • アプリケーションに制御が戻る前にメッセージを送り出し、到着する返信メッセージを待つ。 ゲートウェイが返信を受け取ったとき、メッセージを処理して、アプリケーションに結果を返す。(Blocking(Synchronous) Messaging Gatewayのシーケンス図を参照)
  • Blocking Messaging Gatewayは、メッセージの相互の振る舞いの非同期な性質をカプセル化し、アプリケーションロジックに通常の同期的なメソッドを公開する。それで、アプリケーションは、いくつかの通信の非同期の部分に気づかない。
int GetCreditScore( string SSN);
  • このアプローチは、とてもシンプルにMessaging Gatewayに対してアプリケーションコードを書く一方で、また貧相なパフォーマンスに導いてしまう。なぜならアプリケーションは、動き出したり、他のタスクを処理している間に返信のメッセージを待ったりする時間のほとんどを費やしているからである。

Event-Driven(非同期) Messaging Gateway

  • イベント駆動 Messaging Gatewayは、メッセージングレイヤーの非同期な性質をアプリケーションに公開する。アプリケーションが、Messaging Gatewayにドメイン特有の要求してきたとき、返信のためのドメイン特有のコールバックを提供する。制御は、すぐにアプリケーションに戻す。返信メッセージが到着したとき、Messaging Gateway はそれを処理し、その後、コールバックを起動する(Event-Driven(Asynchronous) Messaging Gateway の図を参照)

  • 例えば、C#では、デリゲートを使用しており、Messaging Gatewayは、次のパブリックなインターフェイスを公開できている。
    delegate void onCreditReplyEvent( int CreditScore);
    void RequestCreditScore( string SSN, OnCreditReplyEvent OnCreditResponse);

  • RequestCreditScore?メソッドは、返信メッセージが到着したときに起動されるコールバックメソッドを特定する追加のパラメータを受け取る。コールバックメソッドは、パラメータCreditScore?を持っているので、Messaging Gateway はアプリケーションの結果を渡すことが出来る。プログラミング言語もしくはプラットフォームに依存して、コールバックは、ファンクションポインタや、オブジェクトの参照、デリゲートで、達成できる。このインターフェイスのイベント駆動の性質にもかかわらず注意すること。特定のメッセージングの技術において少しも依存性はない。
  • 代わりに、アプリケーションは、結果が届いたかどうかを見るために定期的に問い合わせることができる。このアプローチは、より高いレベルのインターフェイスを、ブロッキングを導入することなくシンプルに作ることになる。本質的には、Half-Sync/Half-Async Patter[POSA2]を使っている。このパターンは、入ってくるメッセージを貯めこむバッファの仕様を特徴としている。そのため、便利にメッセージが到着しているかどうかをアプリケーションは問い合わせることができる。

  • イベント駆動のMessaging GateWay?を使う挑戦の1つは、Messaging Gatewayは、リクエスト方法とコールバックイベント(コールスタックは、このブロッキングのケースで面倒をみます)アプリケーションが状態を維持することを必要とする。Messaging Gatewayは、アプリケーションロジックの中にあるコールバックイベントを起動し、アプリケーションは、返信とより簡単な要求を相互に関連付けることをしなければならないので、正しいスレッドの実行を、処理し続けることができる。もしアプリケーションが、要求するメソッドに対してデータのセットをする調停者に、参照を渡すことが許されているならば、Messaging Gateway は、アプリケーションのために、状態を維持することをより簡単にすることができる。Messaging Gatewayは、それでこのデータを通して、コールバックでアプリケーションに戻す。この方法は、非同期のコールバックが、起動された時に、アプリケーションが全ての必要なデータを利用可能にする。この相互のふるまいのタイプは、一般的にACT(Asynchronous Completion Token)[POSA2]と呼ばれる。

  • ACTをサポートした イベント駆動のMessaging Gatewayの公開用のインターフェイスは、このように見受けられるだろう。
    delegate void onCreditReplyEvent(int CreditScore, Object ACT);
    void RequestCreditScore(string SSN, OnCreditReplyEvent OnCreditResponse, Object ACT);
  • RequestCreditScore?メソッドは、Object型参照 の追加のパラメータを持っている。Messaging Gatewayは、参照を保持し、応答メッセージが届くのを待つ。応答が届いたとき、Gatwayは、OnCreditReplyEvent? 型の delegate を起動する。オブジェクトの参照と同じように操作の結果を渡す。アプリケーションのためにとても便利な機能を有しているACTをサポートしている一方で、もしMessaging Gatewayが予測された応答メッセージが決して届かないオブジェクトの参照を保持し続けるのであれば、メモリーリークの危険を導入することになる。

Changing Gateways

  • Message Gatewaysの1レイヤー以上を作るのに有益である。lower-level Messaging Gatewayは、一般的なメッセージングの意味を維持しながらもメッセージングシステムの文法を単純に抽象化できる。例えば、SendMessage?がそうだ。このMessaging Gatewayは、企業がメッセージングの技術を、例えばMSMQからWebSevice?に変更する時に、アプリケーションの残りを守ることを手助けできる。GetCreditScore?のような、一般的なメッセージのAPIを、ドメイン特有のAPIに狭めて、翻訳する追加のMessaging Gatewayで、この基盤のMessaging Gatewayは、ラップしてる。Loan Broker の例のMSMQの実装で、この設定を使用している。(A Chain of Gateway Provides Different Levels of Abstractionの図を参照。もしくは、""Asynchronus Implementation with MSQM""のセクションを参照)

Dealing with Message Exceptions

  • より簡単にアプリケーションをコーディングするのに加えて、Meesaging Gatewayの意図もまた、特定のメッセージ技術においてアプリケーションコードの依存性を取り除くはずである。これは、Messaging Gateway のインターフェイスの裏でいくつかのメッセージング特有のメソッドの呼び出しをラッピングすることで簡単になっている。しかし、ほとんどのメッセージングレイヤーは、メッセージ特有の例外を投げてくる。InvalidDestinationException?は、JMSによって上がってくる。もし本当に自分たちのアプリケーションを、メッセージライブリから独立して作りたいのであれば、Messaging Gatewayは、いくつかのメッセージング特有のエクセプションをキャッチするようにしなければならない。そして、代わりにアプリケーション特有の例外を投げなければならない。このコードは少し長々しくなるが、例えば、JMSからWebサービスにもし根底にある実装を切り替えなければならないのであれば、とても便利である。

Generating Gateways

多くの状況では、外部リソースで公開されたメタデータからMessaging Gatewayのコードを生成することができる。これは、世界のWebサービスにおいて共通である。

Using Gateways for Testsing

Messaging Gatewayは、伝達手段の素晴らしいテストをする。なぜなら、ドメイン特有のインターフェイスに狭ばめられた裏で全てのメッセージングコードをラップしているからである。簡単に、インターフェイスのダミーの実装を生成することができる。

Example:MSMQでの非同期Loan Broker Gateway

ここの例では、Chpter 9:Interulde: Composed Meesaginで紹介した例のLoan Broker の一部を示している。 (Asynchronous Impletation with MSMQ).

  • ※コードは省略します。

担当者のつぶやき

みんなの突っ込み