この章では、BPELプロセス・サービス・コンポーネントでの条件分岐の使用方法について説明します。条件分岐により、BPELプロセス・サービス・コンポーネントの実行フローを制御するための判断ができるようになります。
項目は次のとおりです。
SOAコンポジット・アプリケーションでの条件分岐の作成方法の詳細は、『Oracle Fusion Middleware Oracle SOA Suiteアプリケーションの作成および実行のためのチュートリアル』を参照してください。
BPELは、条件分岐によって選択するロジックを利用します。次のいずれかのアクティビティを使用すると、条件分岐に基づいて異なるアクションを選択するコードを設計できます。
switchアクティビティ
2つ以上のブランチを設定できます。各ブランチにはXPath式の形式を使用します。式がtrueの場合、そのブランチが実行されます。式がfalseの場合、BPELプロセス・サービス・コンポーネントは有効なブランチ条件が見つかるか、otherwiseブランチに達するか、ブランチがなくなるまで次のブランチ条件に進みます。 複数のブランチ条件がtrueの場合は、最初にtrueと判断されたブランチがBPELにより実行されます。 switchアクティビティの作成方法については、第11.2項「switchアクティビティの作成による条件分岐の定義」で説明します。
whileアクティビティ
2つのアクション間で選択を実行するwhileループを作成できます。 whileアクティビティの作成方法については、第11.3項「whileアクティビティの作成による条件分岐の定義」で説明します。
多数のブランチが設定され、各ブランチにはXPath式形式の条件が指定されます。
条件分岐には、タイムアウトを設定できます。 つまり、指定の期間内にレスポンスを生成できない場合、BPELフローは待機を中止し、そのアクティビティを再開できます。 この機能の詳細は、第14章「BPELプロセスでのイベントおよびタイムアウトの使用」で説明します。
2社からの融資提案が同時に収集されるBPELプロセス・サービス・コンポーネントのflowアクティビティを設計し、ここではいずれの条件も比較されていないと仮定します。各条件は、それぞれのグローバル変数に格納されています。 2つの提案を比較し、その比較に基づいて決定するには、switchアクティビティを使用できます。
図11-1に、switchアクティビティに定義されたBPEL条件分岐プロセスの概観を示します。
switchアクティビティを作成する手順は、次のとおりです。
「コンポーネント・パレット」から、デザイナにswitchアクティビティをドラッグします。
+記号をクリックし、図11-2のようにswitchアクティビティを開きます。
switchアクティビティにはデフォルトで2つのswitch caseブランチがあり、各ブランチには機能要素を挿入するためのボックスがあります。ブランチを追加するには、switchアクティビティ全体を選択して右クリックし、メニューから「Switch Caseの追加」を選択します。
最初のブランチを右クリックして、メニューから「編集」を選択します。
「Switch Case」ダイアログが表示されます。
「式」フィールドで、[Ctrl]キーを押しながら[Space]キーを押してXPathブール式を入力し、XPathビルディング・アシスタントを起動します。 例11-1に詳細を示します。
この式は1行で入力します。XPath式ビルダーを使用するには、「式」フィールドの上にある「XPath式ビルダー」アイコンをクリックします。
この例では、融資企業からの完成した2つの融資提案は、グローバル変数loanOffer1
およびloanOffer2
に格納されます。それぞれの融資提案変数には、融資提案のAPRが格納されます。BPELフローは、APRが最も低い融資を選択する必要があります。次のいずれかのswitchアクティビティを実行します。
flowアクティビティと同様に、switchアクティビティには複数のブランチがあります。 例11-2では、2つのブランチのみが設計完了後の.bpel
ファイルに表示されています。 最初のブランチは、United Loanという企業からの融資提案を選択するブランチであり、XPathブール式を含むcase条件が適合した場合に実行されます。 適合しなかった場合は、Star Loanという企業からの融資提案を選択する2番目のブランチが実行されます。デフォルトでは、switchアクティビティに含まれるswitch caseは2つですが、必要に応じて追加できます。
例11-2 switchアクティビティ
<switch name="switch-1"> <case condition="bpws:getVariableData('loanOffer1','payload', '/autoloan:loanOffer/autoloan:APR') < bpws:getVariableData('loanOffer2','payload','/autoloan:loanOffer/autoloan:APR ')"> <assign name="selectUnitedLoan"> <copy> <from variable="loanOffer1" part="payload"> </from> <to variable="selectedLoanOffer" part="payload"/> </copy> </assign> </case> <otherwise> <assign name="selectStarLoan"> <copy> <from variable="loanOffer2" part="payload"> </from> <to variable="selectedLoanOffer" part="payload"/> </copy> </assign> </otherwise> </switch>
複数のアクション間で選択を行うようにBPELコードを設計する別の方法としては、whileアクティビティを使用したwhileループの作成があります。whileループは、指定の条件が適合するまで、アクティビティを繰り返します。たとえば、重要なWebサービスでリクエストに対してサービス・ビジー・メッセージを返している場合、そのサービスが使用可能になるまで、whileアクティビティを使用してポーリングし続けることができます。このときのwhileアクティビティの条件はサービスから受け取った最新のメッセージがビジーであることで、whileアクティビティ内の操作はサービスを再チェックすることです。Webサービスからサービス・ビジー以外のメッセージが戻ると、whileアクティビティは終了し、理想的にはWebサービスからの有効なレスポンスを使用して、BPELプロセス・サービス・コンポーンネントが続行されます。
whileアクティビティを作成する手順は、次のとおりです。
「コンポーネント・パレット」から、デザイナにwhileアクティビティをドラッグします。
+記号をクリックしてwhileアクティビティを開きます。
whileアクティビティには、条件式を作成するアイコンとwhile定義を検証するアイコンがあります。 また、アクティビティをドラッグしてwhileループを定義する領域も用意されています。図11-3に例を示します。
while条件を使用するための追加のアクティビティ(scopeアクティビティなど)をwhileアクティビティの「アクティビティをここにドロップ」領域にドラッグして定義します。
このアクティビティとして、既存のアクティビティや新しいアクティビティを使用できます。
[Ctrl]キーを押しながら[Space]キーを押してXPathビルディング・アシスタントを起動するか、「XPath式ビルダー」アイコンをクリックして「式ビルダー」ダイアログを開きます。
図11-4に示すように、繰り返し実行する式を入力します。 このアクションは、指定したwhile条件のブール値がtrueでなくなるまで実行されます。 この例のアクティビティは、5
未満の場合に繰り返しループするように設定されています。
完了後に「OK」をクリックします。
例11-3に、設計完了後の.bpel
ファイルの例を示します。 whileアクティビティ内にscopeアクティビティがあります。 scopeアクティビティ内にはinvoke、assignおよびwaitアクティビティがあります。 データベース例外処理タスクは、ローカル変数を作成してscopeアクティビティ内にinvokeアクティビティを配置することで実行されます。 ローカル変数はfalseに設定されます(0で表されます)。 ローカル変数の条件が満たされる(1に設定される)まで、whileループ・アクティビティで外部パートナ・サービスのコールを試行します。 whileアクティビティは、最大5回ループするように設定されています。 例外の場合は、フラグをfalse(0)にリセットします。
例11-3 whileアクティビティ
<while name="While_1" condition="bpws:getVariableData('dbStatus') > 5"> <scope name="Scope_1"> <faultHandlers> <catchAll> <sequence name="Sequence_2"> <assign name="assign_DB_retry"> <copy> <from expression="bpws:getVariableData('dbStatus') + 1"/> <to variable="dbStatus"/> </copy> </assign> <wait name="Wait_30_sec" for="'PT31S'"/> </sequence> </catchAll> </faultHandlers> <sequence name="Sequence_1"> <invoke name="Write_DBWrite" partnerLink="WriteDBRecord" portType="ns2:WriteDBRecord_ptt" operation="insert" inputVariable="Invoke_DBWrite_merge_InputVariable"/> <assign name="Assign_dbComplete"> <copy> <from expression="'10'"/> <to variable="dbStatus"/> </copy> </assign> </sequence> </scope> </while>