JBoss World 2012 デモ – 2

平田です。

前回のエントリではJBoss Toy Storeの概要について説明しました。今回はECサイト部分について掘り下げていきます。

ビジネスプロセス

まず、Drools Guvnorにインポートしたビジネスプロセスを見てみます。

ビジネスプロセス

アクティビティが六つ定義されています。

  • Initialize
    • スクリプトタスクです。Orderエンティティをファクトとして投入しています。
  • Risk Assessment
    • ビジネスルールタスクです。後述するRiskAssessmentルールを評価します。
  • Review
    • ユーザタスクです。利用者の注文を決裁します。
  • VP Review
    • ユーザタスクです。RiskAssessmentルールでhigh riskと判断された注文を決裁します。
  • Email
    • Emailと書いてありますが、プロセス変数をログ出力するダミータスクです。
  • Shipping
    • Shippingと書いてありますが、プロセs(ry

RiskAssessment ルール

前述のビジネスプロセスから呼ばれるデシジョンテーブルです。

RiskAssessment ルール

注文合計金額が500ドル以上のとき、high riskと判断します。ここでhigh riskとなった注文は、後続のVP Reviewにかけられます。

ドメインモデル

続いてドメインモデル(業務データ)を見てみましょう。

ドメインモデル(業務データ)

jbwdemo-modelプロジェクトのmodelパッケージにドメインモデルが入っています。この図に無いクラスもありますが、注文に関係するものだけを抜き出しています。

jBPMとの統合

jBPM3.2ではProcessInstanceにkeyという業務キーを保持するフィールドが用意されており、これを用いてビジネスプロセスの実行データとドメインモデルを紐付けしていました。jBPM5ではこのようなフィールドは用意されていない為、自力で紐付けする必要があります。

JBoss Toy Storeでは、プロセス変数を用いてビジネスプロセスの実行データからドメインモデルへの紐付けを定義しています。また、ドメインモデル側(Order)でもビジネスプロセスのエンティティのPKを持っています。

個人的には、特定のミドルウェアに依存する要素をドメインモデルに持たせず、分離しておきたいです。

レイヤ構成

ECサイト部分の各レイヤごとに、どのようなコンポーネントから成るか、見ていきます。

プレゼンテーション層

jbwdemo-clientプロジェクトjbwdemo-services-apiが、ECサイト部分のプレゼンテーション層になります。

プレゼンテーション層では、HTML5 + jQuery Mobileを使ってスマートフォン向けのUIを構築しています。Backbone.jsを使ってREST APIと通信する、画面遷移無しのステートフルなUIです。JavaScript MVCなどと呼ばれるアプローチですね。

  • src/main/webapp/app/main.js: ブラウザ側のURLと、画面モジュールを対応付けしています。
  • src/main/webapp/app/templates/*.html: lodash.jsのテンプレートエンジン機能を使ったUIテンプレートです。
  • src/main/webapp/app/modules/*.js: Backbone.jsによるモデル・コレクションとコントローラです。
  • jbwdemo-services-apiは、JAX-RSアノテーションを付与したインタフェースと、JAXBのJava Beanが定義されています。

Java EEのプレゼンテーション層と言えばJSF/faceletsですが、個人的にはJSFに良い印象を持っていない(複雑過ぎる、ヒープを喰い過ぎる、マークアップが独自で潰しが利かない)ので、このアプローチには非常に興味があります。

ビジネス層

jbwdemo-servicesjbwdemo-processがビジネス層になります。

  • src/main/resources/jbossworld.xml: カタログデータです。InitialiseData(..lizeだよなぁ)によってロードされます。
  • ビジネスロジックはJava EE 6のSingleton Session Beanとして実装されています。
  • jBPM5に関するロジックはjbwdemo-processのProcessControllerに集約されています。

インテグレーション層

jbwdemo-modelがインテグレーション層です。

  • jbwdemo-modelにエンティティが定義されています。
  • ModelUtilは、いわゆるDAOです。

イベントの舞台裏

ここからは、ECサイトの画面表示や利用者の操作といった各イベントごとに、裏側の処理を見ていきます。

入り口画面

  • 入り口 – Registerボタン
    • Registerボタンを押すと、/userにHTTP POSTします。
    • UserResource#createUserが実行され、UpdateManagerが保持するユーザDB(ConcurrentHashMap)に追加します。

買い物カゴ画面

  • 買い物カゴ – 注文ボタン
    • 注文(Place Order)ボタンを押すと、/cart/{id}/checkoutにHTTP POSTします。
    • ShoppingCartResource#checkoutからShoppingCartProcess#checkoutが呼ばれます。
    • 注文データをRDBに保存します。
    • ビジネスプロセスを開始します。

承認待ち注文一覧画面

  • 承認者用UI / 承認待ち注文一覧 – データのロード
    • 承認待ち注文一覧を開くと、/order/openをHTTP GETします。
    • OrderResource#getOpenOrdersからOrderProcess#getOpenOrdersが呼ばれます。
    • jbwdemo-processのTaskorm.xmlに定義されたTaskIdsAssignedAsPotentialOwnerByStatusByGroupクエリ(長い…)を実行し、Review待ちのjBPMタスクを取得します。

承認待ち注文画面

  • 承認者用UI / 承認待ち注文 – 承認ボタン / 否認ボタン
    • 承認(Approve)を押すと、/order/{orderId}/approveにHTTP PUTします。
    • OrderResource#approveOrderからOrderProcess#approveOrderが呼ばれます。
    • Orderエンティティの承認フラグを立て、保存します。
    • プロセス変数 approved=trueをセットし、jBPMタスクを完了させます。
    • 否認(Reject)を押すと、/order/{orderId}/rejectにHTTP PUTし、以降は承認と同じです。

まとめ

jBPM5を除けばTicketMonsterと同じ構成です。jBPM5についてはjbwdemo-processプロジェクトや、その中のProcessControllerクラスが参考になります。

軒並みSingleton Session Beanとして実装してあるのですが、きちんとスレッドセーフに動作するのか気になるところです。

次回はGWTを使った販売実績ダッシュボードを見ていきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です