パラレル・フローを使用すると、BPELプロセスは同時に複数のタスクを実行できます。これは、時間のかかる独立した複数のタスクを実行する必要がある場合に、特に役立ちます。
この章の内容は次のとおりです。
第5章「非同期Webサービスの起動」では、United Loanサービスの非同期Webサービスをコールする方法について習得しました。United Loanサービスから融資提案が返るまでに数日かかることがあるため、Star Loanから別の融資提案を収集する必要があるというケースでは、両方のタスクが並列して実行されるようにBPELプロセスを定義できます。
このユースケースでは、融資サービスへの2つの非同期コールバックを並列に実行するBPELフローのプログラミング方法を示します。
関連項目: 次のサンプルを参照してください。
|
BPELプロセスでは、複数の非同期ソースからの情報の収集が必要になる場合があります。各コールバックに要する時間(時間数または日数)は明らかでないため、各サービスを一度に1つずつコールするのでは時間がかかりすぎることがあります。コールをパラレル・フローに分解することにより、BPELプロセスは複数のWebサービスを一度に起動し、レスポンスが到着するたびに受け取ることができます。この方法は時間の節約に効果的です。
図6-1に、異なる2つのWebサービスからの融資提案を取得するパラレル・フローを実行するBPELプロセスの概要を示します。ここでは、2つの非同期コールバックがパラレルに実行されるため、1つのコールバックはもう1つのコールバックが先に完了するまで待機する必要がありません。各レスポンスは異なるグローバル変数に格納されます。
通常、flow
アクティビティにはいくつかのsequence
アクティビティが含まれ、各sequenceはパラレルに実行されます。flow
アクティビティには、その他のアクティビティも含めることができます(ただし、この例では含めていません)。たとえば、次のようになります。
<flow name="flow-1"> <sequence> <scope name="UnitedLoan"> <sequence> <invoke name="invoke-2" partnerLink="unitedLoan" portType="services:LoanService" operation="initiate" inputVariable="loanApplication"/> <receive createInstance="no" name="receive-1" partnerLink="unitedLoan" portType="services:LoanServiceCallback" operation="onResult" variable="loanOffer1"/> </sequence> </scope> </sequence> <sequence> <scope name="StarLoan"> <sequence> <invoke name="invoke-1" partnerLink="StarLoan" portType="services:LoanService" operation="initiate" inputVariable="loanApplication"/> <pick name="pick-1">. . . </pick> </sequence> </scope> </sequence> </flow>
この例には2つのsequenceがありますが、flowアクティビティには多数のsequenceを含めることができます。
次に、flowアクティビティとrequest
という名前のグローバル入力変数を作成する方法について説明します。このアクティビティは、融資提案Webサービス(United Loan)を使用する非同期のBPELプロセス・アクティビティを開始します。融資提案サービスは、request入力変数を使用して、クライアントからの融資申請を受け取ります。
この例では、Oracle JDeveloperでのflowアクティビティの作成方法を示します。
flowアクティビティをscopeアクティビティにドラッグ・アンド・ドロップします。
「+」記号をクリックしてflowアクティビティを開きます。
scopeアクティビティは、1単位として処理する複数アクティビティのグループを入れるコンテナです。「scopeアクティビティによるアクティビティ・グループの管理」では、scopeアクティビティについて詳細に説明しています。
flowアクティビティには、それぞれ機能要素用のボックスを持つ2つのブランチがあります。これらのボックスにデータを移入するため、scopeアクティビティの場合と同様に、機能を作成するか、「プロセス・アクティビティ」リストからアクティビティをボックスまでドラッグします。
この時点で、複数のサービスを同時に起動するために、フローの左右に複数のアクティビティをドラッグ・アンド・ドロップできます。
関連項目: Oracle JDeveloperでのflowアクティビティの作成例は、次のドキュメントを参照してください。 |
flowアクティビティでは、BPELコードによってパラレル・ブランチの数が決定されます。なお、必要なブランチの数は、しばしば、使用可能な情報に応じて異なります。flowNアクティビティは、N
の値に等しい複数のフローを作成します。この値は、使用可能なデータおよびプロセス内のロジックに基づいて実行時に定義されます。索引変数は、N
の値に到達するまで、新しいブランチが作成されるたびに増分されます。
flowNアクティビティは、任意の数のデータ要素に対してアクティビティを実行します。要素の数の変化に応じて、BPELプロセスは適切に調整を行います。
flowNで作成される各ブランチは、同じアクティビティを実行しますが、異なるデータを使用します。各ブランチは、索引変数を使用して入力変数を参照します。入力変数をXPath式で使用すると、そのブランチに固有のデータを取得できます。
たとえば、データの配列があるとします。BPELプロセスは、count
関数を使用して配列内の要素の数を判断します。次に、N
が要素の数に設定されます。索引変数は、事前に設定された値(デフォルトはゼロ)で始まります。flowNは、ブランチを作成し、配列の各要素を取得して、その要素に含まれるデータを使用してアクティビティを実行します。これらのブランチは、初期索引値とN
の間のすべての値を使用して、パラレルに生成および実行されます。flowNは、索引変数がN
の値に到達すると終了します。たとえば、配列に3
つの要素が含まれている場合、N
は3
に設定されます。索引変数が1で始まるとすると、flowNアクティビティは索引1、2および3を使用して3つのパラレル・ブランチを作成します。
flowNアクティビティは、Webサービスから取得したデータなど、他のソースのデータを使用できます。
次の図に、3つのホテルを参照するflowNアクティビティのOracle BPEL Controlビューを示します。Oracle BPEL Controlビューは、BPELプロセスを示すのではなく、プロセスが実際に実行された方法を示しているのみであり、ビューそのものではありません。この例では、3つのホテルがありますが、ブランチの数は使用可能なホテルの数に応じて異なります。
次の図に、flowNアクティビティのOracle JDeveloperでの表示を示します。
flowNのウィンドウを図6-4に示します。このウィンドウは、flowNアクティビティをダブルクリックすると表示されます。
flowNウィンドウでは、flowNアクティビティ名の設定、N
の値の計算式の入力および索引変数の定義が可能です。
次のコードは、.bpel
ファイルに含まれる参照実装であり、flowN
アクティビティを使用して任意の数のホテルに関する情報を参照します。次のアクションを行います。
まず、sequence
に名前を付けます。
<sequence name="main"> <!-- Received input from requestor. Note: This maps to operation defined in NflowHotels.wsdl The requestor send a set of hotels names wrapped into the "inputVariable" -->
receive
アクティビティは、クライアント・パートナ・リンクをコールして、flowN
アクティビティがN
を定義してホテル情報を参照するために必要な情報を取得します。
<receive name="receiveInput" partnerLink="client" portType="client:NflowHotels" operation="initiate" variable="inputVariable" createInstance="yes"/> <!-- The 'count()' Xpath function is used to get the number of hotelName noded passed in. For lisibility, an intermediate varaible called "NbParallelFlow" is used to store the number of N flows being executed --> <assign name="getHotelsN"> <copy> <from expression="count(bpws:getVariableData('inputVariable','payload','/client:Nflow HotelsProcessRequest/client:ListOfHotels/client:HotelName'));"/> <to variable="NbParallelFlow"/> </copy> </assign> <!-- Initiating the FlowN activity The N value is initialized with the value stored in the "NbParallelFlow" variable The variable call "Index" is defined as the index variable NOTE: Both "NbParallelFlow" and "Index" variables have to be declared -->
次に、flowN
アクティビティについて説明します。flowN
のアクティビティの名前を定義した後、N
をinputVariable
(ホテル・エントリの数)の値として定義します。また、このアクティビティでは、索引変数としてindex
を割り当てます。
<bpelx:flowN name="FlowN" N="bpws:getVariableData('NbParallelFlow')" indexVariable="Index">
<sequence name="Sequence_1">
<!-- Fetching each hotelName by indexing the "inputVariable" with the
"Index" variable.
Note the usage of the "concat()" Xpath function to create the
expression accessing the array element.
-->
次に、各ホテル・エントリをリストとして連結するため、次のコピー・ルールでは索引変数を使用しています。
<assign name="setHotelId"> <copy> <from expression= "bpws:getVariableData('inputVariable','payload',concat('/client:Nflo wHotelsProcessRequest/client:ListOfHotels/client:HotelName[', bpws:getVariableData('Index'),']'))"/> <to variable="InvokeHotelDetailInputVariable" part="payload" query="/ns2:hotelInfoRequest/ns2:id"/> </copy> </assign>
このホテル情報を使用して、invoke
アクティビティは、Webサービスから各ホテルの詳細情報を参照します。
<!-- For each hotel, invoke the Web service giving detailed information on the hotel --> <invoke name="InvokeHotelDetail" partnerLink="getHotelDetail" portType="ns2:getHotelDetail" operation="process" inputVariable="InvokeHotelDetailInputVariable" outputVariable="InvokeHotelDetailOutputVariable"/> <!-- This procees doesn't do anything with the retrieved inforamtion. In the real life, it could be then used to continue the process. Note: Meanwhile an indexing variable is used, unlike a while loop, the activities a executed in parallel, not sequentially. --> </sequence> </bpelx:flowN>
最後に、BPELプロセスは、各ホテルの詳細情報をクライアント・パートナ・リンクに送信します。
<invoke name="callbackClient" partnerLink="client" portType="client:NflowHotelsCallback" operation="onResult" inputVariable="outputVariable"/> </sequence> </sequence>
この章では、flowアクティビティを使用してパラレル・フローを作成し、複数のタスクを同時に実行する方法について説明しました。このBPELプロセスは2つの非同期コールバックをパラレルに実行しました。これにより、2つのコールバックを連続して実行する場合に比べ、大幅に時間を短縮できました。また、flowNアクティビティという別のアクティビティにより、Oracle BPEL Process Managerでは、データを使用して必要な数のパラレル・フローを実行時に生成でき、複数のデータ要素に対して同じアクティビティを実行できます。このため、BPELプロセスで使用可能な情報が異なると、プロセスの動作も異なってきます。