Red Hat Training

A Red Hat training course is available for JBoss Enterprise SOA Platform

第8章 サービスオーケストレーション

8.1. はじめに

本項を参照し、サービスオーケストレーションと JBoss Business Process Manager 機能を統合する方法を学習します。
サービスオーケストレーション
サービスオーケストレーションという用語は、ビジネスプロセスの整理という意味です。従来、Business Process Execution Language (BPEL) を使い SOAP ベースの Web サービスを実行していました。Red Hat は JBPM を使いプロセスのオーケストレーションを行うよう推奨しています。

8.2. ウェブサービスの統制

注記

Red Hat および Enterprise Service Bus チームは、ActiveEndpoints (受賞歴のある ActiveBPEL WS-BPEL Engine を構築) と特別なサポート契約を交わしています。
ActiveBPEL を使い効果的に連携することで、Web サービスインターフェースを公開しないサービス群のうえに WS-BPEL-ベースのオーケストレーション層を提供することできます。JBoss Enterprise Service Bus は、Web サービス統合を提供しており、ActiveBPELプロセスオーケストレーションを提供しています。Flash- ベースのクイックスタートがオンラインで(http://labs.jboss.com/jbossesb/resources/tutorials/bpel-demos/bpel-demos.html) 多数提供されています。

8.3. オーケストレーションダイアグラム

オーケストレーションダイアグラムはフローチャートです。これを使い、ビジネスのサービスオーケストレーションプロセスをデプロイする方法を計画します。jBPM Integrated Development Environment を使いこれらのダイアグラムを作成します。
このオーケストレーションダイアグラムの例は、単純な受注プロセスを示しています(この例は bpm_orchestration4 クイックスタートを元にしています)。
bpm_orchestration4 クイックスタートのオーケストレーションダイアグラム

図8.1 bpm_orchestration4 クイックスタートのオーケストレーションダイアグラム

各ノードのクラス名は JBoss ESB サービスで、これらはIntake OrderCalculate DiscountShip It となっています。通常のnodes であるため、<<Node>> との名前がついています。これらのノードはそれぞれ EsbActionHandler に付いています。つまり、JBoss Business Process Manager ノードは、リクエストをサービスに送り、Enterprise Service Bus がサービスからのレスポンスによりコールバックするまで「待機」のステータスでとどまります。このレスポンスは、JBoss Business Process Manager コンテキスト内で利用していくことができます。
例えば、Intake Order サービスが応答すると、このレスポンスを使い Review Order フォームを生成します。Review Order ノードはタスクノードとなります。このタスクノードは、人とのやりとりを目的として作成されています (この場合、注文プロセスを発生させるには誰かがこの注文をレビューしなければなりません)。

手順8.1 オーケストレーションダイアグラムの作成手順

  1. File > New > Otherを選択します。
  2. Selection ウィザードからJBoss jBPM Process Definitionを選択します。
  3. プロセス定義を保存します (Red Hat は、整理の観点から、プロセス定義毎に別の辞書を使うよう推奨しています。これはプロセス設計ごとに最終的に複数のファイルが形成されるためです)。
  4. まず、 jBPM Integrated Development Environment のメニューパレットからProcess Design ビューにアイテムをドラッグアンドドロップします。追加した XML 要素を確認するために、デザインとソースモードの間で切り替えることも可能です。
    統合に必要な XML フラグメントはここに追加します (最近、ESB サービス と呼ばれる新しい種類のノードが追加されました)。
  5. 注文プロセスの図を構築する前に、3つのサービスを作成、テストします。通常の ESB サービスですので、jboss-esb.xml ファイルにて定義します。
    Red Hat は bpm_orchestration4 クイックスタート内にある jboss-esb.xml ファイルを参照し学習を進めていくよう推奨していますが、サービスオーケストレーション関連で把握しておくべきことはサービス名とカテゴリーです。jboss-esb.xml ファイルからの抜粋を以下に示しています。
        <services>
      <service category="BPM_orchestration4_Starter_Service" 
      name="Starter_Service"
      description="BPM Orchestration Sample 4: Use this service to start a 
    process instance">
    			<!-- .... -->						
      </service>
      <service category="BPM_Orchestration4" name="IntakeService"
      description="IntakeService: transforms, massages, calculates priority">
    			<!-- .... -->
      </service>		
      <service category="BPM_Orchestration4" name="DiscountService"
        description="DiscountService">					
      </service>		
      <service category="BPM_Orchestration4" name="ShippingService"
        description="ShippingService">			
    			<!-- .... -->
      </service>		 	
    </services>
    				
    				
    				
    
    
    EsbActionHandler あるいは EsbNotifier のいずれかを使い、これらのサービスを参照します (JBoss Business Process Manager がレスポンスが必要な場合はEsbActionHandler を、必要でない場合は EsbNotifier を選択します)。
  6. ESB サービスについて学習しましたので、Start ステートノードを設計ビューにドラッグします。新規プロセスインスタンスはこのノードで開始します。
  7. ノードをドラッグします (あるいは利用可能であれば ESB をドラッグします)。
  8. このノードに Intake Order という名前を付けます。
  9. メニューからTransition を選択し、StartIntake Order ノードのうえでクリックすることで、それぞれを接続できます。(これらの接続する矢印が表示されます。最初の Intake Order 方向を向いています)。
  10. Intake ノードにサービスとカテゴリー名を追加します。Source ビューを選択します。Intake Order ノードのソースコードを参照できます。ソースコードは以下のようになっているはずです。
    <node name="Intake Order">
        <transition name="" to="Review Order"></transition>
    </node>
    
  11. EsbHandlerAction クラス参照の後に、サービスカテゴリーと名前のサブ要素構成設定、BPM_Orchestration4IntakeService を追加します。以下に、この方法についてのサンプルコードを示します。
    <node name="Intake Order">
      <action name="esbAction" class=
        "org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
        <esbCategoryName>BPM_Orchestration4</esbCategoryName>
        <esbServiceName>IntakeService</esbServiceName>
        <!-- async call of IntakeService -->
      </action>
      <transition name="" to="Review Order"></transition>
    </node>
    
  12. 次に、サービス呼び出しと共にJBoss Business Process Manager コンテキスト変数を送信します (この例では、entireOrderAsXML という名前に変数があり、メッセージボディのデフォルトの位置に設定されます)。これを行うには以下のコードを追加します。
    <bpmToEsbVars>
      <mapping bpm="entireOrderAsXML" esb="BODY_CONTENT" />
    </bpmToEsbVars>
    
    これにより、entireOrderAsXML 変数の XML ベースコンテンツがメッセージのボディに入るようになります。これにより、パイプライン内で各アクションを通り流れるため、IntakeService がメッセージにアクセスし処理可能になります。最後のアクションに到達すると replyTo プロパティをチェックしメッセージが JBpmCallBack サービスに送信されます。
    JBpmCallBackJBoss Business Process Managerにコールバックし、Intake Order ノードから次のノードで遷移するよう合図を送ります (今回の場合、Review Orderです)。
  13. メッセージから変数を送信したいとします。コンテキストがオブジェクトのクラスをロードできれば、オブジェクト全体を送信することができます。
    JBoss Business Process Manager へマップバックする機能を保持するにはesbToEsbVars 要素を追加します。
    <node name="Intake Order">
    <action name="esbAction" class=
     "org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
    <esbCategoryName>BPM_Orchestration4</esbCategoryName>
    <esbServiceName>IntakeService</esbServiceName>
    <bpmToEsbVars>
    <mapping bpm="entireOrderAsXML" esb="BODY_CONTENT" />
    </bpmToEsbVars>
    <esbToBpmVars>
    <mapping esb="body.entireOrderAsXML" bpm="entireOrderAsXML"/>
    <mapping esb="body.orderHeader" bpm="entireOrderAsObject" />
    <mapping esb="body.customer" bpm="entireCustomerAsObject" />
    <mapping esb="body.order_orderId" bpm="order_orderid" />
    <mapping esb="body.order_totalAmount" bpm="order_totalamount" />
    <mapping esb="body.order_orderPriority" bpm="order_priority" />
    <mapping esb="body.customer_firstName" bpm="customer_firstName" />
    <mapping esb="body.customer_lastName" bpm="customer_lastName" />
    <mapping esb="body.customer_status" bpm="customer_status" />
    </esbToBpmVars>
    </action>
    <transition name="" to="Review Order"></transition>
    </node>
    
    このサービスが返されると、以下の変数はJBoss Business Process Managerのコンテキストに保存されます。
    • entireOrderAsXML,
    • entireOrderAsObject および
    • entireCustomerAsObject
    さらに、デモ目的でフラット化された変数も存在します。
    • order_orderid
    • order_totalAmount
    • order_priority
    • customer_firstName
    • customer_lastName および
    • customer_status
  14. ここで人による注文プロセスの確認を行う必要があります。そのため、task nodeOrder Reviewというタイトルのタスクを追加します。これらのジョブは、actor_id userを持つ誰かが実行する必要があります。
    XML フラグメントは以下のようになっているよう確認します。
    <task-node name="Review Order">
    <task name="Order Review">
    <assignment actor-id="user"></assignment>
     <controller>
    <variable name="customer_firstName"
    access="read,write,required"></variable>
    <variable name="customer_lastName" access="read,write,required">
    <variable name="customer_status" access="read"></variable>
    <variable name="order_totalamount" access="read"></variable>
    <variable name="order_priority" access="read"></variable>
    <variable name="order_orderid" access="read"></variable>
    <variable name="order_discount" access="read"></variable>
    <variable name="entireOrderAsXML" access="read"></variable>
    </controller>
    </task>
    <transition name="" to="Calculate Discount"></transition>
    </task-node>
    
  15. これらの変数が jbpm-console の形式で表示できるように、XHTML データ形式を作成します。

    注記

    詳細は bpm_orchestration4 クイックスタートの Review_Order.xhtml ファイルを参照してください。
  16. これらの設定を forms.xml ファイルに追加し、このデータフォームを task node とリンクします。
    <forms>
    <form task="Order Review" form="Review_Order.xhtml"/>
    <form task="Discount Review" form="Review_Order.xhtml"/>
    </forms>
    
  17. この場合、2つのタスクノードに同じフォームが適用される点に注意してください。以下のサンプルコードで示されているように、Review Order フォームでは変数への参照があります (こうすることで、 JBoss Business Process Managerのコンテキストに設定される変数を参照します)。
    <jbpm:datacell>
    <f:facet name="header">
    <h:outputText value="customer_firstName"/>
    </f:facet>
    <h:inputText value="#{var['customer_firstName']}" />
    </jbpm:datacell>
    
  18. このプロセスが Review Node に到達すると、jBPM Console にログインし Tasks をクリックすることでアイテム一覧を参照することができます。
  19. タスクをクリックし詳細を見ていきます。
  20. Save and Close をクリックして終了します。この時点でプロセスは次のノードに移動します。
  21. これは Calculate Discount ノードです。こちらも ESB サービスノードで、この設定ファイルは以下のようになります。
    <node name="Calculate Discount">
    <action name="esbAction" class="
    org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
    <esbCategoryName>BPM_Orchestration4</esbCategoryName>
    <esbServiceName>DiscountService</esbServiceName>
    <bpmToEsbVars>
    <mapping bpm="entireCustomerAsObject" esb="customer" />
    <mapping bpm="entireOrderAsObject" esb="orderHeader" />
    <mapping bpm="entireOrderAsXML" esb="BODY_CONTENT" />
    </bpmToEsbVars>
    <esbToBpmVars>
    <mapping esb="order"
    bpm="entireOrderAsObject" />
    <mapping esb="body.order_orderDiscount" bpm="order_discount" />
    </esbToBpmVars>
    </action>
    <transition name="" to="Review Discount"></transition>
    </node>
    
    このサービスは customerorderHeader の両オブジェクトだけでなくentireOrderAsXML データも受け取ります。次に割引を参集tします。そのレスポンスにより body.order_orderDiscount 値を order_-discountと呼ばれる JBoss Business Process Manager コンテキスト変数にマッピングします。そうすると、このプロセスは、Review Discount ノードに移動するように印付けされます。
  22. 8.5 に設定されている割引をレビューします。Save and Close をクリックすると、プロセスは ESB サービスである Ship It に移動します。
    Ship It サービスの完了前の注文プロセスを回避するため、EsbNotifier アクションハンドラーを利用し出力遷移に添付します。以下のコードで、方法を説明しています。
    <node name="ShipIt">
    <transition name="ProcessingComplete" to="end">
    <action name="ShipItAction" class=
    "org.jboss.soa.esb.services.jbpm.actionhandlers.EsbNotifier">
    <esbCategoryName>BPM_Orchestration4</esbCategoryName>
    <esbServiceName>ShippingService</esbServiceName>
     <bpmToEsbVars>
    <mapping bpm="entireCustomerAsObject" esb="customer" />
     <mapping bpm="entireOrderAsObject" esb="orderHeader" />
     <mapping bpm="entireOrderAsXML" esb="entireOrderAsXML" />
     </bpmToEsbVars>
     </action>
    </transition>
    </node>
    
    ShippingService に通知後、注文プロセスは end ステータスに移動し終了されます (ShippingService 自体は終了途中の場合もあります)。
    bpm_orchestration4 クイックスタートでは、JBoss Rules エンジンを使い、この注文が通常の手段あるいは、エクスプレス手段いずれを使って出荷されるか決定します。

8.4. プロセス定義のデプロイ

前のセクションで、プロセス定義のインスタンスが実行されていると仮定されていました。この仮定は、プロセスフローを説明するために立てられました。しかし、 processdefinition.xml ファイルが作成されたので、以下のいずれかを使いこのファイルを JBoss Business Process Manager にデプロイできます。
  • 統合開発環境 (以下の例で利用)
  • ant
  • jBPM コンソール
以下のファイルがデプロイされます。
  • Review_Order.xhtml
  • forms.xml
  • gpd.xml
  • processdefinition.xml
  • processimage.jpg
統合デプロイメント環境により .PAR アーカイブが作成され、jBPM データベースにデプロイされます。

警告

Red Hat は、クラスローディングの問題が発生する可能性があるため、.PAR アーカイブで Java コードをデプロイしないようアドバイスをしています。代わりに、クラスのデプロイには .JAR あるいは .ESB アーカイブを使います。

手順8.2 デプロイメントのインスタンス化

  • プロセス定義がデプロイされると新規プロセスインスタンスを作成します (StartProcessInstanceCommandコマンドを利用できます。このコマンドを使うことで、事前設定された初期値を使いプロセスインスタンスを作成できます)。
    このサンプルコードをご覧ください。
    <service category="BPM_orchestration4_Starter_Service"
    name="Starter_Service"
    description="BPM Orchestration Sample 4: Use this service to start a
     process instance">
    <listeners>
    </listeners>
    <actions>
    <action name="setup_key" class=
    "org.jboss.soa.esb.actions.scripting.GroovyActionProcessor">
    <property name="script"
    value="/scripts/setup_key.groovy" />
    </action>
    <action name="start_a_new_order_process" class=
    "org.jboss.soa.esb.services.jbpm.actions.BpmProcessor">
    <property name="command"
    value="StartProcessInstanceCommand" />
    <property name="process-definition-name"
    value="bpm4_ESBOrderProcess" />
    <property name="key" value="body.businessKey" />
    <property name="esbToBpmVars">
     <mapping esb="BODY_CONTENT" bpm="entireOrderAsXML" />
    </property>
    </action>
    </actions>
    </service>
    
    ここでスクリプトを使い新規プロセスインスタンスが呼び出されます。入ってくる注文 CML ファイルにより、jBPM キーが OrderId の値に設定されます。
    同様の XML は結果、esbToBpmVars マッピングを使い、jBPM コンテキストに入れられます。
    bpm_orchestration4 クイックスタートでは、XML はSeam DVD Store から来ており、SampleOrder.xml は以下のようになります。
    <Order orderId="2" orderDate="Wed Nov 15 13:45:28 EST 2006" statusCode="0"
     netAmount="59.97" totalAmount="64.92" tax="4.95">
    <Customer userName="user1" firstName="Rex" lastName="Myers" state="SD"/>
    <OrderLines>
    <OrderLine position="1" quantity="1">
    <Product productId="364" title="Gandhi"
    price="29.98"/>
    </OrderLine>
    <OrderLine position="2" quantity="1">
    <Product productId="299" title="Lost Horizon" price="29.99"/>
    </OrderLine>
    </OrderLines>
    </Order>
    

注記

Enterprise Service Bus と JBoss Business Process Manager のデプロイメントは両方、「ホット」デプロイメントと呼ばれます。
jBPM は、プロセスデプロイメントをバージョン化する特別機能です。新しく作成されたプロセスインスタンスが最新版となり、既存のものは起動したプロセスデプロイメントを使い終了されます。

8.5. まとめ

本項のサンプルを学習することで、JBoss Business Process Manager を使いサービスオーケストレーションや「ヒューマンタスク管理」を行うことができます。

注記

ご希望の jBPM 機能を自由にお使いいただけます。たとえば、forkjoin 機能の使用方法を学習したい場合は、bpm_orchestration2という名前のクイックスタートを確認してください。