ヘッダーをスキップ
Oracle Fusion Middleware Oracle SOA Suite開発者ガイド
11g リリース1(11.1.1)
B56238-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

10 BPELプロセスでのパラレル・フローの使用

この章では、BPELプロセス・サービス・コンポーネントでのパラレル・フローの使用方法について説明します。 パラレル・フローを使用すると、BPELプロセス・サービス・コンポーネントで複数のタスクを同時に実行できます。 パラレル・フローは、時間を要する独立した複数のタスクを実行する必要がある場合に特に役立ちます。

項目は次のとおりです。

SOAコンポジット・アプリケーションでのパラレル・フローの作成方法の詳細は、『Oracle Fusion Middleware Oracle SOA Suiteアプリケーションの作成および実行のためのチュートリアル』を参照してください。

10.1 BPELプロセスでのパラレル・フローの概要

BPELプロセスでは、複数の非同期ソースからの情報の収集が必要になる場合があります。各コールバックに要する時間(時間数または日数)は明らかでないため、各サービスを一度に1つずつコールするのでは時間がかかりすぎることがあります。 複数のコールを1つのパラレル・フローに分解することにより、BPELプロセス・サービス・コンポーネントは複数のWebサービスを同時に起動し、レスポンスが到着するたびに受信できます。この方法は時間の節約に効果的です。

次の図は、WebLogic Fusion Order Demoアプリケーションの「Retrieve_QuotesFromSuppliers」flowアクティビティを示しています。 「Retrieve_QuotesFromSuppliers」flowアクティビティは、注文情報を社内倉庫(InternalWarehouseService)と外部パートナ倉庫(PartnerSupplierMediator)の2つのサプライヤにパラレルで送信します。 2つの倉庫は、注文に対する入札をflowアクティビティに返します。 ここでは、2つの非同期コールバックがパラレルで実行されます。 一方のコールバックは、もう一方のコールバックが先に完了するまで待機する必要がありません。各レスポンスは異なるグローバル変数に格納されます。

図10-1 パラレル・フローの起動

図10-1の説明は次にあります。
「図10-1 パラレル・フローの起動」の説明

10.2 パラレル・フローの作成

BPELプロセス・サービス・コンポーネントにパラレル・フローを作成するには、flowアクティビティを使用します。 flowアクティビティを使用すると、1つ以上のアクティビティを同時に実行するように指定できます。 flowアクティビティは同期性も備えています。flowアクティビティは、フロー内のすべてのアクティビティが処理を終了したときに完了します。このアクティビティが完了しても、許可条件がfalseの場合はスキップされている可能性があります。

10.2.1 パラレル・フローの作成方法

パラレル・フローを作成する手順は、次のとおりです。

  1. 「コンポーネント・パレット」から、デザイナにflowアクティビティをドラッグします。

  2. +記号をクリックし、次の図のようにflowアクティビティを開きます。

    図10-2 flowアクティビティ

    図10-2の説明は次にあります。
    「図10-2 flowアクティビティ」の説明

    flowアクティビティには、2つのブランチがあり、各ブランチには機能要素用のボックスがあります。これらのボックスにデータを移入するには、scopeアクティビティの場合のように、機能を作成するか、複数のアクティビティをボックスにドラッグします。

  3. 複数のサービスを同時に起動するには、追加するアクティビティをflowの両側にドラッグして定義します。

    図10-3 開いた状態のflowアクティビティ

    図10-3の説明は次にあります。
    「図10-3 開いた状態のflowアクティビティ」の説明

    完了すると、flowアクティビティの設計は次のようになります。 この例は、WebLogicFusionOrderDemoアプリケーションの「Retrieve_QuotesFromSuppliers」flowアクティビティを示しています。 入札を受け取るために、「InternalWarehouseService」および「PartnerSupplierMediator」の2つのブランチが定義されています。

    図10-4 設計完了後のflowアクティビティ

    図10-4の説明は次にあります。
    「図10-4 設計完了後のflowアクティビティ」の説明

10.2.2 パラレル・フロー作成時の処理内容

