特集
次世代XML Webサービスを試す Part 3

3.WS-RoutingのSOAPメッセージ

インフォテリア株式会社
吉松 史彰
2003/02/20

Page1 Page2 Page3 Page4 Page5 Page6

送受信されるWS-RoutingのSOAPメッセージ

 これでクライアントの実装も完了だ。さっそく実行してみると、まずクライアントはhttp://localhost/WSERouting/a.ashxに接続して、次のようなSOAPメッセージを送信する。

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>

    <wsrp:path
        soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
        soap:mustUnderstand="1"
        xmlns:wsrp="http://schemas.xmlsoap.org/rp">
      <wsrp:action>http://tempuri.org/Echo</wsrp:action>
      <wsrp:to>http://localhost/WSERouting/Service1.asmx</wsrp:to>
      <wsrp:fwd>
        <wsrp:via>http://localhost/WSERouting/a.ashx</wsrp:via>
        <wsrp:via>http://localhost/WSERouting/b.ashx</wsrp:via>
        <wsrp:via>http://localhost/WSERouting/c.ashx</wsrp:via>
      </wsrp:fwd>
      <wsrp:rev />
      <wsrp:id>uuid:76c87c3a-03c6-4643-8bca-cf8ddec8beae</wsrp:id>
    </wsrp:path>
    <wsu:Timestamp
        xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
      <wsu:Created>2003-01-27T06:19:33Z</wsu:Created>
      <wsu:Expires>2003-01-27T06:24:33Z</wsu:Expires>
    </wsu:Timestamp>
  </soap:Header>
  <soap:Body>
    <Echo xmlns="http://tempuri.org/">
      <input>hello</input>
    </Echo>
  </soap:Body>
</soap:Envelope>

最初の中継者a.ashxに送信されるSOAPメッセージ
fwd要素には経路上の中継者が設定されている。rev要素には、処理が進むにつれて帰りの経路が書き込まれていく。

 SOAPのHeader要素中のPath子要素には、4つの子要素が設定される。action要素はこのSOAPメッセージの意図を表すURIで、この場合はhttp://tempuri.org/Echoで識別される何がしかの処理を実行してほしいという意味になる。

 to要素はSOAPメッセージの最終的な受信者を示すURIで、この場合はサービスのURLが記述されている。fwd要素はSOAPメッセージが送信者から最終的な受信者に至るまでに通る経路上の中継者を示す。ここではMainメソッド内のコードで指定した3つのURLが設定されている。現在は、最初のvia要素の中身であるa.ashxが処理されているわけだ。

 rev要素は、いまは空だが、今後処理が進むにつれて、帰りの経路が書き込まれていく。最後のid要素はメッセージの識別子となるUUID(ユニバーサル・ユニーク識別子)である。

 path要素についているactorとmustUnderstandの2つの属性にも注意してほしい。actor属性にはSOAP仕様で規定されているactorであるhttp://schemas.xmlsoap.org/soap/actor/nextが指定されている。これは「このメッセージを受け取った全受信者」が該当する識別子であり、従ってpath要素は全受信者が処理の対象として検討しなければならない要素であることを示している。

 さらに、mustUnderstand属性には“1”が指定されている。これは「対象として指定された受信者は、必ずこのヘッダを処理しなければならない」という意味である。従って、この場合のa.ashxというSOAP中継者(実体はRoutingHandlerクラス)は必ずpath要素を処理しなければならない。もし意味が分からず処理できなかった場合は、そこで経路が中断され、送信者にSOAP Faultが返されることになる。

 さて、現在SOAPメッセージを処理しているRoutingHandlerクラスは、SOAPメッセージを、何も考えずに次の中継者へ転送する。a.ashxがb.ashxに転送するメッセージは次のようになる。

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <wsu:Timestamp
        xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
      <wsu:Created>2003-01-27T06:19:33Z</wsu:Created>
      <wsu:Expires>2003-01-27T06:24:33Z</wsu:Expires>
      <wsu:Received Actor="http://localhost/WSERouting/a.ashx"
          Delay="1000">
        2003-01-27T06:19:33Z
      </wsu:Received>
    </wsu:Timestamp>

    <wsrp:path
        soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
        soap:mustUnderstand="1"
        xmlns:wsrp="http://schemas.xmlsoap.org/rp">
      <wsrp:action>http://tempuri.org/Echo</wsrp:action>
      <wsrp:to>http://localhost/WSERouting/Service1.asmx</wsrp:to>
      <wsrp:fwd>
        <wsrp:via>http://localhost/WSERouting/b.ashx</wsrp:via>
        <wsrp:via>http://localhost/WSERouting/c.ashx</wsrp:via>
      </wsrp:fwd>
      <wsrp:rev>
        <wsrp:via>http://localhost/WSERouting/a.ashx</wsrp:via>
      </wsrp:rev>
      <wsrp:id>uuid:76c87c3a-03c6-4643-8bca-cf8ddec8beae</wsrp:id>
    </wsrp:path>
  </soap:Header>
  <soap:Body>
    <Echo xmlns="http://tempuri.org/">
      <input>hello</input>
    </Echo>
  </soap:Body>
