研究者の予測によれば、様々な企業が次々にWebサービスを利用するようになるにつれ、Webサービスは、単にシングルエンドのプロセス以上のものを提供するようになるだろうと言われています。一般的に言って、複合アプリケーションの重要性が増し、企業は次第に、より複雑なプロセス相互動作の一部としてWebサービスを使うようになっています。WSCは、正にこの傾向を対象に据えています。
WSCIは、WSDLと組み合せて動作する、XMLベースのインターフェース記述言語です。WSCIの目標は、Webサービスの力を利用して、ダイナミックで変化し続ける今日のビジネス要求に応えるビジネス・プロセスを作れるようにすることです。そうすれば、企業はそのアプリケーション・ソフトウェアやリソースをWebサービスとして公開し、他の企業が動的にそれらを発見してビジネス・プロセスの中で使えるようになります。ビジネス・プロセスを作るためには、そのコンポーネントすべての協調パターンを明確に定義することだけではなく、標準的なB2B(Business-to-Business)相互動作を記述するための手段も必要になります。
これから先では、簡単なオンライン証券会社が、どのようにWebサービスとWSDLを使ってサービスを公開するかを説明し、この手法での欠点、またWSCを利用することによって、こうした欠点が克服できることを示して行きます。この記事では、WSCを解説しながらその価値を紹介し、その特徴の幾つかを学びます。
WSCの必要性と役割は、簡単なオンライン証券会社の例を使って説明することができます。簡単にするために、重要なアクションの大部分を説明しましょう。ただし、株の売買に関するステップの詳細は、この記事の目的ではありませんので省略します。ここでは、単純な株取引の例を使います。下の図1は、オンラインのWebアプリケーションを使って株を売買するために必要なビジネス・プロセスを、ステップ毎に示しています。
図1. 株取引のビジネス・プロセス
オンラインの株取引アプリケーションでは、株の詳細を、例えばxmethods.netなど、サードパーティーのWebサービスから取得し、ユーザーに提供します。ユーザーは、ある株に関心を持つと、その株を選び、より詳細なデータを要求します。オンライン証券会社は、あるサードパーティーのWebサービスを使って、詳細情報を取得します。
ユーザーは、どの株を購入するかを決定すると、買い注文を入れます。オンライン・アプリケーションは、それ自身の内部プロセスを使って、株式市場から株を購入します。するとオンライン株取引アプリケーションは、ユーザーに対して買い注文を確定するように要求し、注文を確定するための期限を設定します。1分以内に注文を確定しないと、ユーザーに対してのタイムアウト・メッセージとなります。
ユーザーが注文を確定すると、オンライン株取引アプリケーションは、ユーザーの口座から、必要な金額を引き落とします。アプリケーションはこれを、既存のサードパーティーWebサービスを使って行います。アプリケーションは1つのWebサービスを使ってクレジット・カードを認証し、2番目のWebサービスを使って必要な金額を引き落とします。両ステップは1つの論理ユニット動作として処理する必要があり、一方のサービスが失敗した場合には、ユーザーに対してのフェール・メッセージとなります。クレジット・カードが無事認証され、ユーザーの口座から資金が無事に送金されると、オンライン・アプリケーションは、必要な口数の株を市場から購入します。ユーザーは、1つ以上の買い注文を入れることができ、それぞれの買い注文は、別の論理ユニット動作として扱われます。
売り注文も、買い注文と同様のステップで行われます。ユーザーは売り注文を入れ、指示されると注文を確定します。確定するとオンライン・アプリケーションは売り注文を入れ、顧客の口座詳細を検証した後、ユーザー・アカウントに入金します。
オンライン証券会社は、ビジネス・チャネルを広げ、他のシステムと協調動作するために、売買アプリケーションをWebサービスとして公開します。単純なWebサービスの場合は、上記のステップを、WSDLファイルでのオペレーションにマッピングすることができます。そうすると顧客は、Microsoft VBAエディター、あるいはWebサービスを呼ぶ外部アプリケーションなどWebサービス・ソフトウェアを使って、こうしたWSDLオペレーションを呼び、売買注文を入れることができます。次のリンクは、VBAを使ってこれを行う方法を説明しています(http://www.microsoft.com/office/previous/xp/webservices/toolkit.asp)。上の図1は、WSDLオペレーションと、ビジネス・プロセスとのマッピングを説明しています。
よく定義された株式売買Webサービスでは、すべてのプロセスがアトミックであれば、つまり何ら状態を共有しなければ、うまく動作します。しかしこの場合、WSDLだけでも、ビジネス・プロセス統合における中核的要求事項が見えてきます。例えば次のような問題です。
-
プロセス・シーケンス
売買Webサービスを利用するサービス利用側は、任意のシーケンスでオペレーションを呼ぶことができます。例えばサービス利用側は、placeBuyOrderやplaceSellOrderオペレーションを呼ぶ前に送金オペレーションを呼ぶことができます。WSDLでは、どのような順番でオペレーションが呼ばれても、それを防ぐことはできません。WSDLを使うWebサービス・アプリケーションは、この点を上記のロジックの中で考慮しておく必要があります。 -
メッセージ相関
相関(correlation)の考え方は単純です。レスポンスが(恐らく、どこか後の時点で)返ってくるのを期待して誰かにメッセージを送信し、ある共通のデータ片を使って、返ってきたメッセージ・インスタンスを送信メッセージ・インスタンスと結びつける(つまり相関させる)のです。ビジネス・プロセスの相互動作では、メッセージ・インスタンス同士の相関を理解し、記述することは非常に重要です。ところがWSDLには、メッセージ・インスタンスを相関させる機能はありません。つまりWSDLは、オペレーション間の状態を保持しないのです。典型的なビジネス・プロセス統合では、プロセスは通常、協調プロセスを提供する目的から、状態を共用します。WSDLを使って公開されるオペレーションは全てステートレスであり、メッセージ・インスタンス同士を相関させる機能はありません。 この例では、ユーザーが次のステップとして買い注文を入れると、Webサービス・アプリケーションは注文を確定するようにユーザーに要求します。しかしユーザーは、注文する株の口数や、買い注文を入れる日を変更するかも知れません。注文を変更すると、ユーザーは再度、買い注文を入れなければなりません。この、会話動作(conversation)は何度も起こる可能性があり、ユーザーは幾つかの買い注文を呼び出すかも知れません。つまり、Webサービス・アプリケーションとの会話動作を幾つか呼び出すかも知れません。しかし、WSDLだけを使うWebサービスには、メッセージ・インスタンス同士を相関させる機能は無いのです。 -
動作単位
Webサービスを長いメッセージ交換の一部とするためには、いつメッセージ交換が実際にトリガーされるのか、いつの時点でそれが終了したと考えられるのか、また、どの部分がトランザクション的に管理されると考えられるのか、などを明確に定義することが重要です。 この例では、placeBuyOrderオペレーションとconfirmBuyOrderオペレーション、そしてdebit money(出金)プロセスは、1単位の動作として行う必要があります。Webサービスは、3つのオペレーション全てを無事実行するか、あるいは3つの一貫性を保ったままで実行前の状態に戻す必要があります。ところが、WSDLで公開された分散トランザクション用のオペレーションを使うことはできません。WSDLでは、トランザクションのスコープは個々のオペレーションに限定され、1つ以上のオペレーションには広がらないのです。 -
例外処理
WSDLは、どの例外を投げる場合も障害コード(fault code)を使いますが、モデリングの成果物には対応していません。つまり特定なメッセージをチェックしたり、例外タイムアウトを宣言したり、(Webサービス全体に対してではなく)あるオペレーション・セットのみのための例外を宣言したりはしません。 プロセスが相互動作するためには、適切な例外モデリング成果物が必須です。この例では、ユーザーが売買注文の確定に1秒以上かかると、Webサービスはタイムアウト例外を投げます。 -
コンテキスト
ビジネス・プロセスの相互動作では、関係するプロセスが、情報共有のためのコンテキストを確立することが重要です。こうした情報としては、一連の宣言や例外イベント群、トランザクション・プロパティーなどがあります。WSDLでは、コンテキスト内でプロセスが動作するための機能が何もありません。
図2. WSDLを使った株取引
上に挙げたような欠点、つまりWSDLをベースとし、その機能を拡張してプロセス統合を行う上で障害となる点は、WSCを使うことで解決できます。下記は、こうした欠点に対してWSCIがどのように対応しているかを説明しています。
幾つかのサービスを集約して複合ビジネス・サービスを作る場合には、サービスがコンテキストを共有する必要があります。コンテキスト要素は、アクティビティーを実行するための環境を設定します。コンテキスト要素はまた、一連のアクティビティーが1つのグループとして行われること、そしてコンテキスト内の全アクティビティーが、一連の宣言や例外イベント群、トランザクション・プロパティーなどを共有することも保証します。
コンテキスト定義には、ローカル・プロパティーとローカル・プロセス定義があります。ローカル・プロパティーは、このコンテキストを実行しているアクティビティーにしかありません。ローカル・プロセス定義は、このコンテキスト内でインスタンス化できるプロセスだけを指定します。ローカル・プロセスを呼んだり作成したりするためには、そのローカル・プロセスの定義が見えるコンテキストから行う必要があります。
下記のリスト1のローカル・プロセス定義では、株の売りと買いではコンテキストが別です。もし、株の買いプロセスで障害が起きても、その障害はそのプロセスに限定されます。例えば、もしコンテキストが定義されていないと、売りプロセスで障害が起きた場合には、状態がplaceSellOrderに戻されるのではなく、ユーザーがWebサービスから追い出されます。このWSCI定義の一部を下記に示します。
リスト1. コンテキスト要素の例
<context>
<foreach select="ns1:arrayOfStockList/leg[position()>1]">
<process name = "PlaceBuyOrder" instantiation = "other">
<action name = "PlaceBuyOrder"
role= "tns:trader"
operation= "tns:placeBuyOrder">
</action>
</process>
</foreach>
<process name = "ConfirmBuyOrder" instantiation = "other">
<action name = "ConfirmBuyOrder"
role= "tns:trader"
operation= "tns:confirmBuyOrder" >
<correlate correlation =
"defs:buyStockCorrelation" instantiation= "true" />
</action>
<exception>
<onTimeout property =
"tns:confirmationTime"
type= "duration"
reference="tns:PlaceBuyOrder@end">
<compensate transaction = "tns:reverseBuyOrders"/>
</onTimeout>
</exception>
</process>
<process name="transferMoney" instantiation="other">
<action name = "cashTransaction"
role= "tns:trader"
operation= "tns:debitMoney" >
</action>
</process>
<exception>
<onMessage>
<action name = "reverseBuyOrders"
role= "tns:trader"
operation= "tns:cancelBuyOrder">
</action>
<fault code = "tns:creditCardTxFaultCode"/>
</onMessage>
</exception>
</context>
|
もっとキメの細かいビジネス・プロセスを、シーケンスに従って呼び、またグローバルなビジネス・プロセスの下でグループ化するために、WSCではインターフェース要素シーケンスを使います。その名が示す通り、インターフェース要素シーケンスによって、システムはシーケンスに従って呼ばれるようになります。例えばサービス利用側が株を購入しようとする場合には、このインターフェース要素は、買いプロセスの前に資金転送オペレーションを呼びます。これは、そのシーケンス要素内の全オペレーションが、あるシーケンスで呼ばれるように定義することによって行われます。これをリスト2に示します。
リスト2. 要素をシーケンス化する例
<sequence>
<!-- Web service Choreography Sequence -->
<operation name="placeBuyOrder">
<input message="buySellOrderRequest"/>
<output message="buySellOrderResponse"/>
</operation>
<operation name="confirmBuyOrder">
<input message="buySellOrderResponse"/>
<output message="buySellOrderResponse"/>
</operation>
<operation name="debitMoney">
<input message="creditCardDetails"/>
<output message="debitMoneyResponse"/>
</operation>
</sequence>
|
WSCでは、サービスに対するメッセージが到着した時に、暗黙的にインスタンスを作ることができます。WSCで作られるインスタンスは、データ・メッセージ内の鍵フィールドを使って識別されます。この例では、confirmBuyOrderプロセスとplaceBuyOrderプロセスは、以前のインスタンスで起きているかも知れないため、両者を相関させることが重要です。サービス利用者側は、注文を確定するように促されると、(例えば株価の変動のため数量を変更しようとして)注文を変更し、再度買い注文を入れるかも知れません。この会話動作は、サービス利用者とWebサービスとの間で、何度も起こる可能性があります。
サービス利用者は、1つ以上の買い注文を入れるかも知れないので、1つ以上の会話動作がトリガーされる可能性があります。ですから、それぞれの会話を識別できる必要があります。このために、placeOrderIdが使われます。この機構が提供されているため、サービス利用者側は好きな数だけ買い注文を入れることができ、しかもそれぞれの注文は、別々の会話に参加するのです。それぞれの会話に対して、固有のplaceOrderIdが作られます。
このためには、固有IDを持ったプロパティーで相関要素を定義します。この例の場合では、株価コードがそれに当たります(リスト3)。
リスト3. 相関要素の例
<correlation name = "buysellCorrelation"
property = "tns:placeOrderId" />
|
WSCIはトランザクション要素を使ってWebサービスの振る舞いをモデル化し、幾つかのアクティビティーを1単位の動作として扱います。WebサービスはWSCIトランザクションを使って他のサービスと通信し、自分が2つのいずれか(こうしたアクティビティーを完全に実行するか、あるいは一貫性を保ったまま全てを実行前の状態に戻すか)ができることを伝えます。
株の売買の例では、オンライン証券会社は、サードパーティーが提供する別々のWebサービス(例えばサードパーティーのクレジット・カードWebサービスなど)に話しかけます。例外プロセスが起きた場合、あるいはサードパーティー・プロバイダーとのトランザクションを終了できない場合には、Webサービスは、その前の状態に戻ることを保証しなければなりません。これは、トランザクション要素と補償要素(compensation element)を使って行われます。リスト4は、このコードの一部を示しています。
リスト4. トランザクション要素の例
<transaction name = "reverseBuyOrder"= "atomic">
<compensation>
<action name = "reverseBuyOrder"= "tns:trader"=
"tns:reverseBuyOrder"/>
</compensation>
</transaction>
The transaction can be called in a compensation element when
an exception occurs as shown below:
<onTimeout property = "tns:confirmationTime"= "duration"=
"tns:PlaceBuyOrder@end">
<compensate transaction = "tns:reverseBuyOrder"/>
</onTimeout>
|
ビジネス・プロセスの統合では、例外の処理と、そのために適切な経路を使うことは、通常のケース(例えばhappy flowなど)を処理するのと同じくらいに重要です。WSCIでは、このために例外要素を使います。WSCIでは、コレオグラフィー(choreography)のある時点でWebサービスが公開する例外振る舞いを宣言することを許しています。例外振る舞いの宣言はコンテキスト定義の一部であり、こうした例外への対応としてWebサービスが実行する一連のアクティビティーと、例外とを関連付けます。例外は、会話のある時点でWebサービスが公開した例外振る舞いをモデル化するために作られた、WSCIモデリング成果物です。例外は、必ずしも何らかの「技術的障害」を表現するわけではありません。
WSCIは、WSDLからの障害メッセージやメッセージ内容、あるいは何かのイベント(例えばTimeoutイベント)に基づいて例外を上げます。例外が起きると、その例外と関連付けられたアクティビティーが実行された後、現在のコンテキストは終了されます。つまりWSCIは、コレオグラフィー全体を終了させることのない、「回復可能例外(recoverable exceptions)」の概念をサポートしているのです(Java™での throw / catch の概念と似ています)。しかし、例外振る舞いが何も定義されていない障害が起きると、コンテキストは終了され、障害は親コンテキストで上げられます。もっと抽象的に言うと、親のコンテキスト定義の中で定義された例外処理の振る舞いは、その親の子すべてに対して、デフォルトの振る舞いとして動作します。また逆に、コンテキスト定義の中で定義された例外処理の振る舞いは、その親の中で定義された例外処理の振る舞いをオーバーライドするために使われます。
リスト5で、ユーザーが注文の確定に1分以上かけると、アプリケーションはタイムアウトする必要があります。WSCでは、これをタイムアウト機能を使って処理します。タイムアウト要素は、実はイベント要素であり、例外要素の中で使われます。1分経つとタイムアウト・イベントがトリガーされ、システムは補償要素を使って、その前のplaceBuyOrder状態に戻ります。
リスト5. 例外とタイムアウト要素の例
<exception>
<onTimeout property = "tns:expiryTime"
type = "duration"
reference="tns:ReserveSeats@end">
<compensate transaction = "tns:seatReservation"/>
</onTimeout>
</exception>
|
図3. WSCIを使った株取引
下記の表1は、WSCIの持つ、その他の便利な機能をリストアップしたものです。完全なリストについては、WSCIのドキュメントを参照してください。
表1. WSCI要素
| 要素名 | 簡単な説明 | 例 | |
| Selector | selector要素は、メッセージからプロパティー値を選択します。これは、複雑なメッセージを、プロパティー・セットとして抽象化する時に便利です。 | selector要素を使うと、getAllStocksResponse メッセージから合計株数を取得することができます。
| |
| Call | call要素は、アクションの間に、任意のオペレーション(例えばサードパーティーのWebサービスへのコール)を呼びます。これは本質的にアトミックであり、呼ばれたプロセスで障害が起きるとアクションはフェールします。 | 監査や調停用の目的で、アプリケーションが全トランザクションのログを取りたいような場合、任意のプロセスを呼んでこれをログすることができます。
| |
| Allアクティビティー | allアクティビティー要素はシーケンス・アクティビティーと似ており、この中で定義されたオペレーションはすべて実行されますが、この要素の中で定義されたアクティビティーは順不同で行われます。 | この例では、買い注文と出金は、任意の順序で実行することができます。
| |
| Foreach | foreach要素は、ある条件に基づいて、ループの中でアクティビティーを実行します。Javaのforループと似ています。 | これは、arrayOfStocksにある株のそれぞれに対して、PlaceSellOrderを実行します。
| |
| Switch | switch要素は、ある条件に基づいて、アクティビティー・リストからのアクティビティーを選択します。条件の順序は非常に重要であり、真と評価される条件が最初に実行されます。Javaのcase命令と似ています。 | 下記は、条件が真の場合に、適切なアクションを実行します。条件が真でない場合には、デフォルトのアクションを実行します。
| |
| Until | until要素は、ブール値に基づいて、全てのアクティビティーを少なくとも一度は実行します。Javaでのdo while命令と似ています。 |
| |
| While | while要素は、ブール値に基づいて、全てのアクティビティーをゼロ回以上実行します。Javaのwhile命令と似ています。 |
| |
| Delay | delay要素は、規定された遅延期間をおいてアクティビティーを実行します。そのアクティビティー内で例外が起きた場合には、そのアクティビティーは規定された時間の前に終了するかもしれません。 |
| |
| Call | call要素はプロセスをインスタンス化し、それが完了するのを待ちます。call要素は、内部プロセスを呼ぶ際に便利です。 |
| |
| Spawn | spawn要素はプロセスをインスタンス化しますが、それが完了するまでは待ちません。 |
| |
| Join | join要素は、作成されたプロセスのインスタンスが完了するまで待ちます。インスタンスが存在しない場合、あるいは全インスタンスが既に完了している場合には、このアクティビティーは完了します。 |
|
Webサービスが、コレオグラフィーに従って他のサービスと相互動作する際、交換するメッセージの流れを記述するための標準方法は、これまでありませんでした。この問題に対応するため、BEA SystemsとIntalio、SAP AG、そしてSun Microsystemsは、WSCIを開発しました。この記事では、WSCIが提供する基本機能の幾つかを簡単な例を通して学びました。ただし、ここで解説した内容は、ごく表面的なことだけです。WSCIをさらに理解するためには、WSCI仕様を読み、またWSCIを使って簡単なサンプル・アプリケーションを書いてみると良いでしょう。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| WSCI For Stock Buy Sell_attachment | WSCIForStockBuySell_attachment.xml | 5KB | HTTP |
- W3Cから、Web Service Choreography Interface仕様を入手してください。
- Microsoft VBAエディターでのWebサービスの使い方を知るために、Office XP Web Services Toolkit Tourを見てみてください。
-
Developer Bookstoreには、Webサービスに関する書籍を始め、広範な話題を網羅した技術書が豊富に取り揃えられていますので、ぜひご利用ください。
- developerWorksのSOA and web services ゾーンでは、豊富な記事を提供しています。
Jerome Josephraj はイギリスの Essex 在住であり、これまで IBM の Web サイトで、Struts と Web サービスに関する記事を公開しています (一部は日本語化されています)。また、Jakarta Struts Cookbook と Web Service, Now 書籍化提案の公式リビューアーでもあります。