BRMS(ビジネスルール管理システム)を活用したオンラインシステムの構築事例
2021.09.22 Progress Corticon
本エントリーはTIS株式会社様が寄稿したエントリー(https://fintan.jp/?p=5677)を転載したものとなります。
はじめに
ビジネスルールの見える化やシステムのアジリティの向上を目的として、BRMS(Business Rule Management System:ビジネスルール管理システム)の導入が注目されて久しい。
BRMSでは、ビジネスルールをディシジョンテーブルとして実装することにより、ビジネスルールが可視化されプログラマーでなくても直観的にビジネスルールを確認することができる。しかし、ディシジョンテーブルの構成を理解し、考慮すべきポイントを押さえなければ、「ディシジョンテーブルの結合後に意図した挙動をしない」や「保守性が低いディシジョンテーブルが作成される」などの問題が発生し、テストフェーズや保守フェーズでBRMSの恩恵を十分に享受することができない。
また、BRMSにビジネスルールを集約することで、ビジネスルールが制御機能などのビジネスルールでないプログラムと疎結合となり、変更に強くアジリティの高いシステムを構築することができる。しかし、BRMSについての仕様・動作については製品マニュアルや研修を通して知識を習得することは可能ではあるが、BRMSを呼び出すプログラムについての情報は少なく、私たちはどのようにして設計・開発をすべきかどうかが判断できずに戸惑ってしまう。
本ドキュメントでは、BRMS未経験者であった私たちが経験した、BRMSを利用したオンラインシステムの構築の実例を通して得た知見を、上記の2点に着目して紹介する。
TL;DR
- 本ドキュメントのポイント
- BRMSのディシジョンテーブルの開発方法および考慮ポイント
- BRMSを利用するアプリケーションの開発方法および考慮ポイント
- 本ドキュメントの想定読者
- BRMSの知見が無い開発者
- BRMSの開発経験はあるが、BRMSの呼び出し側も含めたシステム全体の構築についての知見が無い開発者
- 本ドキュメントで利用するBRMS製品
- Progress Corticon
BRMSについて
BRMSとは
BRMSとは、組織や企業の「ビジネスルール」を業務アプリケーションから切り離して、「ルールエンジン」によって、ビジネスルールを登録・管理・実行するシステムである。 ビジネスルールとは、ビジネスを遂行する上で判断・行動していくための基準となるもので、「○○○ならば(条件)△△△する(アクション)」と表現したものである。 ルールエンジンとは、物事の判断過程の「こういう場合にこうする」をプログラム化して実行するソフトウェアである。
BRMSの詳細については、SCSK株式会社様の以下のサイトを参照頂きたい。
Progress Corticonとは
本ドキュメントでは、BRMSのソフトウェアとしてProgress Corticonを利用した開発事例を紹介する。
Progress Corticonとは、世界40カ国以上で利用されているBRMS製品であリ、以下の特徴がある。
- ユーザフレンドリーなルール記述方式を採用し、ほぼノンコーディングでルールを作成できる。
- ルール呼び出し元との柔軟な連携。
- 優れた開発環境。
Progress Corticonの詳細については、SCSK株式会社様の以下のサイトを参照頂きたい。
BRMS 徹底活用ナビ Progress Corticon製品紹介
BRMSの開発
本章では、Progress Corticonを利用したBRMSの開発方法および考慮ポイントについて説明する。
構築するシステムの概要
まず、私たちが構築するBRMSを活用したオンラインシステムについて説明する。オンラインシステムの概要は、以下のとおり。
- ビジネスルールを呼び出すWEBサービスを、Spring Framework を利用したJavaアプリケーションで構築する。
- ビジネスルールを実行するディシジョンサービスを、Progress Corticon のルールエンジンサーバ(Progress Corticon Server)上に公開する。
- JavaアプリケーションからProgress Corticon Server上のディシジョンサービスへの呼び出しは、JAX-WSを利用したSOAP通信を利用する。(本事例では、通信方式としてSOAPを採用しているが、JAX-RSを利用したREST通信でも可能。)
BRMSの開発対象
Progress CorticonのBRMSを構築するためには、以下の資材を開発する必要がある。これらは、Progress Corticonが提供する開発ツールであるCorticon Studioを利用してGUIで開発する。
- 語彙
- ビジネスルールで利用するエンティティおよび属性をドメインクラスと呼ぶ。
- ドメインクラスを管理する辞書を、Progress Corticonでは語彙と呼ぶ。
- ルールシート
- 平易な言語でビジネスルールを「条件」「アクション」の関係に書き表したものをディシジョンテーブルと呼ぶ。
- ディシジョンテーブルを、Progress Corticonではルールシートと呼ぶ。
- ルールフロー
- 1つまたは複数のルールシートのセットであり、呼び出し順や条件を定義したものをルールフローと呼ぶ。
- ルールフローをデプロイしてサービス公開したものをディシジョンサービスと呼ぶ。
ディシジョンテーブル(ルールシート)の開発
BRMSの開発で重要となるルールシートについて説明する。ルールシートの構成は、以下のとおりである。
- フィルタ条件
- ルールシートを実行させるための条件を記載する。
- 語彙のエンティティ.属性を利用して、条件式を記載する。
- 縦列はAND条件となる。
- 条件部
- ビジネスルールの「○○○ならば」を記載する。
- 語彙のエンティティ.属性を利用して、条件式を記載する。
- 縦列(上図のa~e)は、AND条件となる。(1セル内には、OR条件の記述可能。)
- 条件として評価しない場合は、「-」を記載する。
- 条件部の横列(上図の1~3)の中で条件に合致した列のアクションを実行する。
- アクション部
- ビジネスルールの「△△△する(アクション)」を記載する。
- 語彙のエンティティ.属性を利用して、値の代入などのアクションを記載する。
- 縦列(上図のA~B)に記載してあるすべてのアクションを実行する。(空欄の場合は何もしない。)
また、ルールシート実行時の動きを、上図のルールシートを用いて説明する。
- フィルタ条件を確認する。
- フィルタ条件に記載された条件式をすべて満たしている場合のみ、後続の処理を実行する。
- 上図の例では、「従業員.手当計算 が '未' AND 従業員.年齢 >= 20 」の場合のみ、後続の処理を実行する。
- 条件部の条件を評価し、アクション部を実行する。
- 条件部の各列の条件を評価し、条件に合致した場合はアクション部を実行する。
- 上図の例では、以下のビジネスルールが実行される。
- 従業員.年齢 >= 30 AND 従業員.住居 が '賃貸' の場合、手当.住宅手当 に 30,000 を設定する。
- 従業員.年齢 >= 30 AND 従業員.住居 が '持家' の場合、手当.住宅手当 に 20,000 を設定する。
- 従業員.年齢 < 30 の場合、手当.住宅手当 に 20,000 を設定する。
- なお、「0」の列は、条件部の条件の合致有無に関わらず、アクション部を実行する。上図の例では、以下のビジネスルールが実行される。
- 従業員.手当計算 に '済' 、手当.住宅手当に 0 を設定する。
このように、ルールシートの記述方法は、Javaなどの他のプログラミング言語と大きく異なる。ルールシートとJavaとのプログラム構造の差異については、以下が挙げられる。
- ルールシートは、1つ1つの条件式をAND条件で表現する。
- ルールシートは、条件式でelse文やcase文を利用しない。
ルールシートがこのような構造となる理由は、ルールシートの目的が、「ビジネスルールの可視化」のためである。各条件が「○○○ならば(条件)△△△する(アクション)」のみで表現することにより、プログラミング言語の知識を有さないエンドユーザでもビジネスルールを直感的に理解ができるようになる。これにより、ユーザフレンドリーなシステム構築が可能となる。
ディシジョンテーブル(ルールシート)の保守性の考慮
前述したとおり、ルールシートの目的は「ビジネスルールの可視化」である。そのため、ルールシートを開発する際は、保守性を意識することが重要である。本節では、ルールシートを開発する際の保守性の考慮ポイントについて説明する。
保守性の考慮ポイントの1つとして、「ルールシートの条件のバリエーションをMECE(モレなくダブりなく)に作成する」が挙げられる。先ほど紹介した住宅手当計算のルールシートに対して、「従業員が子持ちの場合は、住宅手当を40,000円、子供手当を子供1人につき10,000円を設定する」のルールを追加した例で説明する。
このルールシートでは、「従業員.年齢 < 30 AND 従業員.子供人数 > 0」の場合は、以下の両方の条件に合致してしまう。そのため、住宅手当が一意に決定しない。
- No.3の条件に合致し、住宅手当に20,000を設定。
- No.4の条件に合致し、住宅手当に40,000を設定。
ルールシートの実行順は、Progress Corticonのオプティマイザが処理性能などを考慮して自動的に決定する。そのため、必ずしもルールシートの番号順に実行するわけではなく、ルールシートを実行してみないと住宅手当を確認することができない。このように、条件にダブりが存在するルールシートの場合では、ルールシートの確認のみでビジネスルールを把握することができない。
また、従業員.住居としては、'賃貸'と'持家'を条件として利用しているが、住居の種類に'社宅'が存在していた場合を考えてみる。「従業員.住居 = '社宅' AND 従業員.子供人数 = 0」は、どの条件にも合致しないため、住宅手当と子供手当は0となる。第三者がこれを確認する場合、住宅手当と子供手当が0となるのは「意図しているもの」なのか、それとも「条件設定のモレ(不具合)」なのか、を判断することができない。このように、条件にモレが存在するルールシートの場合では、ルールシートの確認のみでビジネスルールを把握することができない。
よって、ルールシートは、下図のように条件のバリエーションをMECE(モレなくダブりなく)に作成することが重要となる。Corticon Studioでは、条件のモレやダブりを検知する仕組みが搭載されている。この機能を活用することでMECEなルールシートを確実に作成することができる。
ディシジョンテーブル(ルールシート)のテスト
ルールシートの開発の説明の最後に、本節ではルールシートのテストの実施方法について説明する。また、ルールシートのテストを実施するに当たり、私たちが工夫した点についても紹介する。
BRMSを利用したシステムであっても、Javaなどの他のプログラム言語と同じくルールシート単体でのテストを実施し、品質を確認することが必要となる。Progress Corticonでは、ルールシート(およびルールフロー)のテストをルールテストと呼ばれる資材を作成することで実施する。ルールテストの作成方法は以下のとおりであり、Javaなどの他のプログラム言語と手順は同じである。ルールテストは、ルールシートと同様、Corticon Studioを利用してGUIで作成する。
- ルールシートの入力値を作成する。
- ルールシートの期待値を作成する。
- 入力値をインプットにしてルールシートを実行して、実行結果と期待を比較する。
また、ルールテストのデータバリエーションも、他のプログラム言語のプログラム単体テストと同様、以下の点を考慮して作成する。
- 条件式の網羅(カバレッジ)
- 境界値(前述のルールシートの例では、従業員の年齢を29、30、31でテストを実施する)
- 異例値(0、空文字、NULL値、など)
このようにルールシートの品質を確認するためには、データバリエーションを網羅したテストデータの準備が必要となる。本事例では、プロジェクトの特性上、大量に作成したルールシートに対してのテストを短期間で実施する必要があった。開発対象のルールシートが多い場合、テストデータの準備を行うためのマンパワーも多く必要となるため、私たちはオフショアのマンパワーを活用したテストの準備と実施を計画した。しかし、開発ツールであるCorticon Studioはユーザライセンスであるため、同時に作業を行おうとした場合は、その分のライセンス費用が必要となる。そのため、コスト面から考えて、オフショアでの同時作業の実現は難しいと考えていた。
そこで私たちは、以下の工夫を実施することで、オフショアを活用したテストの準備と実施を実現することができた。
- Progress Corticonの開発サポート製品であるBT4C(Best Tools for Corticon)を利用し、Excelでルールテストの入力値と期待値を作成できるようにする。
- AWS(Amazon Web Services)の東京リージョン上に、Corticon Studioを導入した仮想サーバを構築し、オフショアからアクセスできるようにする。
- オフショアにてExcelでルールテストを作成し、AWSサーバ上のCorticon Studioにインポートして、ルールテストのテストを実行できるようにする。
BT4C(Best Tools for Corticon)は、Excelで作成したルールシートやルールテストをCorticon Studioにインポートすることができる機能である。これにより、Corticon Studioを導入していない開発者がExcelで作成したルールテストをCorticon Studioにインポートし、テストを実行することが可能となり、オフショア拠点の大勢の開発者がルールテストを同時に作成することができる。
また、AWS上のWindows ServerにCorticon Studioを導入し、オフショア拠点からアクセスできるようにする。これにより、オフショアにてExcelで作成したルールテストをCorticon Studioへインポートし、テストを実行することが可能となる。ちなみに、Corticon Studioをオフショア拠点のPCに導入する場合、輸出規約の問題に抵触する。その回避策としてAWSの東京リージョン上の仮想サーバにCorticon Studioをインストールし、オフショア拠点から東京リージョン上のサーバにアクセスさせた。
オフショアを活用したルールシートのテストのフローは、以下のとおりである。
- 東京拠点の開発者は、Corticon Studioを利用してルールシートを作成し、AWS上の構成管理ツール(本事例ではSubversionを利用)にコミットする。
- オフショア拠点の開発者は、Excelを利用してルールテストを作成し、オフショアの管理者に提出する。
- オフショアの管理者は、AWS上のCorticon StudioにExcelで作成したルールテストをインポートして、ルールテストを作成する。
- オフショアの管理者は、AWS上の構成管理ツールからルールシートをチェックアウトし、ルールテストを利用してテストを実行する。
これにより、開発ボリュームが大きくなった場合でも、Corticon Studioのライセンス料を最適化しながら、ルールシートのテストを推進することが可能となる。
BRMSを呼び出すJavaの開発
前章では、BRMS自体の開発方法および考慮ポイントについて説明をした。本章では、BRMSを利用してビジネスルールを実行し、エンドユーザに処理結果を提供するJavaアプリケーションの開発方法および考慮ポイントについて説明する。
サービスの構成
BRMSを導入する目的の1つは、「ビジネスルール」を業務アプリケーションから切り離すことである。よって、BRMSを呼び出すJavaアプリケーションも、ビジネスルールの切り出しを意識して、以下のようなクラス構成とすべきである。
- ビジネスルールを取り扱うビジネスロジックとビジネスロジック以外(DBアクセスなど)を分離する。
- 制御フローとビジネスロジックを分離する。
上図のように、BRMSにアクセスしてビジネスルールを取り扱うサービスとDBアクセス(参照および更新)を行うサービスは、クラス構成を分離して構築すべきである。理由は、BRMSのビジネスルール(ルールシートやルールフロー)とビジネスルール以外の機能(DBアクセスなど)との依存関係を疎にするためである。これにより、保守時にビジネスルールに改修が発生した場合でも、アプリケーションへの影響を局所化することができる。
また、上図のように、制御フローと各種サービス(ビジネスロジック、DBアクセス)の呼び出しをDI(Dependency Injection)を利用して疎とするべきである。理由は、BRMSのビジネスルール(ルールシートやルールフロー)と制御機能(SOAPの送受信やエラーハンドリング)との依存関係を疎にするためである。これにより、保守時にビジネスルールに改修が発生した場合でも、アプリケーションへの影響を局所化することができる。
ビジネスロジックとDBアクセスの分離について詳細に説明する。これを実現するためには、以下のようにビジネスルールで必要なDBデータを事前に取得してBRMSへ連携することが必要となる。
- DB参照を行うタイミングで、ビジネスルールで利用するDBデータを取得する。
- JavaアプリケーションからProgress Corticonへアクセスするタイミングで、SOAP通信上にDBデータをセットする。
- Progress Corticon上ではDBデータに対応する語彙を作成する。Javaアプリケーションから連携されたDBデータは、その語彙にセットする。
- Progress Corticon上のルールシートは、語彙上にセットされたDBデータを利用する。
しかし、JavaアプリケーションからProgress Corticonへ連携するデータ件数が多い場合は、性能懸念が生じる可能性がある。よって、JavaアプリケーションにてDBからデータを取得するタイミングで、検索条件を指定して可能な限り取得件数を削減することが重要となる。
また、上記以外にも、以下の2つの方式を採用することも可能であるため紹介する。
- Progress Corticonのルールシート上にDBデータを保持させる方式
- ルールシートをRDBのテーブルと見立ててデータを保持させ、他のルールシートからアクセスして利用する方式。
- DBデータの件数が少ない、更新が発生しない、変更頻度が少ない場合のみ採用可能。
- JavaアプリケーションでのDBアクセスやProgress CorticonへのDBデータの連携が不要となるため、性能面で最も優れている方式。
- Progress CorticonからDBアクセスを許容する方式
- EDC(Enterprise Data Connect)を利用して、Progress CorticonからDBアクセスを実現する方式。(以前は追加オプションであったが、2020年7月現在、EDCはVer5.7より標準機能として搭載。)
- DBデータの件数が多く、検索条件による事前の絞り込みが難しい場合に効果が高い。
- ビジネスルールとDBのテーブルの依存度が高まるため、保守性を考慮し、対象テーブルを限定することが必要。
ディシジョンサービスの呼び出し
本節では、JavaアプリケーションからProgress Corticon上のディシジョンサービスへのアクセス方法について説明する。本事例では、Progress CorticonへのアクセスはJAX-WSを利用したSOAP通信を利用する。
Progress Corticonへの連携で利用するSOAP(XMLファイル)のデータ構造は、ディシジョンサービス内のルールシートで利用する語彙のエンティティと属性となる。よって、Javaアプリケーションは、Progress Corticonの語彙に対応するDTOに対して、入力値のセットと処理結果の取得の処理が必要となる。
Progress Corticonとの通信方式がSOAPの場合、必要な手順は以下となる。
1.Progress CorticonのWeb Console(管理コンソール)から、ディシジョンサービスのWSDL(Web Services Description Language)ファイルを取得。 2.ディシジョンサービスのWSDLファイルからJAX-WSの機能を利用して、SOAP通信で利用するアクセス部品およびDTO(Progress Corticonの語彙のエンティティと属性と同じ構成となる)を自動生成。 3.自動生成したDTOへ入力値をセットするロジックを実装。 4.自動生成したアクセス部品を利用してProgress Corticonにアクセスするロジックを実装。 5.自動生成したDTOから処理結果を取得するロジックを実装。
ディシジョンサービスの保守性と性能の考慮
Javaアプリケーションからアクセスされるディシジョンサービスを、どのような単位で作成するかを設計することが非常に重要となる。本節では、ディシジョンサービスを作成する際の保守性と性能の考慮ポイントについて説明する。
まず、ディシジョンサービス(ルールフロー)には、同じ用途(同じエンティティや属性を利用する)ルールシートを紐づけるべきである。それを実施することのメリットは、以下のとおりである。
- ルールフロー内に同種のビジネスルールが集まることになるため、保守性が向上する。
- Javaからセットするエンティティと属性の種類が減るため、DTOとのデータ移送の処理量とSOAPの通信量が減り処理性能が向上する。
しかし、ルールフローの単位を細かくし過ぎた場合、JavaアプリケーションからのProgress Corticonへのアクセス回数が多くなる。その場合、以下のデメリットが生じてしまう。
- 前節で説明した、JavaアプリケーションからProgress Corticonへの連携処理の実装が必要となるため、開発コストが増える。
- JavaアプリケーションとProgress Corticon Server間の通信処理回数が増えるため、性能懸念が生じる。
- JavaアプリケーションでのDTOとのデータ移送の処理回数が増えるため、性能懸念が生じる。
上記を考慮するためには、まず、1つ1つのルールシートに着目して設計・開発を行うのではなく、全体(ルールシート間の関連や依存)を俯瞰して設計する必要がある。また、BRMSのみ着目して設計・開発を行うのではなく、利用する側(Javaアプリケーション)を考慮して設計する必要がある。すなわち、部分最適ではなく全体最適でアプリケーションを設計し、構築する必要がある。
CI/CDを活用した品質確保
最後に本節では、Progress Corticonを利用したオンラインシステム全体の品質を積み上げるために、本事例で私たちが採用したCI/CDの仕組みについて紹介する。
実現したCI/CDの仕組みは以下のとおりである。
- BRMSのディシジョンサービスの実行モジュールであるEDSファイルを、Corticon Web Console(管理コンソール)を利用して開発環境のCorticon Serverへデプロイ。
- Javaアプリケーションを、Jenkinsを利用して日次でビルドおよび開発環境のAPサーバ(JBoss EAP)へデプロイ。
- 「JavaアプリケーションへのSOAP通信」と「処理結果の実際値(SOAPおよびDBデータ)と期待値との比較」を実施するJUNITを作成し、Jenkinsを利用して日次で全件テストを実行。
日次でProgress CorticonのディシジョンサービスとJavaアプリケーションをインテグレーション(統合)する。さらに、JUnitを利用したリグレッションテストを実施することで、BRMSとJavaアプリケーションの両方の品質を常に高い状態で保つことが可能となる。これにより、安全な本番リリースを実現することができる。
おわりに
本ドキュメントでは、特に保守性と品質に着目して説明させて頂いた。
本事例を経験して、私たちは「BRMSを導入すれば、ビジネスルールの見える化が実現されシステムのアジリティが向上する」ことは正しいと感じている。しかし、BRMSの恩恵を受けられる形でBRMSのディシジョンテーブルとBRMSを利用するアプリケーションを開発しなければ、保守性の高いシステムの構築は実現できないことも理解した。
また、BRMSと言えども、他のプログラミング言語で開発したアプリケーションと同様に品質の積み上げは最重要であることも理解した。そのためには、一般的なJava開発と同様に、テストプロセスの工夫やCI/CDなどの仕組みの導入を検討することが必要となる。
本事例の案件開始時点では、私たちはProgress Corticonの製品仕様に対しての知識は研修を通して習得していた。しかし、上記の点については理解できていない状態であったため、実装やテストのフェーズにて後戻りが発生し、開発の方針展開を何回も繰り返してしまった。よって、次にBRMSを利用したシステム構築を行う際には、本ドキュメントで記載した以下のポイントについてを開発開始前にメンバーに展開し、理解してもらうことが重要であると考えている。
- BRMSのディシジョンテーブルの開発方法および考慮ポイント
- BRMSを利用するアプリケーションの開発方法および考慮ポイント
また、テストプロセスやCI/CDについても改善を図っていきたい。例えば、本事例では以下については手作業での実施を行ったが、Jenkinsを利用した自動化も実現可能であり、導入効果も高いと判断している。
- Progress Corticonのルールテストの全量実行の自動化
- Progress Corticonのディシジョンサービスの実行モジュール(EDSファイル)の作成とデプロイの自動化
これからBRMSを利用したシステム開発を挑戦しようとしている人、すでに挑戦していて進め方に悩んでいる人にとって当事例が少しでも参考になり、開発成功の助けになることを願う。