通常、flowアクティビティには多数のsequenceアクティビティが含まれています。 各sequenceはパラレルに実行されます。 例10-1は、設計完了後のOrderProcessor.bpelファイルのRetrieve_QuotesFromSuppliers flowアクティビティに対してsequenceが2つある構文を示しています。ただし、flowアクティビティには多数のsequenceを指定できます。 flowアクティビティには、他のアクティビティを含めることもできます。 例10-1では、flowの各sequenceにassign、invokeおよびreceiveアクティビティが含まれています。

図10-1 flowアクティビティ

<flow name="Retrieve_QuotesFromSuppliers">
    <sequence name="Sequence_4">
        <assign name="Assign_InternalWarehouseRequest">
            <copy>
                <from variable="gOrderInfoVariable"
                    query="/ns4:orderInfoVOSDO/ns4:OrderId"/>
                <to variable="lInternalWarehouseInputVariable"
                    part="payload"
                    query="/ns1:WarehouseRequest/ns1:orderId"/>
            </copy>
        </assign>
        <invoke name="Invoke_InternalWarehouse"
            inputVariable="lInternalWarehouseInputVariable"
            partnerLink="InternalWarehouseService"
            portType="ns1:InternalWarehouseService"
            operation="process"/>
        <receive name="Receive_InternalWarehouse"
            createInstance="no"
            variable="lInternalWarehouseResponseVariable"
            partnerLink="InternalWarehouseService"
            portType="ns1:InternalWarehouseServiceCallback"
            operation="processResponse"/>
        <assign name="Assign_InterWHResponse">
            <bpelx:append>
                <bpelx:from variable="lInternalWarehouseResponseVariable"
                       part="payload"
                       query="/ns1:WarehouseResponse"/>
                <bpelx:to variable="gWarehouseQuotes"
                       query="/ns1:WarehouseList"/>
            </bpelx:append>
        </assign>
    </sequence>
    <sequence name="Sequence_4">
        <assign name="Assign_PartnerRequest">
            <copy>
                <from variable="gOrderInfoVariable"
                    query="/ns4:orderInfoVOSDO"/>
                <to variable="lPartnerSupplierInputVariable"
                    part="request" query="/ns4:orderInfoVOSDO"/>
            </copy>
        </assign>
        <invoke name="Invoke_PartnerSupplier"
            partnerLink="PartnerSupplierMediator"
            portType="ns15:execute_ptt" operation="execute"
            inputVariable="lPartnerSupplierInputVariable"/>
        <receive name="Receive_PartnerResponse"
            createInstance="no"
            variable="lPartnerResponseVariable"
            partnerLink="PartnerSupplierMediator"
            portType="ns15:callback_ptt" operation="callback"/>
            <assign name="Assign_PartnerWHResponse">
                <bpelx:append>
                    <bpelx:from variable="lPartnerResponseVariable"
                           part="callback"
                           query="/ns1:WarehouseResponse"/>
                           <bpelx:to variable="gWarehouseQuotes"
                           query="/ns1:WarehouseList"/>
                    </bpelx:append>
            </assign>
    </sequence>
</flow>

10.3 flowNアクティビティを使用したflowアクティビティ数のカスタマイズ

flowアクティビティでは、BPELコードによってパラレル・ブランチの数が決定されます。ただし、必要なブランチの数は、多くの場合、使用可能な情報に応じて異なります。 flowNアクティビティは、Nの値に等しい複数のフローを作成します。この値は、使用可能なデータおよびプロセス内のロジックに基づいて実行時に定義されます。索引変数は、Nの値に到達するまで、新しいブランチが作成されるたびに増分されます。

flowNアクティビティは、任意の数のデータ要素に対してアクティビティを実行します。BPELプロセス・サービス・コンポーネントは、要素の数の変化に応じて適切に調整を実行します。

flowNで作成される各ブランチは、同じアクティビティを実行しますが、異なるデータを使用します。各ブランチは、索引変数を使用して入力変数を参照します。索引変数をXPath式で使用すると、そのブランチに固有のデータを取得できます。

