日本オラクル
プロダクトSC本部 テクノロジーSC部
佐藤 直生

第3回:BPELによるWebサービスの連携




 はじめに

前回まで2回にわたり、WSDLの観点から単一のWebサービスを考える上でのポイントをご紹介しました。Oracle JDeveloper 10gやOC4Jを使って、J2EE 1.4準拠のJAX-RPC Webサービスを簡単に構築できることも、お分かりいただけたかと思います。

今回からは、複数のWebサービスを組み合わてビジネス・プロセスを定義するための言語であるBPELを取り上げ、そのポイントをご紹介していきます。オラクルが提供するBPEL開発/実行環境 Oracle BPEL Process Managerについても、合わせてご紹介していきます。


 BPELとは?

(JAX-RPCやMicrosoft .Netなどで実装された)複数のWebサービスがすでに利用可能な状況を考えてみましょう。それぞれのWebサービスは、ビジネス上価値のある「サービス」を提供しているものとします。すると、それらのWebサービスを組み合わせ、既存のWebサービスを再利用しつつ、より価値のあるサービスを提供することを考えますよね?このシナリオはまさに、数年前にWebサービスが登場したころから言われ続けてきたWebサービスのメリットの1つです。

ですが、BPELのようなビジネス・プロセス定義言語なしには、これを実装するのは大変でした。確かに、JAX-RPCでもMicrosoft .Netでも他のWebサービス・ツールキットでも、WebサービスにアクセスするクライアントAPIが提供されています。このクライアントAPIを駆使して、プログラム的に複数のWebサービスを呼び出すビジネス・プロセスを実装することは、できない話ではありません。

とはいえ、長期間にわたるビジネス・プロセスを定義する上で通常必要になるさまざまな機能を、手作業でプログラム的に実装していくのは、面倒で効率の悪い作業になってしまいます。ビジネス・プロセス定義に必要な機能には、たとえば以下のようなものがあります。

- Webサービスの非同期呼び出しとそのコールバック
- 非同期コールバックにおける相関関係の維持
- 複数のWebサービスの並列呼び出し
- エラー発生時の処理の処理の取消し(補償トランザクション)
- 小さなビジネス・プロセスをもとにした、より大きなビジネス・プロセスの構築

こういった機能を手作業で毎回プログラム的に実装していくよりは、ビジネス・プロセス定義言語で宣言的に定義してしまった方が、明らかに効率的ですね。BPELのようなビジネス・プロセス定義言語は、こういったニーズのもとに登場しました。

Webサービスのためのビジネス・プロセス定義言語に対する初期の取り組みとしては、MicrosoftのXLANGやIBMのWSFL(Web Services Flow Language)などのベンダ独自仕様がありました。その後、2002年8月に、IBM、Microsoft、BEAによって、XLANGとWSFLを統合する形でBPEL(Business Process Execution Language for Web Services) 1.0が公開されました。

現在では、2003年3月に公開されたBPEL 1.1をベースに、OASISのWeb Services Business Process Execution Language Technical Committee(WSBPEL TC)でBPELの標準化作業が進行中です。OracleもこのWSBPEL TCに参加しており、BPELの標準化作業に貢献しています。

 BPEL 1.1
http://dev2dev.bea.com/technologies/webservices/BPEL4WS.jsp
http://www-106.ibm.com/developerworks/webservices/library/ws-bpel/
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbiz2k2/html/BPEL1-1.asp

ここで、再度BPELとは何か考えてみましょう。BPELは、一言で言えば、Webサービスのためのビジネス・プロセス定義言語です。まぁ、悪く言ってしまえば、旧来のワークフロー・システムやプロプライエタリなEAI/BPMシステムにおけるプロセス定義を、Webサービスに対応させて焼き直しただけ、と見ることもできます。とはいえ、ビジネス・プロセス定義に必要な機能として上に挙げたものはすべてサポートおり、十分成熟した機能を備えていること、これまでプロプライエタリ(ベンダ独自)だったプロセス定義が標準化されることなどを考えれば、BPELは非常に価値のあるものだと思います。

OASISにおける標準化の動向や(Oracleを含む)メジャーなITベンダのサポート動向を見た限りでは、BPELは、SOA(サービス指向アーキテクチャ)の基礎を支える仕様として今後広く普及していくものと考えられるでしょう。


 Oracle BPEL Process Manager

Oracleは、BPELプロセスの実行環境 "Oracle BPEL Process Manager" と、BPELプロセスのビジュアル開発環境 "Oracle BPEL Designer" を提供しています。本稿執筆時点では残念ながら日本語の資料は準備できていませんが、OTNでは英語の資料を数多く公開しています。Oracle BPEL Process ManagerとOracle BPEL Designerも、このページから無償でダウンロードできます。

 OTN > Oracle BPEL Process Manager
