この章の内容は次のとおりです。
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つのブランチの条件は指定の時間待機することです。
図15-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アクティビティでは実行できません。
注意:
BPEL 1.1のscopeアクティビティにおけるonMessageブランチと、BPEL 1.1および2.0のscopeアクティビティにおけるonAlarmブランチも作成できます。Oracle JDeveloperでscopeアクティビティを開き、左側でアイコンを参照して追加するブランチを検索します。
次の例のコード・セグメントは、この操作の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つのプロセスを作成します。
BPELバージョン1.1および2.0における次のタイプの操作に対して、タイムアウト設定を指定できます。
リクエスト/リプライ(同期)操作。
入力専用receive(非同期)操作。このシナリオでは、receiveアクティビティは中間プロセスのアクティビティであり、新しいインスタンスを作成する(つまり、「Receive」ダイアログの「インスタンスの作成」チェック・ボックスが選択されている)アクティビティではない必要があります。
この機能は、パートナ・コールバックのタイムアウト期間を指定する際に使用するpickアクティビティのonMessageブランチとonAlarmブランチの代替手段として提供されています。
図15-6 に、中間プロセスのreceiveアクティビティのタイムアウトを設定する「タイムアウト」タブを示します。
receiveアクティビティのリクエスト・リプライ操作および入力専用操作に対するタイムアウトを設定する前に理解しておく基本的な概念の詳細は、「リクエスト・リプライ操作および入力専用操作に対するタイムアウトの設定に関する必知事項」を参照してください。
Oracle JDeveloperでreceiveアクティビティのタイムアウトを設定する方法の詳細は、「receiveアクティビティのタイムアウトの設定方法」を参照してください。
次のシナリオを使用して、タイムアウトを設定します。
「インスタンスの作成」チェック・ボックスを選択解除する
receiveアクティビティは、BPELプロセス(ほとんどの場合)の処理中である
receiveアクティビティでタイムアウトを設定する手順は、次のとおりです。
.bpel
ファイルのコード・セグメントは、特定の操作に対する設計完了後の定義を示しています。
たとえば、アクティビティが実行開始後5分以内にインバウンド・メッセージの着信を予定していることを指定した場合は、次の例に示すような構文が表示されます。
<bpelx:for="'PT5M'"/>
たとえば、アクティビティが実行開始以降、インバウンド・メッセージの着信を遅くとも2010年1月24日午前11時(UTC+1)以前に予定していることを指定した場合は、次のコードに示すような構文が表示されます。
<bpelx:until="'2010-01-24T11:00:00-08:00'"/>
たとえば、アクティビティの起動時からの相対的なタイムアウトの値を取得するようにXPath式を指定した場合は、次のコードに示すような構文が表示されます。
<bpelx:for="bpws:getVariableData('inputVariable','payload','/tns:waitValue/tns:for ')"/>
次の各項では、リクエスト・リプライおよび入力専用のタイムアウト操作の機能について説明します。
アクティビティの起動時からの相対的なタイムアウト設定
絶対的な日時でのタイムアウト設定
XPath式を使用して動的に計算されるタイムアウト設定
アクティビティ・タイムアウト時にスローされるbpelx:timeout
フォルト
アクティビティ・タイムアウト時にBPELインスタンス監査証跡に追加されるイベント
サーバー再起動時にリカバリ可能なタイムアウト・アクティビティ
タイムアウト設定として、アクティビティの起動時からの相対的なタイムアウトを指定できます。この設定は、次の例に示すBPEL 1.1用の構文を使用して相対的な期間として指定されます。
<receive | bpelx:for="duration-expr"> standard-elements </receive>
BPEL 2.0では、構文は次の例のようになります。
<receive | <bpelx:for>'duration-expr'</bpelx:for> standard-elements </receive>
このタイプでは、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アクティビティの絶対的な期限として指定できます。BPEL 2.0では、構文は次の例のようになります。
<receive <bpelx:until>"deadline-expr"</bpelx:until> </receive>
BPEL 1.1では、構文は次の例のようになります。
<receive bpelx:until="deadline-expr"> standard-elements </receive>
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アクティビティ、入力専用receive(コールバック)アクティビティおよびpickアクティビティのonMessageブランチに対するタイムアウト設定は、静的な期間またはdatetime
値を入力するかわりに、XPath式を使用して設定できます。この場合は、次のいずれかを式の値として返す必要があります。
XMLの静的な期間またはdatetime
値と解釈される文字列
XMLスキーマの期間またはdatetime
タイプ
次の例に、BPEL 1.1で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アクティビティとほぼ同様の方法で実装されます。スケジューラを使用してこれらのアクティビティをスケジュールしたノードが(正常な停止または中途完了のいずれかで)停止した場合は、サーバー再起動時に、スケジューラを使用してこれらのアクティビティをすべて再スケジュールする必要があります。
ノードが停止した場合、これらのアクティビティをクラスタの単一のノード(マスター・ノード)で再スケジュールすることはできません。
waitアクティビティを使用すると、プロセスは指定された期間または時間制限に達するまで待機できます。有効期限条件を1つのみ指定する必要があります。このアクティビティの典型的な用途は、一定の時間に操作を起動することです。通常は、プロセスの状態に依存する式を入力します。
待機期間を指定する場合は、次の点に注意してください。
処理を必要とする他のイベントとともにスケジュールされている場合、待機期間は保証されません。この追加処理のために、実際の待機期間は、BPELプロセスに指定されている待機期間より長くなる可能性があります。
2秒未満の待機期間はサーバーから無視されます。2秒以上1分未満の待機期間は、正確な指定時間で実行されないことがあります。ただし、分単位の待機期間は指定時間で実行されます。
待機時間2
秒のデフォルト値は、Oracle Enterprise Manager Fusion Middleware ControlのシステムMBeanブラウザのMinBPELWaitプロパティで指定されます。このプロパティは任意の値に設定でき、MinBPELWait未満の待機の遅延は無視されます。
注意:
waitアクティビティの期限切れイベントのスケジュールには、Quartzバージョン1.6がサポートされています。
BPELプロセスがデハイドレーションに関連して待機する最小期間を指定できます。待機期間が指定値以下の場合、BPELはアクティビティの実行を同じスレッドの同じトランザクションで続行します。
最小待機時間を指定する手順は、次のとおりです。
指定されたイベントがメッセージの到着を待機するonEventブランチをscopeアクティビティ内に作成できます。たとえば、顧客のクレジット要求メッセージによって開始されるクレジット要求プロセスがあると仮定します。さらに顧客対応を行わなくても要求は完全に処理され、結果が顧客に送信されます。ただし、顧客がクレジット要求のステータスに関する問合せ、要求内容の変更、または処理中の要求の完全な取消を行う場合があります。このような顧客対応は、ビジネス処理の特定の時点でのみ発生するとはかぎりません。onEventブランチなどのイベント・ハンドラを使用すると、ビジネス・プロセスでは、プライマリ・ビジネス・ロジック・フローに並行して到着する要求(ステータス要求、変更要求、取消要求など)を受け入れることができます。
onEventイベント・ハンドラは、内側に囲まれているスコープと関連付けられます。onEventイベント・ハンドラはスコープが初期化されると有効になり、スコープが終了すると無効になります。有効になると、いくつものイベントが発生する可能性があります。イベントは、スコープのプライマリ・アクティビティおよびイベント相互に並行して処理されます。メッセージ・イベントも、プロセスによって公開されるサービス操作を表し、onEvent要素としてモデル化されます。イベント・ハンドラは新しいプロセス・インスタンスを作成できません。したがって、メッセージ・イベントは常に、すでにアクティブなプロセス・インスタンスで受信されます。
次の例に、設計完了後の.bpel
ファイル内のonEventブランチの概要を示します。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タイムアウト・プロパティの値を増加する必要があります。
このプロパティの設定方法の詳細は、「永続同期プロセスのトランザクションのタイムアウト値の指定」を参照してください。
Oracle Enterprise SchedulerジョブをBPELプロセスで起動できます。Oracle Enterprise Schedulerジョブは、Java、データベースのストアド・プロシージャまたは実行可能ファイルの形態における作業の単位です。ジョブ定義はOracle Enterprise Schedulerに関連付けられ、ここでジョブの実行方法を記述します。Oracle Enterprise Schedulerでは、WebサービスがジョブをBPELプロセス内から発行し、スケジュールをそのジョブ・リクエストと関連付けます。
スケジュール済Oracle Enterprise Schedulerジョブはランタイム環境に格納され、データベース・ベースのアクセスを使用して、Oracle Metadata Servicesリポジトリ(MDSリポジトリ)接続でアクセスできます。
注意:
この項では、ジョブの完了を待機する方法ではなく、BPELプロセスからのジョブの発行方法を説明します。BPELプロセスでジョブの完了を待機するには、Webサービスを起動して、ジョブの完了時にコールバックを要求し、そのコールバックを取得するために受信を実行する必要があります。詳細は、『Oracle Enterprise Schedulerアプリケーションの開発』の「Oracle Enterprise Scheduler Webサービスの使用方法」を参照してください。
OracleデータベースとSOA-MDSの接続を作成するには:
SOAコンポジット・アプリケーションを作成します。詳細は、「SOAアプリケーションの作成」を参照してください。
BPELプロセスをSOAコンポジット・エディタで作成します(この例では、同期BPELプロセスが作成されます)。詳細は、「BPELプロセス・サービス・コンポーネントの追加方法」を参照してください。
SOAコンポジット・エディタでBPELプロセスをダブルクリックします。
Oracle BPELデザイナが表示されます。
Oracleデータベース接続を作成します。これはOracle Enterprise Schedulerジョブの問合せで必要です。
「ファイル」メイン・メニューから「新規」→「アプリケーション」の順に選択します。
「カテゴリ」リストから、「接続」を選択します。
「データベース接続」を選択します。
「データベース接続の作成」ウィザードが表示されます。
Oracle Enterprise Schedulerがデプロイされているランタイム・サーバーの、スケジューラOracle Metadata Services Repositoryデータベースとの接続を作成するためのデータベース接続の作成ウィザードのダイアログを完了し、「終了」をクリックします。
SOA-MDS接続を作成します。データベース・ベースのMDSリポジトリが、選択ジョブの取得で使用されます。
「ファイル」メイン・メニューから「新規」→「アプリケーション」の順に選択します。
「カテゴリ」リストから、「接続」を選択します。
「SOA-MDS接続」を選択します。
「SOA-MDS接続の作成」ダイアログが表示されます。
「接続タイプ」リストから、「DBベースMDS」を選択します。
「接続」リストで、手順4で作成されたデータベース接続が表示されることを確認してください。
「MDSパーティションの選択」リストから、Oracle Enterprise Schedulerジョブを含めるパーティションを選択します。ネイティブのホスティング・アプリケーションが事前デプロイ済のOracle Enterprise Schedulerに定義されているジョブの場合は、MDSパーティション名はessUserMetadataです。
SOA-MDS接続を作成するためのダイアログの残りのフィールドを完成し、「OK」をクリックします。