JBoss jbpm 入門 水野浩典 佐藤修一オープンソース コンピテンシコンピテンシ センター日本ヒューレットパッカードヒューレットパッカード株式会社 2006 年 12 月 6 日 2006 Hewlett-Packard Development Company, L.P. The information contained herein is subject to change without notice
目的 JBossから提供されているワークフロー管理用エンジンである JBoss jbpm の概要紹介 2 JBoss jbpm は... じぇいぼすじぇいびーぴーえむ と読みます
内容 JBoss jbpm とは? JBoss jbpm 事例紹介と弊社の取り組み JBoss jbpm システム概要 プロセスの動作概要 JBoss jbpm アプリケーション JBoss jbpm Web アプリケーション 3
JBoss jbpm とは?
JBoss jbpm とは? ビジネスプロセス管理用エンジンを実装した Java ライブラリ jbpm-3.1.2.jar プロセスの開発ツール プロセス作成用 GUI プロセスデプロイツール ちなみに JBoss jbpm JBoss AS (J2EE サーバ ) JBoss jbpm Struts or JSF ( 等のプレゼンテーション用フレームワーク ) JBoss jbpm アプリケーション (web アプリケーション等 ) 5
JBoss JEMS そして JBoss jbpm JEMS (JBoss Enterprise Middleware Suite) RedHat/JBossが掲げるオープンソースのSOAプラットフォーム 業界をリードしているオープンソースプロダクト群から構成されている プロダクトは組み合わせ可能 JBoss jbpm は JEMS 中の1 プロダクトでもある 6
ビジネスプロセス管理用エンジンとは 各種プロセスプロセスを管理管理する 7 ワークフロープロセス 人間が関与するタスク ( 仕事 / 業務 ) を持つプロセス BPM プロセス システムや人間が関与するタスク ( 仕事 / 業務 ) を持つプロセス オーケストレーションプロセス Web サービスに関係するプロセス (BPEL などの言語で定義 ) 各種プロセスプロセスの状態状態を保存保存する プロセスの遷移遷移を管理管理する 遷移処理はユーザプログラム ( クライアント ) で実行 タスク ( 仕事 / 業務 ) の処理処理は行わない タスク ( 仕事 ) の処理はユーザプログラムで実装する
JBoss jbpm 最大の特徴 グラフ指向プログラミング 業務分析担当者とシステム開発者開発者が 1つのグラフ ( 図 ) を介して 業務プロセスについて直感的に議論ができる 業務分析担当者 業務プロセスの設計ができる システム開発者 グラフ ( 図 ) で表現されたプロセスをアプリケーションに直結できる 8
JBoss jbpm が持つ機能 (1/3) 2 つのプロセスプロセス定義言語定義言語をサポート JPDL : JBoss jbpm 独自 プロセスと POJO を連携させる BPEL : Web サービス連携用言語 その他のプロセス定義言語への対応拡張も可能 プロセス内のノード 基本的に waite ステート Java の任意のクラス ( ビジネスロジック ) を実行可能 アクション プロセスのグラフ ( 図 ) 表現には表れないビジネスロジック実装する Java クラス 9
JBoss jbpm が持つ機能 (2/3) 既存 / 外部システムシステムとのとの連携 Java で書けることな何でも可能 ノード内の Java クラス アクション タイマー 特定の時間に... アクションを実行 (ex. リマインダーを送信する ) プロセスを遷移 プロセス変数 ビジネスプロセスを実体化したもの ( プロセスインスタンス ) に変数を持たすことができる 10
JBoss jbpm が持つ機能 (3/3) プロセス管理面 11 トラッキング機能 (RDBMS を利用 ) ビジネスプロセスの個々の実体 ( プロセスインスタンス ) タスク ( 人間に割り当てられた仕事 ) ビジネスプロセスに行われた処理のログ ビジネスプロセスのバージョン プロセスの非同期実行 再開 ビジネスカレンダーの定義 ユーザ / グループ等の情報を持つ企業ディレクトリとの連携
JBoss jbpm の特徴 : 実装とシステム要件 実装 12 100% Java シンプルなコアエンジン API 他 Javaライブラリへの依存度が非常に低い システム要件 Any JVM (J2SE 環境で動作可能 ) JDBC 対応の任意のデータベースサーバ 不要!! Web サービス /Web コンテナ /EJB コンテナ /JMS ただし J2EE 環境 /J2EEクラスター環境でも動作可能 Webサービス /Servlet/JSP/EJB/JMSとの連携も可能
JBoss jbpm の特徴 : ライセンス 費用 オープンソース ライセンスは LGPL フリーで使用可能 ( 製品保守を除く ) 商用ワークフローエンジンには 利用ユーザ数に応じて課金するものもある JBoss jbpm を使ったシステムではユーザ数に関わらず 0 円 13
JBoss jbpm の特徴 : 開発機能面 ビジネスプロセスをグラフ ( 図 ) で表現可能 業務分析担当者とシステム開発者との容易な連携 ビジネスプロセスのソースはJPDL(XML) GUI によるプロセスプロセスの設計設計 モデリングモデリング 開発 Eclipse の GPD プラグイン GPD( グラフィカル プロセス デザイナー ) : JBossが開発 提供 プロセスのグラフ ( 図 ) 表現とJPDL(XML) 間の相互変換が瞬時に可能 作成したプロセスのデプロイ もちろんオープンソース Java のコーディング不要 GPD プラグインもしくは JPDL(XML) の編集だけでビジネスプロセスの作成 Ant, JUnit 等の汎用汎用ツールツールで開発開発 デプロイデプロイ テストテスト可能 14 ビジネスプロセスの開発 デプロイ テスト JBoss jbpm を使ったユーザアプリケーションの開発 テスト
GPD : Eclipse プラグイン 15
JBoss jbpm の特徴 : 標準化への対応 JBoss jbpm の開発リーダーや JBoss 開発チームが JSR に参画 JSR 207: Process Definition for Java JSR 208: Java Business Integration (JBI) JSR 299: Web Beans JBossSeam 16
JBoss jbpm 事例紹介と 弊社の取り組み
事例 ( 海外の事例 ) 事例 (1) 会社名 : 大手保険会社 業界 : 金融 採用目的 : クレーム申請 新規保険証書の発行処理 性能 : 100,000 プロセス ステップ / 分 事例 (2) 会社名 : 大手航空宇宙会社 業界 : 運輸 採用目的 : 調達承認処理 部品納入ベンダが登録する 大手航空宇宙会社による仕様確認やベンダへの質問 事例 (3) 会社名 : 大手金融サービス会社 業界 : 金融 採用目的 : 証券取引所における不正処理調査 事例 (4) 会社名 : 大手政府機関 業界 : 政府 採用目的 : 法的処置案件管理システムのプロトタイプ 事例 (5) 会社名 : Raible Designs 社 採用目的 : JBoss jbpm を使った ESB(Enterprise Service Bus) 参照 URL : http://raibledesigns.com/page/rd?anchor=djug_building_an_ope n_source 事例 (6) 会社名 : ルクセンブルク陸軍 業界 : 政府 採用目的 : JBoss jbpm を使った ERP 事例 (7) 会社名 : 司法サービス会社 業界 : 法曹界 採用目的 :Windows のクライアント / サーバによる貧弱なワークフローシステムを JBoss jbpm を使った Web アプリケーションに置き換え 事例 (8) 会社名 : Computation 社 業界 : 不明 採用目的 : ERP システムのワークフロー処理 事例 (9) 会社名 : Met@Logo ( ドイツ技術協力公社 (GTZ) による egovernment プロジェクト ) www.metalogo.org 業界 : 政府 採用目的 : 南米各国の地方自治体向け電子政府ソリューションにおけるビジネスプロセス処理の基盤エンジンとして 事例 (10) 会社名 : Texas Institute of Genomic Medicine 業界 : バイオ 採用目的 : ビジネス処理のモデル化として採用 18
HP における JBoss HP ワールドワイドで製品保守を提供 JBoss Application Server JEMS( JBoss Enterprise Middleware Suite ) この中に jbpm が入っています JBoss jbpm 日本 HP での対応 JBoss Application Server 2005 年 7 月から標準時間の製品保守を提供 JEMS, JBoss jbpm 現在準備中 JBoss jbpm 開発支援コンサルティングを提供 19
オープンソースサポート体制 (JBoss/MySQL/Redhat) ハードウェア OS ミドルウエアなどプラットフォームに関するお問い合わせ 障害解決 ( コア解析含 ) 支援 製品に関するヘルプデスクおよび障害対応 エンドユーザ パートナ 電話または e-mail HWとOSを一括で契約 日本 日本レッドハット 日本 HP 担当サポートエンジニア 日本 HP 協調 コールセンター 貢献 エスカレーション JBoss/MySQL/Redhat HP 担当サポートエンジニア HP 世界 協調 グローバル専任サポートチーム ハードウェア HP 製ソフトウェアと他社製品を切り分け対応 開発者 Open Source & Linux Lab HP SW 開発部門 HP HW 開発部門 コミュニティー 20 HP と各社の強固なパートナーシップによる問題解決体制
JBoss 開発者支援コンサルティング 全工程に対するする一貫一貫したした開発者支援開発者支援サービス 設計プロトタイプ開発テスト運用 経験不足 + 情報不足 新しいソフトウェアに対する経験不足 ドキュメントや システム構築のノウハウ トラブルシューティングなどに関する情報不足 サービス内容 設計支援 仕様決定支援 障害解析支援 サンプルコード提供 運用手順支援 21
JBoss jbpm システム概要
プロセス ビジネスなどの処理フローを表現したもの 申請 承認プロセス Start 通常のプログラムのフローチャートとは異なります 承認などの外部からのイベントを待つことが可能 プロセスは JPDL を用いて記述 表現する 申請したい品目の入力 ここで 承認を待ちます 承認 Input approval yes no 経理処理 account End 23
プロセス定義ファイル (JPDL) 申請 承認プロセス Start <process-definition name= pay raise process"> 申請したい品目の入力承認 Input approval yes no <start-state name= Start > <transition to= input /> </start-state> <task-node name= input > <transition to= approval /> </task-node> <task-node name= approval > <transition name= yes to= account /> <transition name= no to= End /> </task-node> 経理処理 account <task-node name= account > <transition to= End /> </task-node> <end-state name= End /> </process-definition> End 24
JPDL で表現できるフロー State Task-node State-node Node Decision ForkとJoin Subprocess Start Task-node Fork Decision yes no Task-node Task-node Node State Join End 25
ソフトウェアスタック プロセスアーカイブ Process 定義 Start Input User Program 開発環境 ~/src/config/ ~/src/process/ ~/src/java/ ~/target/classes/ ~/target/par/ no approval yes account End Action 定義 jbpm 開発ツール (GUI) jbpm デプロイツール Database jbpm engine Hibernate J2SE 26
システム全体図 Start Input JVM item Hibernate Log Exe 環境構築ツール 作成 デプロイ 開発環境 ~/src/config/ ~/src/process/ ~/src/java/ ~/target/classes/ ~/target/par/ User Program no approval yes account End jbpm engine Start Input approval yes account End item no Process Instance Variable Token Def Process 定義 Action 定義 デプロイツール deploy 作成ツール 作成 Process Archive(*.par) Process 定義 Start Input approval yes account End (GUI) no Action 定義 27
プロセスの生成と動作 1. ユーザプログラムが jbpm エンジンにプロセスの生成を依頼 2.jBPM エンジンがプロセス定義を参照しプロセスを生成 3. ユーザプログラムがエンジンにプロセスの実行を依頼 JVM Hibernate Log 4.jBPM エンジンがプロセスの実行を開始 5. プロセスを順次実行 6. 必要があればユーザプログラムに制御を渡すためにプロセスを待ち状態にする User program User program 8 Start Input approval yes account End item no Exe Process Instance Variable Token 7. ユーザプログラムが待っているプロセスのリストを取得 8. 取得したプロセスに対して処理を行う 9. プロセスの続行をエンジンに依頼 1 3 4,5,6 9 7 jbpm engine 2 Def Process 定義 Action 定義 28
プロセスの動作概要
Token ( トークン ) プロセスの遷移を表現する プロセスの現在の位置を保持するオブジェクト 以下の情報を保持 Start Log プロセスインスタンスへのリンク情報 ノード ( 位置 ) 情報 Input item Exe Process Instance approval Variable yes no Token account Def End Process 定義 Action 定義 30
プロセス変数 (Variable) 各プロセスインスタンスが保持する変数 データベースに保持される ユーザー定義のデータを使用する場合は独自にシリアライザを作成する必要がある Start Input item Log Exe Process Instance approval Variable yes no Token account Def End Process 定義 Action 定義 31
アクション プロセスのステートが遷移するときに自動的に呼び出されるユーザ処理 アクションは インターフェースの execute() メソッドで実装 JPDL 定義ファイルでアクションを定義 アクションを設定できる場所 プロセスの開始と終了 ステートに入ったとき (ENTER) ステートから出る時 (LEAVE) ステートが変わる時 (TRANSITION) execute() メソッド内から 同メソッドの引数である ActionContext を用いてプロセス変数にアクセス可能 プロセス変数経由でプロセスを呼び出したプログラムと情報の交換が可能 使用例 外部システムとの連携 Start transition state-enter 入力 state-leave transition decision-enter 承認 decision-leave transition 経理処理 End process-start yes state-enter state-leave transition no process-end 1 設定 2call transition item 3access 32
プロセスとクライアントプログラム クライアントプログラム プロセス生成の実行 プロセスの開始 Start 社員が自分自身に関連するプロセスを取得承認する商品を入力商品を item 変数に設定次に進む Input item 上司が自分自身に関連するプロセスを取得 item 変数から商品を取得承認するかしないかを判断次に進む approval 33
JBoss jbpm アプリケーション --- 購買アプリケーションの例 ---
購買アプリケーション 備品を購入するための申請 承認システム 登場人物 : 社員 ( 申請者 ) 上司 ( 承認者 ) 社員 上司 購買申請処理 商品と値段の入力 承認する上司の選択 承認が緊急であるかどうかを入力 緊急の場合は 承認者にメールが自動送信される申請履歴の参照 承認結果を参照 申請の承認処理 承認結果は 申請者にメールで知らされる 35
購買アプリケーションのユースケース < 社員 : 購買申請 > Step1 : システムにログイン Step2 : 購買申請メニューへ進む Step3 : 購買品目情報を入力し 次の画面へ 品名 価格 Step4 : 次の情報を選択し 購買申請を送信 承認依頼する上司 外部システムにアクセスし 価格に応じて選択可能な上司の一覧が表示される 緊急かどうか 緊急な場合は上司にメールが送信される Step5 : 申請確認画面が表示される 申請 ID 品名 価格 上司名 Step6 : ログアウト < 上司 : 承認処理 > Step1 : システムにログイン Step2 : 承認処理メニューへ進む Step3 : 申請を承認するか否かを選択し 確定 承認結果が社員にメール送信される Step4 : ログアウト < 社員 : 申請履歴参照 > Step1 : システムにログイン Step2 : 購買申請履歴メニューへ進む Step3 : 過去の申請 ID を入力すると 申請のステータスが表示される 申請 ID( プロセス ID) 品目 価格 ステータス ( 承認済 未承認 却下 ) Step4 : ログアウト 36
購買アプリケーション用ビジネスプロセス 37
38 購買アプリケーション全体図プロセスインスタンスプロセスインスタンスプロセスインスタンスプロセスインスタンス jbpmconfiguration JVM DB セッション / トランザクション生成 user_name mgr_name isurgent approval 申請確定 Start-state End-state 品目入力承認上司選択上司選択上司選択上司選択承認依頼承認依頼承認依頼承認依頼のメールメールメールメール送信送信送信送信承認結果承認結果承認結果承認結果のメールメールメールメール送信送信送信送信 item price SelectMgr SendMail SendMail UserAssignment UserAssignment MgrAssignment トークン user1 user1 manager1 jbpm DB EIS 設定情報緊急の場合メール送信メール送信 jbpmcontext ログインログアウトログインログアウトログインログアウト購買申請購買申請購買申請購買申請プログラムプログラムプログラムプログラム申請履歴参照申請履歴参照申請履歴参照申請履歴参照プログラムプログラムプログラムプログラム承認承認承認承認プログラムプログラムプログラムプログラム
購買申請プログラム < 社員 : 購買申請 > Step1 : Step2 : Step3 : Step4 : Step5 : Step6 : システムにログイン 購買申請メニューへ進む 購買品目情報を入力し 次の画面へ 品名 価格 次の情報を選択し 購買申請を送信 承認依頼する上司 緊急かどうか 申請内容確認画面が表示される 申請 ID 品名 価格 上司名ログアウト 購買申請プログラム ユーザ "user1" でログイン jbpmcontext 取得プロセスインスタンスの生成トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送るプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得申請情報を入力 タスクを終了させるプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得申請依頼をする上司を選択申請が緊急かどうかを選択 タスクを終了させるプロセスインスタンスを保存 jbpmcontext クローズ ログアウト jbpmcontext 生成 jbpmconfiguration DB セッション / トランザクション プロセスインスタンス isurgent トークン トークン トークン approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 トークン item 承認 price user1 user1 manager1 承認結果のメールメール送信 user_name mgr_name プロセス変数 "user_name" の値をアサイン UserAssignment SelectMgr アサイン UserAssignment SendMail MgrAssignment SendMail 設定情報 1 上司問合せ jbpm DB 3 プロセス変数 "mgr_name" に "manager1" を登録 2"manager1" EIS 緊急の場合メール送信 プロセス変数 mgr_name の値をアサイン JVM End-state 39
JBoss jbpm Web アプリケーション --- 購買アプリケーションの例 --
Web アプリケーション ( 購買申請プログラム ) HTTP リクエスト / レスポンス 41 Step1 : HttpSession の user_name 属性にログインユーザー名を登録 システムにログイン Step2 : 購買申請メニューへ進む 申請 Step3 : 購買品目情報を入力 ログイン 履歴 次へ Step4 : 上司 緊急度を選択し購買申請を送信申請確定 Step5 : 申請確認画面が表示される Step6 : ログアウトログアウト 生成と 削除 ログイン jbpmcontext 取得プロセスインスタンスの生成トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送るプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得 申請情報を入力 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 ログアウト Servlet Filter user1 に割り当てられたタスクを取得 申請依頼をする上司を選択 申請が緊急かどうかを選択 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext HttpSession user_name Tomcat item isurgent トークン トークン トークン トークン ServletContext jbpmconfiguration プロセスインスタンス approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 承認 price 承認結果のメールメール送信 End-state user1 mgr_name UserAssignment SelectMgr user1 UserAssignment manager1 SendMail MgrAssignment SendMail jbpm DB HttpSessionのEIS user_name" 属性値をアサイン 緊急の場合メール送信
Web アプリケーションのソフトウェアスタック例 : JBoss AS と Seasar2 と連携させた場合 app.dicon web.xml HTML Action クラス Logic クラス プロセス JbpmContextFilter S2ContainerFilter Tomcat Step3 : 購買品目 情報を入力 S2JSF JSF Myfaces 次へ faces-config.xml 品目入力 S2Container item price user_name isurgentapprovalmgr_name Start-state user1 token 品目入力 申請確定承認 End-state JBoss jbpm Hibernate JBoss AS JbpmConfiguration 42
JbpmContextFilter jbpmcontext の生成とクローズを実施 JBoss jbpm に付属の Servlet Filter クライアントからの HTTP リクエスト受付時に JbpmContext を生成 生成された JbpmContext はスレッドに割り当てられる (ThreaLocal) クライアントに HTTP レスポンスを返す前に JbpmContext をクローズ web.xml... <filter> <filter-name>jbpmcontextfilter</filter-name> <filter-class>org.jbpm.web.jbpmcontextfilter </filter-class> </filter> <filter-mapping> <filter-name>jbpmcontextfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>... JbpmContextFilter.java public class JbpmContextFilter implements Filter, Serializable {... public void dofilter(servletrequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws IOException, ServletException { JbpmContext jbpmcontext = getjbpmconfiguration().createjbpmcontext(jbpmcontextname); try { if (isauthenticationenabled) { jbpmcontext.setactorid(actorid); } filterchain.dofilter(servletrequest, servletresponse); } finally { jbpmcontext.close(); } } 43
Step3 : 購買品目情報を入力 Servlet HttpSession ServletContext HTTP リクエスト / レスポンス 44 Step1 : システムにログインログイン Step2 : 購買申請メニューへ進む申請履歴 Step3 : 購買品目情報を入力次へ Step4 : 上司 緊急度を選択し購買申請を送信申請確定 Step5 : 申請確認画面が表示される Step6 : ログアウトログアウト ログイン jbpmcontext 取得プロセスインスタンスの生成トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送るプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得 申請情報を入力 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 ログアウト Filter user1 に割り当てられたタスクを取得 申請依頼をする上司を選択 申請が緊急かどうかを選択 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext user_name item isurgent トークン トークン jbpmconfiguration プロセスインスタンス approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 承認 price 承認結果のメールメール送信 End-state user1 user1 manager1 Tomcat/JBossAS mgr_name UserAssignment SelectMgr UserAssignment SendMail MgrAssignment SendMail jbpm DB EIS 緊急の場合メール送信
Step3 : 購買品目情報を入力 システム制御フロー HTTP リクエスト user_input.html 45 HTTP レスポンス user_confirm.html jbpmcontext のクローズ jbpmcontext の生成 JbpmContextFilter S2ContainerFilter Tomcat 品目と値段を DTO に設定 HTML Step3 : 購買品目 情報を入力 JSF Myfaces S2JSF 次へ 戻り値の user_confirm を元に遷移先画面を決定 UserAction#input() Action クラス 品目入力 戻り値 user_confirm S2Container JBoss AS BpmLogic#input() Logic プロセスクラス item price user_name isurgentapprovalmgr_name token Start-state 品目入力 申請確定 承認 End-state user1 JBoss jbpm JbpmConfiguration Hibernate
最後に... JBoss jbpm を始めてみたい方へ
JBoss jbpm を始めてみたい方へ... お薦めです JBoss jbpm getting started guide http://wiki.jboss.org/wiki/wiki.jsp?page=jbpmgettingstarted コンテンツ : JBoss jbpm の入手方法 JBoss jbpm エンジンの使用方法スターターキット ( サンプル Web アプリケーション +JBossAS) の実行方法ビジネスプロセスの作成方法 GPD の使用方法 FAQ... などなど 47
まとめ JBoss jbpm とは? JBoss jbpm 事例紹介と弊社の取り組み JBoss jbpm システム概要 プロセスの動作概要 JBoss jbpm アプリケーション JBoss jbpm Web アプリケーション 48
付録 (1) 各種参考資料へのリンク
参照資料 JBoss jbpm のホームページ http://www.jbpm.org/index.html jbpm のドキュメントのページ http://www.jbpm.org/docs.html jbpm のユーザフォーラム http://sourceforge.net/forum/forum.php?forum_id=240085 jbpm の Wiki http://wiki.jboss.org/wiki/wiki.jsp?page=jbpmwiki JBoss jbpm getting started guide http://wiki.jboss.org/wiki/wiki.jsp?page=jbpmgettingstarted Seasar プロジェクトのホームページ http://www.seasar.org/index.html 50
弊社 URL JBoss のページ http://www.hp.com/jp/jboss/ Open Source & Linux のページ http://www.hp.com/jp/linux/ 51
付録 (2) JBoss jbpm アプリケーションの例 --- 購買アプリケーション -- 詳細
53 購買アプリケーション全体図プロセスインスタンスプロセスインスタンスプロセスインスタンスプロセスインスタンス jbpmconfiguration JVM DB セッション / トランザクション生成 user_name mgr_name isurgent approval 申請確定 Start-state End-state 品目入力承認上司選択上司選択上司選択上司選択承認依頼承認依頼承認依頼承認依頼のメールメールメールメール送信送信送信送信承認結果承認結果承認結果承認結果のメールメールメールメール送信送信送信送信 item price SelectMgr SendMail SendMail UserAssignment UserAssignment MgrAssignment トークン user1 user1 manager1 jbpm DB EIS 設定情報緊急の場合メール送信メール送信 jbpmcontext ログインログアウトログインログアウトログインログアウト購買申請購買申請購買申請購買申請プログラムプログラムプログラムプログラム申請履歴参照申請履歴参照申請履歴参照申請履歴参照プログラムプログラムプログラムプログラム承認承認承認承認プログラムプログラムプログラムプログラム
購買申請プログラム < 社員 : 購買申請 > Step1 : Step2 : Step3 : Step4 : Step5 : Step6 : システムにログイン 購買申請メニューへ進む 購買品目情報を入力し 次の画面へ 品名 価格 次の情報を選択し 購買申請を送信 承認依頼する上司 緊急かどうか 申請内容確認画面が表示される 申請 ID 品名 価格 上司名ログアウト 購買申請プログラム ユーザ "user1" でログイン jbpmcontext 取得プロセスインスタンスの生成トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送るプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得申請情報を入力 タスクを終了させるプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得申請依頼をする上司を選択申請が緊急かどうかを選択 タスクを終了させるプロセスインスタンスを保存 jbpmcontext クローズ ログアウト jbpmcontext 生成 jbpmconfiguration DB セッション / トランザクション プロセスインスタンス isurgent トークン トークン トークン approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 トークン item 承認 price user1 user1 manager1 承認結果のメールメール送信 user_name mgr_name プロセス変数 "user_name" の値をアサイン UserAssignment SelectMgr アサイン UserAssignment SendMail MgrAssignment SendMail 設定情報 1 上司問合せ jbpm DB 3 プロセス変数 "mgr_name" に "manager1" を登録 2"manager1" EIS 緊急の場合メール送信 プロセス変数 mgr_name の値をアサイン JVM End-state 54
プロセスインスタンスの生成 Step1: ログイン jbpmconfiguration 設定情報 Step2: 購買申請メニューに進む ユーザ "user1" でログイン 1jbpmContext 取得 2 プロセスインスタンスの生成 3 トークンを取得 2 3 7 graphsession jbpmcontext 1 2 6 DB セッション / トランザクション プロセスインスタンス item isurgent price approval user_name mgr_name 4 jbpm DB 4 プロセス変数 user_name にユーザ名 user1 を登録 5 トークン Start-state 5 トークンにシグナルを送る 6 プロセスインスタンスを保存 7jbpmContext クローズ 5 トークン 品目入力 user1 UserAssignment 上司選択 SelectMgr 申請確定 承認依頼のメールメール送信 UserAssignment SendMail 55
プロセスインスタンスの生成 ( コード ) Step2: 購買申請メニューへ "user1" でログイン jbpmcontext 取得 プロセスインスタンスの生成 トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送る プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得 申請情報を入力 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ ログアウト jbpmconfiguration jbpmcontext // jbpmcontext の取得 JbpmContext jbpmcontext = jbpmconfiguration.createjbpmcontext(); GraphSession graphsession = jbpmcontext.getgraphsession(); try { // プロセスインスタンスの生成 ProcessDefinition pd = graphsession.findlatestprocessdefinition(procname); ProcessInstance pi = new ProcessInstance(pd); // トークンを取得 Token token = pi.getroottoken(); // プロセス変数 "user_name" に ユーザ名 "user1" を登録 pi.getcontextinstance().setvariable("user_name", getusername()); // トークンにシグナルを送る token.signal(); // プロセスインスタンスを保存 jbpmcontext.save(pi); } finally { jbpmcontext.close(); // jbpmcontext のクローズ } 56
task へのユーザー登録 Step1: ログイン jbpmconfiguration Step2: 購買申請メニューに進む ユーザ "user1" でログイン 1jbpmContext 取得 2 プロセスインスタンスの生成 3 トークンを取得 4プロセス変数ユーザ名 user1を登録 user_name 5 トークンにシグナルを送る 6 プロセスインスタンスを保存 7jbpmContext クローズ に graphsession jbpmcontext 5 プロセスインスタンス item isurgent トークン 5 トークン Start-state 品目入力 上司選択 price approval user1 user_name mgr_name 5` SelectMgr 4 jbpm DB プロセス変数 "user_name" の値をタスクにアサイン UserAssignment 申請確定 承認依頼のメールメール送信 UserAssignment SendMail 57
ユーザーの設定 (UserAssignment) item isurgent プロセスインスタンス approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 承認 price user1 user1 manager1 承認結果のメールメール送信 user_name mgr_name UserAssignment SelectMgr UserAssignment SendMail MgrAssignment SendMail import org.jbpm.graph.exe.executioncontext; import org.jbpm.taskmgmt.def.assignment; import org.jbpm.taskmgmt.exe.assignable; public class UserAssignment implements Assignment { public void assign(assignable assignable, ExecutionContext executioncontext) { } } // プロセス変数 "user_name" からアサイン対象のユーザ名を取得 String user = (String)executionContext.getVariable("user_name"); // アサインする assignable.setactorid(user); End-state 58
タスクの処理 Step3: 申請情報を入力 1 jbpmconfiguration 設定情報 ユーザ "user1" でログイン 1jbpmContext 取得 2 プロセスインスタンスの生成 3 トークンを取得 4 プロセス変数 user_name にユーザ名 user1 を登録 5 トークンにシグナルを送る 6 プロセスインスタンスを保存 7jbpmContext クローズ 1jbpmContext 取得 2user1 に割り当てられたタスクを取得 3 申請情報を入力 4 タスクを終了させる 5 プロセスインスタンスを保存 6jbpmContext クローズ... 6 graphsession jbpmcontext 2 isurgent findtaskinsnces("user1") 4 5 DB セッション / トランザクション プロセスインスタンス 3 item トークン Start-state 品目入力 上司選択 トークン 申請確定 price approval user1 user_name mgr_name UserAssignment SelectMgr UserAssignment jbpm DB 承認依頼のメールメール送信 SendMail 59
タスクの処理 ( コード ) Step3: 申請情報を入力 "user1" でログイン jbpmcontext 取得 プロセスインスタンスの生成 トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送る プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得 申請情報を入力 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ 60 ログアウト jbpmconfiguration jbpmcontext // jbpmcontext の取得 JbpmContext jbpmcontext = jbpmconfiguration.createjbpmcontext(); TaskMgmtSession taskmgmtsession = jbpmcontext.gettaskmgmtsession(); try { // user1 に割り当てられた最初の "apply item task" タスクを処理 Iterator it = taskmgmtsession.findtaskinstances(getusername()).iterator(); TaskInstance ti = null; for (; it.hasnext(); ) { ti = (TaskInstance)it.next(); if (ti.getname().equalsignorecase("apply item task")) { } } // 申請情報を入力 ti.setvariable("item", getitem()); // 品名 ti.setvariable("price", getprice()); // 価格 ti.setvariable("applicant", getusername()); // ユーザ名 "user1" break; ti.end(); // タスクを終了させる jbpmcontext.save(pi); // プロセスインスタンスを保存 } finally { jbpmcontext.close(); // jbpmcontext のクローズ }
アクションハンドラーの動作 Step3: 申請情報を入力 61 ユーザ "user1" でログイン 1jbpmContext 取得 2 プロセスインスタンスの生成 3 トークンを取得 4 プロセス変数 user_name にユーザ名 user1 を登録 5 トークンにシグナルを送る 6 プロセスインスタンスを保存 7jbpmContext クローズ 1jbpmContext 取得 2user1 に割り当てられたタスクを取得 3 申請情報を入力 4 タスクを終了させる 5 プロセスインスタンスを保存 6jbpmContext クローズ... graphsession 4 jbpmcontext jbpmconfiguration トークン プロセスインスタンス item isurgent Start-state 品目入力 上司選択 トークン 申請確定 price approval 承認依頼のメールメール送信 user1 user_name mgr_name UserAssignment SelectMgr UserAssignment SendMail 承認者問合せ jbpm DB manager1 EIS
アクションハンドラーのコード (SelectMgr) プロセスインスタンス item price user_name isurgent approval mgr_name Start-state import org.jbpm.graph.def.; import org.jbpm.graph.exe.executioncontext; public class SelectMgr implements { public void execute(executioncontext executioncontext) { user1 品目入力 上司選択 user1 申請確定 承認依頼のメールメール送信 manager1 承認 承認結果のメールメール送信 End-state UserAssignment SelectMgr UserAssignment SendMail MgrAssignment SendMail } } // プロセス変数から 申請者と価格の情報を取得 String applicant = (String)executionContext.getVariable("user_name"); String price = (String)executionContext.getVariable("price"); // 承認対象上司を取得 // 外部データベース ディレクトリサーバにアクセスして // 申請者と価格に応じた承認対象の上司を決定する... String manager = getmanager(applicant, price); // プロセス変数 "mgr_name" に承認対象上司を登録 executioncontext.setvariable("mgr_name", manager); 62
承認処理の全体図 JVM jbpmconfiguration < 上司 : 承認処理 > Step1: システムにログイン Step2 : 承認処理メニューへ進む Step3 : 申請を承認するか否かを選択し 確定 承認結果が社員にメール送信される Step4: ログアウト 承認プログラム ユーザ manager1 でログイン jbpmcontext 取得 ログアウト jbpmcontext manager1 に割り当てられたタスクを取得 申請の承認を行う タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ プロセスインスタンス item isurgent approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 トークン 承認 price user1 user1 manager1 承認結果のメールメール送信 user_name mgr_name UserAssignment SelectMgr UserAssignment SendMail MgrAssignment 承認結果をメール送信 SendMail トークン End-state 63
アクションハンドラーのコード SendMail プロセスインスタンス item isurgent price approval user_name mgr_name Start-state user1 品目入力 上司選択 user1 申請確定 承認依頼のメールメール送信 manager1 承認 承認結果のメールメール送信 UserAssignment SelectMgr UserAssignment SendMail MgrAssignment SendMail import org.jbpm.graph.def.; import org.jbpm.graph.exe.executioncontext; public class SendMail implements { public void execute(executioncontext executioncontext) { // 申請者名と承認結果をプロセス変数から取得 String applicant = (String)executionContext.getVariable( user_name"); String approval = (String)executionContext.getVariable( approval"); // 申請者にメールを送信 dosendmailtouser(applicant, approval); End-state } } 64
申請履歴を参照するプログラム 更新履歴参照プログラム jbpmconfiguration jbpm DB < 社員 : 申請履歴の参照 > Step1: システムにログイン Step2 : Step3 : 購買申請履歴メニューへ進む 申請 ID を入力すると 下記のステータスが表示される 申請 ID( プロセス ID) 承認ステータス 品名 価格 Step4: ログアウト jbpmcontext "user1" でログイン jbpmcontext 取得 過去の申請 ID("1") を持つプロセスインスタンスを取得 プロセスインスタンスから情報を取得 承認ステータス 品名 価格 jbpmcontext クローズ ログアウト プロセスインスタンス (ID=1) item isurgent approval Start-state プロセスインスタンスからプロセス変 数を取得承認 user_name mgr_name 品目入力 プロセスインスタ上司選択ンスの検索 ID=1user1 のインスタンスを取得申請確定 price user1 承認依頼のメールメール送信 manager1 承認結果のメールメール送信 UserAssignment SelectMgr UserAssignment SendMail MgrAssignment SendMail JVM トークン End-state 65
申請履歴を参照するプログラム ( コード ) // jbpmcontext の取得 JbpmContext jbpmcontext = jbpmconfiguration.createjbpmcontext(); GraphSession graphsession = jbpmcontext.getgraphsession(); "user1" でログイン jbpmcontext 取得 申請 ID("1") を持つプロセスインスタンスを取得 プロセスインスタンスから情報を取得 承認ステータス 品名 価格 jbpmcontext クローズ ログアウト jbpmcontext try { String status = "processing"; String item = "none"; String price = "none"; long pid = getpid(); // プロセスインスタンス ID を取得 // プロセスインスタンス ID からプロセスインスタンスを取得 ProcessInstance pi = graphsession.loadprocessinstance(pid); if (pi!= null) { // 品目 価格の取得 item = (String)pi.getContextInstance().getVariable("item"); price = (String)pi.getContextInstance().getVariable("price"); // プロセスインスタンスが終了していれば 承認結果を取得 if (pi.hasended()) { status = (String)pi.getContextInstance().getVariable("approval"); } } printstatus(pid, status, item, price); 66 } finally { jbpmcontext.close(); // jbpmcontext のクローズ }
付録 (3) JBoss jbpm Webアプリケーション --- 購買アプリケーション --- (Seasar2 との連携例 )
Seasar2 との連携 購買アプリケーションの Web システムを JBoss と Seasar2 で構築 J2EE サーバ : JBoss AS 4.0.5 DIxAOP コンテナ : S2Container 2.3.10 プレゼンテーション フレームワーク : S2JSF 1.0.18 ビジネスロジックエンジン : JBoss jbpm 3.1.2 O/R Mapper : Hibernate 3.1 68
ソフトウェアスタック app.dicon web.xml HTML Action クラス Logic クラス プロセス JbpmContextFilter S2ContainerFilter Tomcat Step3 : 購買品目 情報を入力 S2JSF JSF Myfaces 次へ faces-config.xml 品目入力 S2Container item price user_name isurgentapprovalmgr_name Start-state user1 token 品目入力 申請確定承認 End-state JBoss jbpm Hibernate JBoss AS JbpmConfiguration 69
連携する上で重要な設定 web.xml Servlet Filter jbpmのjbpmcontextを設定するフィルターを設定 org.jbpm.web.jbpmcontextfilter app.dicon DI の設定 jbpm の API をコールするロジッククラス jbpm.sar を JBoss にデプロイ jbpmをjbossと連携させるために必要 jbpmcontext 取得用 JBoss JNDI サービス 70
基本的な設定 faces-config.xml 画面遷移の設定 app.dicon DI の設定 アクションクラス DTO 71
Step3 : 購買品目情報を入力 Servlet HttpSession ServletContext HTTP リクエスト / レスポンス 72 Step1 : システムにログインログイン Step2 : 購買申請メニューへ進む申請履歴 Step3 : 購買品目情報を入力次へ Step4 : 上司 緊急度を選択し購買申請を送信申請確定 Step5 : 申請確認画面が表示される Step6 : ログアウトログアウト ログイン jbpmcontext 取得プロセスインスタンスの生成トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送るプロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得 申請情報を入力 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 ログアウト Filter user1 に割り当てられたタスクを取得 申請依頼をする上司を選択 申請が緊急かどうかを選択 タスクを終了させる プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext user_name item isurgent トークン トークン jbpmconfiguration プロセスインスタンス approval Start-state 品目入力 上司選択 申請確定 承認依頼のメールメール送信 承認 price 承認結果のメールメール送信 End-state user1 user1 manager1 Tomcat/JBossAS mgr_name UserAssignment SelectMgr UserAssignment SendMail MgrAssignment SendMail jbpm DB EIS 緊急の場合メール送信
システム制御フロー HTTP リクエスト user_input.html 73 HTTP レスポンス user_confirm.html jbpmcontext のクローズ jbpmcontext の生成 JbpmContextFilter S2ContainerFilter Tomcat 品目と値段を DTO に設定 HTML Step3 : 購買品目 情報を入力 JSF Myfaces S2JSF 次へ 戻り値の user_confirm を元に遷移先画面を決定 UserAction#input() Action クラス 品目入力 戻り値 user_confirm S2Container JBoss AS BpmLogic#input() Logic プロセスクラス item price user_name isurgentapprovalmgr_name token Start-state 品目入力 申請確定 承認 End-state user1 JBoss jbpm JbpmConfiguration Hibernate
JbpmContextFilter jbpmcontext の生成とクローズを実施 JBoss jbpm に付属の Servlet Filter クライアントからの HTTP リクエスト受付時に JbpmContext を生成 生成された JbpmContext はスレッドに割り当てられる (ThreaLocal) クライアントに HTTP レスポンスを返す前に JbpmContext をクローズ web.xml... <filter> <filter-name>jbpmcontextfilter</filter-name> <filter-class>org.jbpm.web.jbpmcontextfilter </filter-class> </filter> <filter-mapping> <filter-name>jbpmcontextfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>... JbpmContextFilter.java public class JbpmContextFilter implements Filter, Serializable {... public void dofilter(servletrequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws IOException, ServletException { JbpmContext jbpmcontext = getjbpmconfiguration().createjbpmcontext(jbpmcontextname); try { if (isauthenticationenabled) { jbpmcontext.setactorid(actorid); } filterchain.dofilter(servletrequest, servletresponse); } finally { jbpmcontext.close(); } } 74
HTTP リクエスト :user_input.html <h2>enter item to apply!</h2> <span m:inject="h:messages" m:globalonly="false" m:showdetail="true"/> DTOにitemと <form> priceの値を設定 <table border="0"> <tr> <td>item </td> <td><input type="text" m:value="#{applydto.item}"/></td> </tr> <tr> <td>price </td> <td><input type="text" m:value="#{applydto.price}"/></td> </tr> </table> <input type="submit" value="next" m:action="#{useraction.input}"/> </form> 75 アクションクラスの呼び出し
アクションクラス :UserAction#input() public class UserActionImpl implements UserAction {... private BpmLogic bpmlogic;... public void setbpmlogic(bpmlogic bpmlogic) { } this.bpmlogic = bpmlogic; }... public String input() { bpmlogic.input(); return "user_confirm"; }... ロジッククラスの DI ロジッククラスの呼び出し 次の遷移先の指定 76
ロジッククラス :BpmLogic#input() Step3: 申請情報を入力 jbpmcontext 取得 プロセスインスタンスの生成 トークンを取得 プロセス変数 user_name にユーザ名 user1 を登録 トークンにシグナルを送る プロセスインスタンスを保存 jbpmcontext クローズ jbpmcontext 取得 user1 に割り当てられたタスクを取得 申請情報を入力 タスクを終了させる プロセスインスタンスを保存 jbpmconfiguration jbpmcontext public class BpmLogicImpl implements BpmLogic { public BpmLogicImpl() { // コンストラクタ // jbpmcontext 取得 this.jbpmcontext = JbpmContext.getCurrentJbpmContext(); this.taskmgmtsession = jbpmcontext.gettaskmgmtsession(); }... public void input() { // user1に割り当てられた最初の "apply item task" タスクを処理 String username = userdto.getusername(); // 以下は同じコードなので省略 for ( ) { if (ti.getname().equalsignorecase("apply item task")) { } } // 申請情報情報を取得 ti.setvariable("item", applydto.getitem()); // 品名 ti.setvariable("price", applydto.getprice()); // 価格 ti.setvariable("applicant", username); // ユーザ名 break; } } ti.end(); // タスクを終了させる jbpmcontext.save(pi); // プロセスインスタンスを保存 // jbpmcontext のクローズクローズ処理処理は ここではここでは不要 77
画面遷移 :faces-config.xml Web アプリケーションの画面遷移は JSF の faces-config.xml で記述 <faces-config> <! Step4 申請情報確認確認画面 --> <navigation-rule> <navigation-case> <from-outcome>user_confirm</from-outcome> <to-view-id>/user_confirm.html</to-view-id> <redirect/> </navigation-case> </navigation-rule>... </faces-config> 78
app.dicon : DI の設定 アクションクラス 79 画面遷移先を決定するためのクラス DTO アクションクラスやロジッククラスからフォームに入力されたデータを利用するためのクラス アプリケーションからデータベース上のデータを利用するためのクラス ロジッククラス JBoss jbpm エンジンの API を実際にコールするクラスの設定 アクションクラスから呼ばれる <!-- アクションクラス --> <component class="org.seasar.framework.container. autoregister.filesystemcomponentautoregister"> <property name="instancedef"> @org.seasar.framework.container.deployer.instancedeffactory@request </property> <initmethod name="addclasspattern"> <arg>"com.hp.kobe.oss.jbpm31.webapp.action.impl"</arg> <arg>".*actionimpl"</arg> </initmethod> </component> <!-- DTO -->... <property name="instancedef"> @org.seasar.framework.container.deployer.instancedeffactory@session </property> <initmethod name="addclasspattern"> <arg>"com.hp.kobe.oss.jbpm31.webapp.dto"</arg> <arg>".*dto"</arg> </initmethod>... <!-- ロジッククラス -->... <property name="instancedef"> @org.seasar.framework.container.deployer.instancedeffactory@request </property> <initmethod name="addclasspattern"> <arg>"com.hp.kobe.oss.jbpm31.webapp.logic.impl"</arg> <arg>".*logicimpl"</arg> </initmethod>...
Seasar2 との連携によるメリット S2Container の DI 機能を使用することで ロジッククラスは 既存の POJO をそのまま使用可能 画面作成は HTML (S2JSF) で簡単作成 画面遷移は faces-config.xml (JSF) で簡単作成 S2AOP も使用可能 80