http://www.oracle.com/technetwork/middleware/bpel/overview/index.html

BPELプロセス・エンジンであるOracle BPEL Process Managerは、J2EEアプリケーションとして実装されており、技術的には任意のJ2EEコンテナ上で動作します。OTNからダウンロードできるのは、OC4J、JBoss、WebLogic向けのOracle BPEL Process Managerです。

Oracle BPEL Process Managerは、完了してないビジネス・プロセスのステート情報を格納するため、リレーショナル・データベースを使用します。Oracle BPEL Process Managerをインストールすると、デフォルトでは軽量なデータベースOracle Liteを使う構成になっています。Oracle Liteも同時にインストールされるため、特に考えることなく使用を開始できます。なお、軽量なOracle Liteはあくまで開発環境向けの構成であり、本番環境ではOracle Databaseやその他のリレーショナル・データベースを使う構成にすることをお薦めします。

一方、Oracle BPEL Designerは、複雑なXMLであるBPELを直接編集することなく、ビジュアルにBPELプロセスを開発できる開発環境です。本稿執筆時点では、オープンソースのIDEであるEclipse 3.0のプラグインとして動作します。なお、OracleのJava IDEであるOracle JDeveloper 10g上で動作するOracle BPEL Designerも今後提供する予定になっています。

もしご興味がある場合は、Oracle BPEL Process ManagerとOracle BPEL Designerをインストールし、次のページにあるチュートリアル(BPEL Tutorials)に沿って一通り手順を追ってみることをお薦めします。チュートリアルは、最初のいくつかをやってみるだけでも勉強になると思いますので、是非お試しください。

 OTN > Oracle BPEL Process Manager > BPEL Developer Support
http://www.oracle.com/technetwork/middleware/ias/dev-support-098317.html


 初めてのBPELプロセス

ここでは、例としてOracle BPEL Designerで作成した、非常に簡単なBPELプロセスを見ていきます。その詳細な手順は説明しませんが、一度チュートリアルで手順を追ってみれば、簡単に分かると思います。(どうしても分からない場合は、 OTN Japan掲示版の「Webサービスの部屋」で聞いてみてください。)

今回は、BPELプロセスから呼び出すWebサービスとして、XMethodsで提供されている"Currency Exchange Rate"(為替レート)サービスを使用します。

 XMethods
http://www.xmethods.com/
 XMethods > XMethods Demo Services > Currency Exchange Rate
http://www.xmethods.com/ve2/ViewListing.po?key=uuid:D784C184-99B2-DA25-ED45-3665D11A12E5
 "Currency Exchange Rate"サービスのWSDL
http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl

Webサービスの説明やWSDLを読めば分かると思いますが、このサービスは、string型の2つの入力パラメータとして国名を取り、その2国の通貨間の為替レートをfloat型で返すRPC/エンコード・スタイルのWebサービスです。WSDLを読み解く方法については、本連載の前回までの内容をご確認ください。

.....
<definitions name="CurrencyExchangeService" .....>

  <message name="getRateRequest">
    <part name="country1" type="xsd:string"/>
    <part name="country2" type="xsd:string"/>
  </message>

  <message name="getRateResponse">
    <part name="Result" type="xsd:float"/>
  </message>

  <portType name="CurrencyExchangePortType">
    <operation name="getRate">
      <input message="tns:getRateRequest" />
      <output message="tns:getRateResponse" />
    </operation>
  </portType>

  <binding .....>
    .....
  </binding>

  <service .....>
    .....
  </service>

</definitions>

今回作成するBPELサービスは、以下のような極めてシンプルなプロセスを持つ為替計算サービスです。

(1) USドルでの金額をfloat型の数値として取る
(2) "Currency Exchange Rate"サービスを呼び出して、USドル-日本円の為替レートを取得
(3) 日本円での金額をint型の数値として返す

   

それでは、Oracle BPEL Designerを使って作成したBPELサービスの実体を解剖してみましょう。

BPELサービス自体、外部から見れば1つのWebサービスなので、BPELサービスを記述するWSDLがあります。今回作成した為替計算サービスのWSDL CurrencyCalc.wsdlを見てみます(コメントを削除し、インデントを修正しています)。

<definitions name="CurrencyCalc"
             targetNamespace="http://otn.oracle.co.jp/CurrencyCalc"
             xmlns:tns="http://otn.oracle.co.jp/CurrencyCalc"
             xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