たとえば、データの配列があるとします。BPELプロセス・サービス・コンポーネントは、count関数を使用して配列内の要素の数を判断します。次に、Nが要素の数に設定されます。索引変数は、事前に設定された値(デフォルトは0(ゼロ))で始まります。flowNは、複数のブランチを作成して配列の各要素を取得し、その要素に含まれるデータを使用してアクティビティを実行します。これらのブランチは、初期索引値とNの間のすべての値を使用して、パラレルに生成および実行されます。flowNは、索引変数がNの値に到達すると終了します。たとえば、配列に3つの要素が含まれている場合、N3に設定されます。索引変数が1で始まるとすると、flowNアクティビティは索引1、2および3を使用して3つのパラレル・ブランチを作成します。

flowNアクティビティでは、Webサービスから取得したデータなど、他のソースのデータも使用できます。

図10-5は、3つのホテルを参照するOracle Enterprise Manager Fusion Middleware ControlコンソールのflowNアクティビティの実行時フローを示しています。この図は、BPELプロセス・サービス・コンポーネントではなく、プロセスを実際に実行する方法を示しているため、ビューそのものではありません。この例では、3つのホテルがありますが、ブランチの数は使用可能なホテルの数に応じて異なります。

図10-5 flowNアクティビティの実行を示すOracle Enterprise Manager Fusion Middleware Controlコンソール・ビュー

図10-5の説明は次にあります。
「図10-5 flowNアクティビティの実行を示すOracle Enterprise Manager Fusion Middleware Controlコンソール・ビュー」の説明

10.3.1 flowNアクティビティの作成方法

flowNアクティビティを作成する手順は、次のとおりです。

  1. 「コンポーネント・パレット」から、デザイナにflowNアクティビティをドラッグします。

  2. +記号をクリックしてflowNアクティビティを開きます。

  3. flowNアクティビティをダブルクリックします。

    図10-6は、「FlowN」ダイアログを示しています。

    図10-6 「FlowN」ダイアログ

    図10-6の説明は次にあります。
    「図10-6 「FlowN」ダイアログ」の説明

    「FlowN」ダイアログでは次のことができます。

    • アクティビティ名の設定

    • 値またはNの値(作成するブランチ数)の計算式の入力

    • 索引変数(各ブランチでの待機時間)の定義

  4. 追加するアクティビティをflowNアクティビティにドラッグして定義します。

    図10-7は、flowNアクティビティと他のアクティビティが表示されている様子を示しています。

    図10-7 flowNアクティビティと他のアクティビティ

    図10-7の説明は次にあります。
    「図10-7 flowNアクティビティと他のアクティビティ」の説明

10.3.2 flowNアクティビティ作成時の処理内容

次のコードは、flowNアクティビティを使用して任意の数のホテルの情報を参照する.bpelファイルを示しています。次のアクションを実行します。

例10-2にsequence名を示します。

例10-2 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の数を定義してホテル情報を参照するために必要な情報を取得します。 例10-3に例を示します。

例10-3 receiveアクティビティ

    <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.
       An intermediate variable 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のアクティビティに名前を定義すると、NinputVariable(ホテル・エントリの数)の値として定義されます。また、このアクティビティは、索引変数としてindexを割り当てます。 例10-4に例を示します。

図10-4 flowNアクティビティ

<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.
            -->

例10-5に示すコピー・ルールで索引変数を使用し、複数のホテル・エントリを1つのリストに連結します。

例10-5 assignアクティビティ

<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サービスから各ホテルの詳細情報を参照します。 例10-6に例を示します。

例10-6 invokeアクティビティ

 <!-- 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 does not do anything with the retrieved information.
        In real life, it could then be used to continue the process.
        Note: Meanwhile an indexing variable is used. Unlike a while loop, the
 activities are executed in parallel, not sequentially.
        -->
      </sequence>
    </bpelx:flowN>

最後に、このBPELプロセスは、各ホテルの詳細情報をクライアント・パートナ・リンクに送信します。 例10-7に例を示します。

例10-7 invokeアクティビティ

    <invoke name="callbackClient" partnerLink="client"
 portType="client:NflowHotelsCallback" operation="onResult"
 inputVariable="outputVariable"/>
  </sequence>
  </sequence>