</soap:Envelope>

中継者a.ashxから中継者b.ashxへ転送されるSOAPメッセージ
fwd要素のvia子要素からa.ashxが消え、rev要素のvia子要素が追加されている。

 fwd要素のvia子要素からa.ashxが消え、rev要素のvia子要素が追加されたのが分かる。これはWS-Routing仕様の処理モデルで規定されている動作である。中継者は自分の処理が完了すると、行きの経路から自分を外さなければならない。また、帰りの経路として自分自身を追加できるようになっている。

 b.ashxがc.ashxにSOAPメッセージを転送すると、path要素の内容は次のようになる。

<wsrp:path soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
    soap:mustUnderstand="1"
    xmlns:wsrp="http://schemas.xmlsoap.org/rp">
  <wsrp:action>http://tempuri.org/Echo</wsrp:action>
  <wsrp:to>http://localhost/WSERouting/Service1.asmx</wsrp:to>
  <wsrp:fwd>
    <wsrp:via>http://localhost/WSERouting/c.ashx</wsrp:via>
  </wsrp:fwd>
  <wsrp:rev>
    <wsrp:via>http://localhost/WSERouting/b.ashx</wsrp:via>
    <wsrp:via>http://localhost/WSERouting/a.ashx</wsrp:via>
  </wsrp:rev>
  <wsrp:id>uuid:76c87c3a-03c6-4643-8bca-cf8ddec8beae</wsrp:id>
</wsrp:path>
b.ashxからc.ashxへ転送されるSOAPメッセージのpath要素

 そして、c.ashxがService1.asmxにSOAPメッセージを転送すると、path要素の内容は次のようになる。

<wsrp:path soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
    soap:mustUnderstand="1"
    xmlns:wsrp="http://schemas.xmlsoap.org/rp">
  <wsrp:action>http://tempuri.org/Echo</wsrp:action>
  <wsrp:to>http://localhost/WSERouting/Service1.asmx</wsrp:to>
  <wsrp:rev>
    <wsrp:via>http://localhost/WSERouting/c.ashx</wsrp:via>
    <wsrp:via>http://localhost/WSERouting/b.ashx</wsrp:via>
    <wsrp:via>http://localhost/WSERouting/a.ashx</wsrp:via>
  </wsrp:rev>
  <wsrp:id>uuid:76c87c3a-03c6-4643-8bca-cf8ddec8beae</wsrp:id>
</wsrp:path>
c.ashxからService1.asmxへ転送されるSOAPメッセージのpath要素

 Service1.asmxは次のような返信メッセージを生成し、c.ashxに返す。このとき、

  • 送信者 → a.ashx
  • a.ashx → b.ashx
  • b.ashx → c.ashx
  • c.ashx → Service1.asmx

の4つのHTTPセッションはいずれもまだ生きていることに注意してほしい。これらが生きているので、Service1.asmxからの返信メッセージはHTTPのレスポンスを返すことで経路を逆にたどることができる。このため、返信メッセージにはWS-Routingのpath要素を含めなくてもいいのだ*2

*2 このように、WSEが持っているデフォルトのルータ(RoutingHandler)を使用する限り、非同期実行は実現できない。これはWSEの実装の問題であって、WS-Routingの仕様自体は非同期返信をサポートしていることに注意してほしい。
 
<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <wsu:Timestamp
      xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
    <wsu:Created>2003-01-27T06:19:34Z</wsu:Created>
    <wsu:Expires>2003-01-27T06:24:34Z</wsu:Expires>
    </wsu:Timestamp>
  </soap:Header>
  <soap:Body>
    <EchoResponse xmlns="http://tempuri.org/">
      <EchoResult>hello</EchoResult>
    </EchoResponse>
  </soap:Body>
</soap:Envelope>
Service1.asmxからc.ashxへ返される返信メッセージ
経路途中のHTTPセッションは閉じられていないため、返信メッセージにはpath要素が含まれる必要はない。

 ここまでのWSEによる実装を見て「おかしい」と思った読者も多いだろう。上記の手順では、SOAPメッセージがたどる経路はクライアント・アプリケーションで明示的に指定している。ということは、クライアント側でサーバ側の経路情報を把握しておかなくてはならない。これでは、ファイアウォールやロード・バランサのようなルータは実現できない。

 WSEでは、サーバ側で経路を決めてWS-Routingのヘッダを設定することもできるようになっている。次回後編では、サーバ側で経路を決定するための2つの方法について解説する。


 INDEX
  [特集]次世代XML Webサービスを試す Part 3
  SOAPメッセージのルーティング
    1.SOAPメッセージのルーティングを規定するWS-Routing
    2.WSEでのWS-Routing利用
  3.WS-RoutingのSOAPメッセージ
    4.WSEによるルータの実装
    5.WS-Referralを利用したルーティング(1)
    6.WS-Referralを利用したルーティング(2)
 
 「特集:次世代XML Webサービスを試す」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間