>

  <types>
    <schema attributeFormDefault="qualified"
            elementFormDefault="qualified" 
            targetNamespace="http://otn.oracle.co.jp/CurrencyCalc" 
            xmlns="http://www.w3.org/2001/XMLSchema">

      <element name="CurrencyCalcRequest">
        <complexType>
          <sequence>
            <element name="PriceInUsd" type="float"/>
          </sequence>
        </complexType>
      </element>

      <element name="CurrencyCalcResponse">
        <complexType>
          <sequence>
            <element name="PriceInYen" type="int"/>
          </sequence>
        </complexType>
      </element>
    </schema>
  </types>

  <message name="CurrencyCalcRequestMessage">
    <part name="payload" element="tns:CurrencyCalcRequest"/>
  </message>

  <message name="CurrencyCalcResponseMessage">
    <part name="payload" element="tns:CurrencyCalcResponse"/>
  </message>

  <portType name="CurrencyCalc">
    <operation name="process">
      <input  message="tns:CurrencyCalcRequestMessage" />
      <output message="tns:CurrencyCalcResponseMessage"/>
    </operation>
  </portType>

  <plnk:partnerLinkType name="CurrencyCalc">
    <plnk:role name="CurrencyCalcProvider">
      <plnk:portType name="tns:CurrencyCalc"/>
    </plnk:role>
  </plnk:partnerLinkType>

</definitions>

本連載の前回までをお読みの方はお分かりいただけると思いますが、これはまさにWSDLの抽象定義の部分に相当します。<message>要素の子要素である<part>要素がtype属性ではなくelement属性を持っていることから、このWSDLは、RPCスタイルではなくドキュメント・スタイルであることも分かりますね。

<plnk:partnerLinkType>要素については次回以降取り上げていこうと思っていますので、ここでは説明を割愛します。WSDLとBPELを結び付ける重要な定義だ、という程度に考えておいてください。

続いて、為替計算サービスのBPELプロセス定義を表すCurrencyCalc.bpelを見てみましょう(コメントを削除し、インデントを修正しています)。

<process name="CurrencyCalc" 
         targetNamespace="http://otn.oracle.co.jp/CurrencyCalc" 
         suppressJoinFailure="yes" 
         xmlns:tns="http://otn.oracle.co.jp/CurrencyCalc" 
         xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/" 
         xmlns:bpelx="http://schemas.oracle.com/bpel/extension" 
         xmlns:ora="http://schemas.oracle.com/xpath/extension" 
         xmlns:CurrencyExchangeService=
"http://www.xmethods.net/sd/CurrencyExchangeService.wsdl" 
         xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
>

  <partnerLinks>
    <partnerLink name="client" 
                 partnerLinkType="tns:CurrencyCalc" 
                 myRole="CurrencyCalcProvider"
    />
    <partnerLink name="partnerLink0" 
                 partnerLinkType="CurrencyExchangeService:CurrencyExchangePortTypeLink" 
                 partnerRole="CurrencyExchangePortTypeProvider"
    />
  </partnerLinks>

  <variables>
    <variable name="input" messageType="tns:CurrencyCalcRequestMessage"/>
    <variable name="output" messageType="tns:CurrencyCalcResponseMessage"/>
    <variable name="rateInput" messageType="CurrencyExchangeService:getRateRequest"/>
    <variable name="rateOutput" messageType="CurrencyExchangeService:getRateResponse"/>
  </variables>

  <sequence name="main">

    <receive name="receiveInput" 
             partnerLink="client" 
             portType="tns:CurrencyCalc" 
             operation="process" 
             variable="input" 
             createInstance="yes"
    />

    <assign name="assign-1">
      <copy>
        <from expression="&quot;US&quot;"></from>
        <to variable="rateInput" part="country1"/>
      </copy>

      <copy>
        <from expression="&quot;Japan&quot;"></from>
        <to variable="rateInput" part="country2"/>
      </copy>
    </assign>

    <invoke name="invoke-1" 
            partnerLink="partnerLink0" 
            portType="CurrencyExchangeService:CurrencyExchangePortType" 
            operation="getRate" 
            inputVariable="rateInput" 
            outputVariable="rateOutput"
    />

    <assign name="assign-2">
      <copy>
        <from expression="round(bpws:getVariableData(&quot;rateOutput&quot;,
                          &quot;Result&quot;) *
                          bpws:getVariableData(&quot;input&quot;,
                          &quot;payload&quot;,
                          &quot;/tns:CurrencyCalcRequest/tns:PriceInUsd&quot;))">
        </from>
        <to variable="output" part="payload"
 query="/tns:CurrencyCalcResponse/tns:PriceInYen"/>
      </copy>
    </assign>

    <reply name="replyOutput" 
           partnerLink="client" 
           portType="tns:CurrencyCalc" 
           operation="process"
           variable="output"
     />
  </sequence>
</process>

BPELプロセスのルート要素は、<process>要素です。<process>要素内で最初に登場する<partnerLinks>についても、次回以降取り上げるので、読み流しておいてください。

次の<variables>要素には、BPELプロセス内で使用するXML形式の変数が、<variable>要素で定義されています。各<variable>要素は、BPELプロセスのWSDLや"Currency Exchange Rate"サービスのWSDLで定義済みの<message>要素を参照していることを確認しておきましょう。

