この章では、イベントおよびタイムアウトの使用方法について説明します。Webサービスはレスポンスを返すまでに長時間かかる場合があるため、BPELプロセス・サービス・コンポーネントでは一定の時間が経過した後、タイムアウトしてフローの残りを継続できることが必要です。
項目は次のとおりです。
この章では、融資提案を提供するStar LoanというWebサービスからのレスポンスを1分間待機するBPELプロセス・サービス・コンポーネントのプログラミング例を説明します。Star Loanが1分以内にレスポンスを返さない場合、BPELプロセス・サービス・コンポーネントはUnited Loanという別のWebサービスからの融資提案を自動的に選択します。現実的には、時間の制限は48時間など1分より大きな値です。しかし、この例では、BPELプロセス・サービス・コンポーネントが正しく動作しているかどうかを確認するために、そのような長時間の待機は設定しません。
非同期Webサービスはレスポンスを返すまでに長時間かかる場合があるため、BPELプロセス・サービス・コンポーネントでは一定の時間が経過した後、タイムアウトしてフローの残りを継続できることが必要です。
pickアクティビティを使用して、指定された時間待機するか、作業の実行を続行するようにBPELフローを構成できます。有効期限を設定するには、waitアクティビティを使用します。
pickアクティビティには2つのブランチがあり、それぞれに条件があります。最初に条件が満たされたブランチが実行されます。次の例では、1つのブランチの条件は融資提案を受け取ることで、もう1つのブランチの条件は指定の時間待機することです。
図14-1に概要を示します。(優先度に従って)次のアクティビティが発生します。
invokeアクティビティがサービス(この場合はStar Loanからの融資提案に対するリクエスト)を開始します。
次に、pickアクティビティが開始されます。これには次の条件があります。
onMessage
この条件には、Star Loan Webサービスからの融資提案の形式でリプライを受け取るためのコードが含まれています。onMessageコードは、タイムアウトが追加される前の、Star Loan Webサービスからのレスポンスを受け取るコードと一致します。
onAlarm
この条件には、1分のタイムアウトのコードが含まれています。この時間はPT1M
として定義されています。これは、タイムアウトまでに1分待機するという意味です。タイムアウト設定には、次の記号を使用します。
S
は秒
M
は分
H
は時間
D
は日
Y
は年
あまり一般的な例ではありませんが、時間制限が1
年3
日15
秒の場合は、PT1Y3D15S
と入力します。コードの残りの部分では、融資変数selectedおよびapprovedをfalse
に設定し、年率(APR)を0.0
に設定して、この情報をloanOffer
変数にコピーしています。
期間のフォーマットはBPEL標準によって指定されます。期間のフォーマットの詳細は、次の場所にある最新の「XML Schema Part 2: Datatypes」ドキュメントを参照してください。
http://www.w3.org/TR/xmlschema-2/#duration
最初に条件が満たされたpickアクティビティのブランチが、BPELプロセス・サービス・コンポーネントにより実行されます。他のブランチは実行されません。
onMessageブランチは、操作を受信するという点でreceiveアクティビティに似ています。ただし、類似したパートナ・リンクおよびポート・タイプを待機し、操作が異なる複数のonMessageブランチを持つpickアクティビティを定義できます。したがって、操作ごとに個別のスレッドおよびパラレル処理を起動できます。この点は、操作が1つのみのreceiveアクティビティとは異なります。もう1つの違いは、(「インスタンスの作成」チェック・ボックスを選択することで)receiveアクティビティを使用してビジネス・プロセスの新しいインスタンスを作成できますが、これをpickアクティビティで実行することはできません。
pickアクティビティを作成する手順は、次のとおりです。
SOAコンポジット・エディタで、BPELプロセス・サービス・コンポーネントをダブルクリックします。
「コンポーネント・パレット」で、「BPELコンストラクト」を展開します。
pickアクティビティをデザイナにドラッグします。
pickアクティビティにはonMessageブランチが含まれています。図14-2に例を示します。
onMessageブランチをダブルクリックします。図14-3に例を示します。
融資サービスからのレスポンスを受け取るように、その属性を編集します。
pickアクティビティを選択します。
onMessageブランチおよびOnAlarmブランチを追加するためのアイコンが表示されます。
図14-4に示すように、「OnAlarmの追加」をクリックします。
OnAlarmブランチが表示されます。
表示されたpickアクティビティのonAlarmブランチをダブルクリックし、時間制限を1
分に設定します。図14-5に例を示します。
「OK」をクリックします。
例14-1のコード・セグメントは、この操作のpick
アクティビティに対する設計完了後の定義を示しています。
例14-1 pickアクティビティ
<pick> <!-- receive the result of the remote process --> <onMessage partnerLink="LoanService" portType="services:LoanServiceCallback" operation="onResult" variable="loanOffer"> <assign> <copy> <from variable="loanOffer" part="payload"/> <to variable="output" part="payload"/> </copy> </assign> </onMessage> <!-- wait for one minute, then timesout --> <onAlarm for="PT1M"> <assign> <copy> <from> <loanOffer xmlns="http://www.autoloan.com/ns/autoloan"> <providerName>Expired</providerName> <selected type="boolean">false</selected> <approved type="boolean">false</approved> <APR type="double">0.0</APR> </loanOffer> </from> <to variable="loanOffer" part="payload"/> </copy> </assign> </onAlarm> </pick>
BPEL 2.0のOracle BPEL Process Managerの実装では、pickアクティビティの同時onMessageブランチはサポートされていません。
開始アクティビティとして(どちらも相関定義でinitiate
がjoin
に設定されている)2つのonMessageブランチと、起動を次々に転送する起動プロセスを持つpickアクティビティがプロセスにある場合、どちらの起動も、起動されたプロセスの同じインスタンスに到達すると想定されます。ただし、Oracle BPEL Process ManagerのBPEL 2.0の実装では、起動されたプロセスの2つのインスタンスは起動ごとに作成されます。
これは想定されている動作ですが、BPEL 2.0仕様に記載されているものとは異なります。
たとえば、同期BPELプロセスAがあり、2つのパラレル・ブランチを持つflowアクティビティがあると仮定します。
ブランチ1は、非同期BPELプロセスBで操作processMessage1を呼び出します。
ブランチ2は、非同期BPELプロセスBで操作processMessage2を起動します。起動は5秒間待機した後に行われます。その後、BPELプロセスAはBPELプロセスBからのコールバックで待機し、出力をクライアントに返します。
起動されたプロセスの1つのインスタンスを作成し、最初のインスタンスがアクティブで実行中の状態になった後、2番目の起動が行われるという考えです。
BPELプロセスBには、createInstance
がyes
に設定されたpickアクティビティがあります。pickアクティビティ内には2つのonMessageブランチがあります。
一方のブランチはprocessMessage1操作に使用されます。この操作では、約10秒間スリープ状態になります。
もう一方のブランチはprocessMessage2操作に使用されます。この操作では、5秒間待機します。
どちらの操作も入力メッセージ・タイプは同じであり、initiate
がjoin
に設定された相関が定義されています。processMessage1の起動がただちに行われ、BPELプロセスBインスタンスが作成されて10秒間スリープします。5秒後、起動プロセスはprocessMessage2の起動をBPELプロセスBに転送し、この起動は、新しいインスタンスを作成するのではなく既存のインスタンスに移動します(相関IDが同じでinitiate
がjoin
に設定されているため)。
ただし、起動ごとにBPELプロセスBの新しいインスタンスが作成され、結果は予測できません。
processMessage2操作のブランチが先に完了した場合、後続の割当て操作は失敗します。これは、processMessage1からの入力変数はnullと想定されるためです(そのインスタンスの場合)。
processMessage1操作のブランチが先に完了した場合、プロセスは一部の情報のみを含むコールバック・データを返します(processMessage2からの入力は含まれません)。
Oracle BPEL Process Managerの実装では、2つの操作(processMessage1またはprocessMessage2)のいずれかによって新しいインスタンスが作成されます。この実装により、すでに作成されたインスタンスがあるかどうかを確認するためにデータベース問合せを行う必要がなくなります。
この問題を解決するには、2つの異なる操作によって開始される2つのプロセスを作成します。
receiveアクティビティのリクエスト/レスポンス操作には、タイムアウトを指定できます。この機能は、パートナ・コールバックのタイムアウト期間を指定する際に使用するpickアクティビティのonMessageブランチとonAlarmブランチの代替手段として提供されています。
次の各項では、この機能の概要について説明します。
アクティビティの起動時からの相対的なタイムアウト設定
絶対的な日時でのタイムアウト設定
XPath式を使用して動的に計算されるタイムアウト設定
アクティビティ・タイムアウト時にスローされるbpelx:timeout
フォルト
アクティビティ・タイムアウト時にBPELインスタンス監査証跡に追加されるイベント
サーバー再起動時にリカバリ可能なタイムアウト・アクティビティ
注意: リクエスト/レスポンス操作のタイムアウト設定は、BPELバージョン2.0をサポートするBPELプロジェクトでは使用できません。 |
タイムアウト設定として、アクティビティの起動時からの相対的なタイムアウトを指定できます。この設定は、例14-2に示す構文を使用して相対的な期間として指定されます。
このタイプでは、bpelx:for
属性を使用して、XMLスキーマ・タイプ期間として評価される静的な値またはXPath式を指定します。アクティビティには、bpelx:for
属性またはbpelx:until
属性のいずれか一方のみを使用できます。
XPath式がマイナスの期間として評価された場合、タイムアウトは無視され、その期間の値が無効であることを示すインスタンス監査証跡にイベントが記録されます。
有効な期間の値が取得されると、アクティビティの有効期限は、現在のノード時間(そのノードが使用可能になってからのクラスタ時間)にその期間の値を加算した値に設定されます。たとえば、期間の値bpelx:for="'PT5M'"
は、アクティビティが実行開始後5分以内にインバウンド・メッセージの着信を予定していることを示します。
注意: 現在、pickアクティビティのonMessageブランチにはタイムアウト設定属性が適用されません。これは、pickアクティビティのonMessageブランチとonAlarmブランチを使用した同じ機能が存在しているためです。 |
タイムアウト期間は、次のアクティビティにのみ指定できます。
中間プロセスのreceiveアクティビティ
createInstance="true"
の指定がないreceiveアクティビティ
receiveアクティビティは、インスタンス化された後にのみタイムアウトします。receiveアクティビティのエントリではタイムアウトになりません。
タイムアウト設定は、リクエスト/レスポンスreceiveアクティビティの絶対的な期限として指定できます。このタイプでは、例14-3に示す構文を使用します。
bpelx:until
属性の予定有効期限は、現在時刻より少なくとも2秒後である必要があります。それ以外の場合は、タイマーが指定されていなかったかのように、タイマー・スケジュールを無視してスキップされます。
bpelx:until
属性には、datetime
またはdate
のXMLスキーマ・タイプとして評価される静的な値またはXPath式を指定します。アクティビティには、bpelx:for
属性またはbpelx:until
属性のいずれか一方のみを使用できます。
XPathバージョン1.0は、XMLスキーマに対応していません。したがって、XPathバージョン1.0の組込み関数では、dateTime
値やdate
値を作成したり、操作することはできません。ただし、次のいずれかを実行できます。
XMLスキーマ定義に準拠する定数(リテラル)の記述、および期限値としての使用
使用可能ないずれかのタイプの変数(パート)からのフィールドの抽出、および期限値としての使用
XPathバージョン1.0では、リテラルが文字列リテラルとして処理されますが、結果はdateTime
値またはdate
値の字句表記として解釈されます。
有効なdatetime
値またはdate
値が取得されると、アクティビティの有効期限が指定の日付に設定されます。たとえば、bpelx:until="'2009-12-24T18:00+01:00'"
というdatetime
値は、アクティビティが実行開始以降、インバウンド・メッセージの着信を遅くとも2009年12月24日午後6時(UTC+1)以前に予定していることを示します。
注意: 現在、pickアクティビティのonMessageブランチにはタイムアウト設定属性が適用されません。これは、pickアクティビティのonMessageブランチとonAlarmブランチを使用した同じ機能が存在しているためです。 |
タイムアウト日付は、次のアクティビティにのみ指定できます。
中間プロセスのreceiveアクティビティ
createInstance="true"
の指定がないreceiveアクティビティ
receiveアクティビティは、インスタンス化された後にのみタイムアウトします。receiveアクティビティのエントリではタイムアウトになりません。
リクエスト/レスポンスreceiveアクティビティ、およびpickアクティビティのonMessageブランチに対するタイムアウト設定は、静的な期間またはdatetime
値を入力するかわりに、XPath式を使用して設定できます。この場合は、次のいずれかを式の値として返す必要があります。
XMLの静的な期間またはdatetime
値と解釈される文字列
XMLスキーマの期間またはdatetime
タイプ
例14-4に、XPath式を使用するための構文を示します。
例14-4 XPath式を使用して動的に計算されるタイムアウト設定
<bpelx:for="bpws:getVariableData('input', 'payload', '/tns:waitValue/tns:for')"/> <bpelx:until="bpws:getVariableData('input', 'payload', '/tns:waitValue/tns:until')"/>
返された式の値をXMLスキーマの期間またはdatetime
タイプと解釈できない場合は、無効な期間またはdatetime
の値が指定されたことを示すインスタンス監査証跡にイベントが記録され、アクティビティの有効期限は設定されません。
bpelx:for
またはbpelx:until
属性から、有効なXMLスキーマの期間またはdatetime
値が返された場合は、タイムアウトしたアクティビティからbpelx:timeout
フォルトがスローされます。このフォルトはcatchまたはcatchAllブロックによって捕捉され、通常のBPELフォルトと同様に処理されます。フォルトのメッセージはアクティビティの名前になります。また、タイムアウト期間より前に、想定したコールバック・メッセージの受信に失敗したためにアクティビティがタイムアウトしたことを示すインスタンス監査証跡にイベントが記録されます。
タイムアウト期間より前にアクティビティがパートナからコールバックを受信した場合、フォルトはスローされません。コールバックを受信したときにアクティビティがタイムアウトしていた場合、コールバック・メッセージはアクティビティに配信されず、配信メッセージ表に取消しのマークが設定されます。コールバック・メッセージの処理と同時にタイムアウト・アクションが試行された場合、そのタイムアウト・アクションは無視されます。11g リリース1現在、インスタンスはオプティミスティックにロックされます(リリース10gのペシミスティック・ロックとは対照的です)。したがって、行の第2のアクションがそのまま実行されます。ただし、インスタンス・バージョン・チェックは、インスタンスのデハイドレーションで失敗となります。
操作に対するフォルトがコンポーネントWSDLに宣言されている場合は、BPELコンポーネントからbpelx:timeout
フォルトをスローできます。操作に対するフォルトが宣言されていない場合、フォルトはFabricInvocationException
(実行時フォルト)に変換されます。このフォルトは、いずれかのコール元コンポーネント(BPELコンポーネントを含む)によって捕捉されますが、フォルトのタイプはbpelx:timeout
ではなくなります(ただし、フォルト・メッセージ文字列には、フォルトが当初はタイムアウト・フォルトであったことが記載されます)。
タイムアウトしたアクティビティからbpelx:timeout
フォルトがスローされると、想定したコールバック・メッセージをパートナから受信した場合とは対照的に、アクティビティがタイムアウトしたことを示すインスタンス監査証跡にイベントが記録されます。
有効なタイムアウトの期間またはdatetime
を指定するアクティビティは、基礎となる作業アイテム・オブジェクトの有効期限が設定されているwaitアクティビティおよびonAlarmアクティビティとほぼ同様の方法で実装されます。スケジューラを使用してこれらのアクティビティをスケジュールしたノードが(正常な停止または中途完了のいずれかで)停止した場合は、サーバー再起動時に、スケジューラを使用してこれらのアクティビティをすべて再スケジュールする必要があります。
ノードが停止した場合、これらのアクティビティをクラスタの単一のノード(マスター・ノード)で再スケジュールすることはできません。
receiveアクティビティのリクエスト/レスポンス操作にタイムアウトを設定する手順は、次のとおりです。
SOAコンポジット・エディタで、バージョン1.1のBPELプロセス・サービス・コンポーネントをダブルクリックします。
「コンポーネント・パレット」で、「BPELコンストラクト」を展開します。
receiveアクティビティをデザイナにドラッグします。
アクティビティを開きます。
「タイムアウト」タブをクリックします。
図14-6に示すように、このタブでリクエスト/レスポンス操作のタイムアウトを設定できます。
適切な値を指定し、「適用」をクリックします。例:
アクティビティの起動時からの相対的なタイムアウトを指定するには、「期間」ボタンをクリックして値を入力するか、「式」ボタンをクリックしてXPath式を指定します。
リクエスト/レスポンス操作の絶対的な期限としてタイムアウトを指定するには、「期限」ボタンをクリックして値を入力するか、「式」ボタンをクリックしてXPath式を指定します。
「適用」→「OK」の順にクリックします。
.bpel
ファイルのコード・セグメントは、特定の操作に対する設計完了後の定義を示しています。
たとえば、アクティビティが実行開始後5分以内にインバウンド・メッセージの着信を予定していることを指定した場合は、例14-5に示す構文が表示されます。
たとえば、アクティビティが実行開始以降、インバウンド・メッセージの着信を遅くとも2010年1月24日午前11時(UTC+1)以前に予定していることを指定した場合は、例14-6に示す構文が表示されます。
たとえば、アクティビティの起動時からの相対的なタイムアウトの値を取得するようにXPath式を指定した場合は、例14-7に示すような構文が表示されます。
waitアクティビティを使用すると、プロセスは指定された期間または時間制限に達するまで待機できます。有効期限条件を1つのみ指定する必要があります。このアクティビティの典型的な用途は、一定の時間に操作を起動することです。通常は、プロセスの状態に依存する式を入力します。
待機期間を指定する場合は、次の点に注意してください。
処理を必要とする他のイベントとともにスケジュールされている場合、待機期間は保証されません。この追加処理のために、実際の待機期間は、BPELプロセスに指定されている待機期間より長くなる可能性があります。
2秒未満の待機期間はサーバーから無視されます。2秒以上1分未満の待機期間は、正確な指定時間で実行されないことがあります。ただし、分単位の待機期間は指定時間で実行されます。
待機時間2
秒のデフォルト値は、Oracle Enterprise Manager Fusion Middleware ControlコンソールのシステムMBeanブラウザのMinBPELWaitプロパティで指定されます。このプロパティは任意の値に設定でき、MinBPELWait未満の待機の遅延は無視されます。
注意: waitアクティビティの期限切れイベントのスケジュールには、Quartzバージョン1.6がサポートされています。 |
BPELプロセスがデハイドレーションに関連して待機する最小期間を指定できます。待機期間が指定値以下の場合、BPELはアクティビティの実行を同じスレッドの同じトランザクションで続行します。
「SOAインフラストラクチャ」メニューから、「SOA管理」→「BPELプロパティ」の順に選択します。
「BPELサービス・エンジン・プロパティ」ページの下部で、「詳細BPEL構成プロパティ」をクリックします。
MinBPELWaitをクリックします。
「値」フィールドに値を秒単位で指定します。
「適用」をクリックします。
「戻る」をクリックします。
waitアクティビティを作成する手順は、次のとおりです。
「コンポーネント・パレット」で、「BPELコンストラクト」を展開します。
waitアクティビティをデザイナにドラッグします。
waitアクティビティをダブルクリックし、「Wait」ダイアログを表示します。
「期間」セクションに、待機する時間を入力します。
図14-7に示すように、「期限」セクションで、待機する期限を選択します。
指定されたイベントがメッセージの到着を待機するonEventブランチをscopeアクティビティ内に作成できます。たとえば、顧客のクレジット要求メッセージによって開始されるクレジット要求プロセスがあると仮定します。さらに顧客対応を行わなくても要求は完全に処理され、結果が顧客に送信されます。ただし、顧客がクレジット要求のステータスに関する問合せ、要求内容の変更、または処理中の要求の完全な取消を行う場合があります。このような顧客対応は、ビジネス・オーダー処理の特定の時点でのみ発生するとはかぎりません。onEventブランチなどのイベント・ハンドラを使用すると、ビジネス・プロセスでは、プライマリ・ビジネス・ロジック・フローに並行して到着する要求(ステータス要求、変更要求、取消要求など)を受け入れることができます。
onEventイベント・ハンドラは、内側に囲まれているスコープと関連付けられます。onEventイベント・ハンドラはスコープが初期化されると有効になり、スコープが終了すると無効になります。有効になると、いくつものイベントが発生する可能性があります。イベントは、スコープのプライマリ・アクティビティおよびイベント相互に並行して処理されます。メッセージ・イベントも、プロセスによって公開されるサービス操作を表し、onEvent要素としてモデル化されます。イベント・ハンドラは新しいプロセス・インスタンスを作成できません。したがって、メッセージ・イベントは常に、すでにアクティブなプロセス・インスタンスで受信されます。
scopeアクティビティでonEventブランチを作成する手順は、次のとおりです。
図14-8に示すように、開いた状態のscopeアクティビティで、「OnEventの追加」をクリックします。
これにより、OnEventブランチおよび内側に囲まれているscopeアクティビティが作成されます。
OnEventブランチをダブルクリックします。
図14-9に示すように、「OnEvent」ダイアログが表示されます。
「パートナ・リンク」フィールドで、「検索」アイコンをクリックして、メッセージが到着するエンドポイント参照を含むパートナ・リンクを選択します。
「ポート・タイプ」フィールドおよび「操作」フィールドは、イベントを発生させるためにパートナによって呼び出されるポート・タイプおよび操作を定義します。
変数または「送信元パート」要素を使用して、パートナからメッセージを受信するための方法を指定します。
「適用」をクリックし、「OK」をクリックします。
BPELプロセスの設計を続行します。
例14-9に、設計完了後の.bpel
ファイル内のonEvent
ブランチの概要を示します。onEventブランチは、クレジット要求のステータスの問合せ、要求内容の変更または処理中の要求の完全な取消を行います。
例14-9 onEventブランチ
<process name="creditRequestProcess" . . .> . . . <eventHandlers> <onEvent partnerLink="requestCreditScore" operation="queryCreditRequestStatus" ...> <scope name="scopeStatus">...</scope> </onEvent> <onEvent partnerLink="requestCreditScore" operation="modifyCreditRequest" ...> <scope name="scopeRequest">...</scope> </onEvent> <onEvent partnerLink="requestCreditScore" operation="cancelCreditRequest" ...> <scope name="scopeCancel">...</scope> </onEvent> </eventHandlers> . . . </process>
リモート・データベースに接続する同期プロセスについては、Oracle Enterprise Manager Fusion Middleware ControlコンソールのシステムMBeanブラウザで、SyncMaxWaitTimeタイムアウト・プロパティの値を増加する必要があります。
このプロパティの設定方法については、第7.3項「タイムアウト値の指定」を参照してください。