次の<sequence>要素が、実際のプロセス定義に相当します。<sequence>要素の中には、順番に<receive>、<assign>、<invoke>、<assign>、<reply>という要素が登場しています。

最初の<receive>要素は、BPELプロセスのクライアントからのBPELプロセスの同期型呼び出し(リクエスト)を表しています。そして、最後の<reply>要素が、BPELプロセスのクライアントへのレスポンスになります。

中央の<invoke>要素は、外部の"Currency Exchange Rate"サービスの呼び出しになります。その前後の<assign>要素は、変数の代入処理になります。

1つめの<assign>要素は、"Currency Exchange Rate"サービスの入力パラメータであるrateInput変数に固定的に"US"、"Japan"という文字列を代入しています。

    <assign name="assign-1">
      <copy>
        <from expression="&quot;US&quot;"></from>
        <to variable="rateInput" part="country1"/>
      </copy>

      <copy>
        <from expression="&quot;Japan&quot;"></from>
        <to variable="rateInput" part="country2"/>
      </copy>
    </assign>

1つめの<assign>要素は、&quot;が頻出していて読みづらくなっていますが、<from>要素のexpression属性には、実際には次の値が入っています。これは、為替レート("Currency Exchange Rate"サービスの出力)にUSドルでの金額(BPELプロセスの入力)を掛け合わせ、整数値に四捨五入しています。BPEL変数へのアクセスにはBPELのgetVariableData()関数を、四捨五入にはXPath 1.0のround()関数を使っています。

round(
  bpws:getVariableData("rateOutput", "Result") 
  * 
  bpws:getVariableData("input","payload",
"/tns:CurrencyCalcRequest/tns:PriceInUsd")
)


<sequence>要素の中の一連の要素は、クライアントからの入力を受付け、"Currency Exchange Rate"サービスを呼び出すための変数を準備し、実際に"Currency Exchange Rate"サービスを呼び出し、その結果をもとにクライアントに返す結果を計算し、実際にクライアントに結果を返すという、一連のプロセスに1対1に対応していることがお分かりいただけると思います。

BPELプロセスの定義の実体がどのようなXMLなのか、感覚はつかめたでしょうか?


では、このBPELプロセスをBPELプロセス・エンジンにデプロイし、クライアントからアクセスしてみましょう。Oracle BPEL Designerからは、ワンクリックで簡単にOracle BPEL Process Managerにデプロイができます。そして、デプロイ済みのBPELプロセスの管理やテストには、Oracle BPEL Process Managerに付属の管理ツールOracle BPEL Consoleを使うことができます。以下の画面は、BPELプロセスに入力として、12.34USドルを渡して実行し、結果をして1268円を取得した様子を示しています。

   
   

実行結果の画面から"Visual Flow"、"Audit Instance"、"Debug Instance"へのリンクを辿ると、このBPELプロセスの実行に関するさまざまな情報を参照できます。次の画面は、"Visual Flow"から"Currency Exchange Rate"サービスの呼び出しを確認してみた様子です。BPELプロセスで定義した通り"US"、"Japan"という文字列を渡し、結果として"102.72"という数値を取得していることが分かりますね。そして、"round(102.72 * 12.34)"の計算結果は、確かに"1268"になります。

   

次の図に、実際にWebサービスを介してやり取りされているXMLメッセージを示しました(簡単のため、名前空間などは省略しています)。


BPELプロセスの実行時の流れがどのようなものか、感覚はつかめたでしょうか?


 おわりに

今回は、BPELの概要を説明し、実際のBPELプロセス定義を概観してみました。今回ご紹介したBPELプロセスは、単に1つのWebサービスを呼び出すだけの非常にシンプルなものでしたが、BPELには、並列呼び出し、条件分岐、相関、フォルト処理、補償 (コンペンセーション) 処理など、多様なプロセスフローを定義できる表現力があります。

次回は、パートナーリンクや同期/非同期など、BPELに関する興味深いトピックをいくつかご紹介しようと思っています。

[リファレンス]
 OTN > Oracle BPEL Process Manager
http://www.oracle.com/technetwork/middleware/bpel/overview/index-092538.html
 OASIS Web Services Business Process Execution Language Technical Committee(WSBPEL TC)
http://www.oasis-open.org/committees/wsbpel/
 BPEL 1.1
http://dev2dev.bea.com/technologies/webservices/BPEL4WS.jsp
http://www-106.ibm.com/developerworks/webservices/library/ws-bpel/
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbiz2k2/html/BPEL1-1.asp
 XLANG
http://www.gotdotnet.com/team/xml_wsspecs/xlang-c/
 WSFL
http://www-3.ibm.com/software/solutions/webservices/pdf/WSFL.pdf
 XMethods
http://www.xmethods.com/