レッドハットのソリューションアーキテクトの森です。
Red Hat Decision Manager / Process Automation Manager は、VSCode 拡張機能のサポートが提供され、Visual Studio Code (VSCode) で BPMN モデル、 DMN モデル、及びテストシナリオを可視化し、設計できるようになりました。
今回は、VSCode で DMNモデルを用いて簡単なルールを作成して動かしてみたいと思います。
必要なセット
- VSCode
- Red Hat Business Automation Bundle (VSCode拡張機能)
- KIE Server (RHDM/PAM に 含まれている、REST API でルールを実行できるサーバアプリ)
- Java 11
- Maven
- Git
DMN について
DMN (Decision Model and Notation) は、業務的意思決定を説明してモデル化するための表記法です。OMG (Object Management Group)によって定義されています。 業務ルールを整理し定義する際に、DMNを使うことで、要件定義・設計・実装における認識の齟齬を低減し、開発効率と品質を向上することが期待されます。 DMNの基本については、こちらも合わせてご覧いただければと思います。
ルールの要件
今回は、ドライバーが交通違反をした時の罰則の判断(罰金・減点)と、免許停止の判断をサンプルとして作ってみます。
- 違反の内容が 速度超過 で、超過速度が 10km/h 以上、30km/h 未満の場合、違反点数 3、罰金 500
- 違反の内容が 速度超過 で、超過速度が 30km/h 以上の場合、違反点数 7、罰金 1000
- 違反の内容が 駐車違反の場合、違反点数 1、罰金 100
- 違反の内容が 飲酒運転の場合、違反点数 5、罰金 1000
- 違反点数が 累計 20 以上の場合、免許停止となる
プロジェクトの作成
まずは Maven アーキタイプを使用して、新しいプロジェクトを作成します。
mvn archetype:generate \
-DarchetypeGroupId=org.kie \
-DarchetypeArtifactId=kie-kjar-archetype \
-DarchetypeVersion=7.48.0.Final-redhat-00004
※ Red Hat Maven Repository(https://maven.repository.redhat.com/ga/) を ~/.m2/settings.xml に設定しておく必要があります。
設定例:
1) 以下の XML を settings.xml ファイルの <profiles> 要素へコピーします。
<!-- Configure the JBoss Enterprise Maven repository -->
<profile>
<id>jboss-enterprise-maven-repository</id>
<repositories>
<repository>
<id>jboss-enterprise-maven-repository</id>
<url>https://maven.repository.redhat.com/ga/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss-enterprise-maven-repository</id>
<url>https://maven.repository.redhat.com/ga/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
2) 以下の XML を settings.xml ファイルの <activeProfiles> 要素へコピーします。
<activeProfile>jboss-enterprise-maven-repository</activeProfile>
※ 7.48.0.Final-redhat-00004 は RHDM 7.10 に対応しています。
デフォルトのGAV(group:artifact:version)を使用してプロジェクトを作成するかを聞かれますので、一旦そのままとしておきます。

DNM ファイルの作成
次に、src/main/resource 配下のフォルダに、traffic-violation.dmn というファイルを作成します。

ファイルを作成すると、以下のような DMN エディタが開きます。

DMN エディタが開いたら、入力データノードを2つキャンバスに配置し、それぞれ、ドライバー情報, 違反情報 と名前を変更します。
(名前の変更はノードをダブルクリックするか、右側のプロパティパネルの Name を変更します)
続いて、罰則の内容を判断するデシジョンと、免許停止かどうかを判断するデシジョンを作成します。
デシジョンノードを2つキャンバスに配置し、それぞれ、罰則, 免許停止 と名前を変更します。
入力データノード 違反情報 から、デシジョンノード 罰則 へ、情報要件を用いて接続をします。

以下のように各ノードを接続して下さい。

データ構造の定義
次に、DMN で使用するデータ構造について定義をします。
エディタの上部メニューからデータタイプを選択し、中央の Add a custom Data Type をクリックして下さい。

- Name: ドライバー情報
- タイプ: Structure
と入力し、右側のチェックマークをクリックすると、ドライバー情報 という名前の Structure型 のデータが定義されます。

以下の表に従って、3つの Structure型 を含むデータを定義して下さい。
| Name | タイプ |
|---|---|
| ドライバー情報 | Structure |
| 点数 | number |
| Name | タイプ |
|---|---|
| 違反情報 | Structure |
| タイプ | string |
| 制限速度 | number |
| 違反時速度 | number |
| Name | タイプ |
|---|---|
| 罰則情報 | Structure |
| 罰金 | number |
| 点数 | number |
下記のように定義ができていればOKです。

エディターに戻り、各ノードのデータタイプを定義していきます。
入力データノード ドライバー情報 をクリックし、右側のプロパティパネルの情報アイテムで、データタイプを ドライバー情報 に設定して下さい。

他のノードも、下記の表に従って設定をします。
| ノード | データタイプ |
|---|---|
| ドライバー情報 | ドライバー情報 |
| 違反情報 | 違反情報 |
| 罰則 | 罰則情報 |
| 免許停止 | string |
デシジョンの作成
2つのデシジョン、罰則, 免許停止 について、ルールの定義を行っていきます。
デシジョンノード 罰則 を選択し、編集 をクリックしてデシジョンエディタを開きます。

式の選択をクリックし、デシジョンテーブルを選択します。

条件列として、情報要件で接続した入力データノードの内容が、またアクション列として、デシジョンのデータタイプの内容が既に設定されています。

違反情報.違反時速度 の列を、違反情報.違反時速度 - 違反情報.制限速度 に修正をして、
違反情報.制限速度 の列を削除します。
次に、罰則のルールの要件に従って条件とアクションを作成していきます。
下記の表のように各行を設定をして下さい。

[10..30) は、10以上、30未満(10 ≦ x < 30)という意味になります。
続いて、デシジョンノード 免許停止 を選択し、編集 をクリックしてデシジョンエディタを開きます。
式の選択をクリックし、コンテキストを選択します。

ContextEntry-1 をクリックして、Name に 累計点数 、データタイプ に number と入力します。

累計点数 の右の式の選択をクリックして文字式を選択し、ドライバー情報.点数 + 罰則.点数 と入力します。
次に、<result> の右の式の選択をクリックして文字式を選択し、if 累計点数 >= 20 then "はい" else "いいえ" と入力します。

こちらの記述式については、FEEL(Friendly Enough Expression Language) という言語で、簡単に計算等のロジックを記述できます。 DMN における FEEL の詳細は OMG の Decision Model and Notation specification を参照してみてください。
以上で、DMN の作成については完了です!
シナリオテスト
VSCode拡張機能を使って、DMN のテストシナリオを作成することができます。
テストシナリオを使用するには、プロジェクトに以下の依存関係を追加する必要があります。
- junit:junit
- org.drools:drools-scenario-simulation-backend
- org.drools:drools-scenario-simulation-api
org.drools については、org.kie と バージョンを合わせる必要があります。
今回のサンプルでは、RHDM 7.10 を使用しており、7.48.0.Final-redhat-00004 となります。
プロジェクトの pom.xml を開き、次の依存関係を追加して下さい。
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-scenario-simulation-api</artifactId>
<version>${version.org.kie}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-scenario-simulation-backend</artifactId>
<version>${version.org.kie}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
次に、src/test/java 配下のフォルダに、testscenario というフォルダを作成します。
そのフォルダの中に、下記の内容で ScenarioJunitActivatorTest.java というファイルを作成しておくことで、Junit と一緒にテストシナリオを実行できるようになります。
package testscenario;
@org.junit.runner.RunWith(org.drools.scenariosimulation.backend.runner.ScenarioJunitActivator.class)
public class ScenarioJunitActivatorTest {
}

それでは、テストシナリオを作成していきます。
src/test/resources 配下のフォルダに、org/kie/businessapp というフォルダを作成し、その中に Violation_Scenarios.scesim というファイルを作成します。
テストシナリオのエディタが開きますので、下記を指定します。
- Source type: DMN
- Choose a valid DMN asset from the list: traffic-violation.dmn

入力と期待値については、列が既に設定されています。 いくつかのパターンで、シナリオを作成してみて下さい。
テストを実行するには、ターミナルから mvn test を実行するか、ScenarioJunitActivatorTest.java ファイルを右クリックして、Run java を選択します。

テストの結果が問題なければ、mvn clean install を実行して、プロジェクトがコンパイルできることを確認します。
KIE Server の準備
ルールを実行するための KIE Server を準備します。 Red Hat Customer Portal にログインして、下記ファイルをダウンロードします。
1) jboss-eap-7.3.0.zip を解凍します。解凍したファイルを格納したフォルダを、仮に $EAP_HOME としておきます。
2) rhdm-7.10.0-kie-server-ee8.zip を $EAP_HOME フォルダ内に解凍します。
3) $EAP_HOME/SecurityPolicy フォルダ配下のファイルを、$EAP_HOME/bin/ に移動します。
mv SecurityPolicy/* $EAP_HOME/jboss-eap-7.3/bin/
4) $EAP_HOME/kie-server.war フォルダを、$EAP_HOME/standalone/deployments/に移動します。
mv kie-server.war/ $EAP_HOME/jboss-eap-7.3/standalone/deployments/
5) kie-server.war を自動デプロイするための .dodeploy ファイルを作成します。
touch $EAP_HOME/jboss-eap-7.3/standalone/deployments/kie-server.war.dodeploy
6) KIE Server REST 機能にアクセス可能なユーザを追加します。パスワードは 8 文字以上で、数字と、英数字以外の文字をそれぞれ 1 文字以上使用する必要があります。ただし & の文字は使用できません。<USERNAME> と <PASSWORD> 書き換えて実行してください。
$EAP_HOME/jboss-eap-7.3/bin/add-user.sh -a --user <USERNAME> --password <PASSWORD> --role kie-server,admin
7) EAP を起動します。
$EAP_HOME/jboss-eap-7.3/bin/standalone.sh -c standalone-full.xml
8) 設定したユーザとパスワードを使用して、ブラウザから http://localhost:8080/kie-server/services/rest/server にアクセスできればOKです。
デプロイ
今回は、KIE Server REST API を使用して、DMN を含むプロジェクトをデプロイしていきます。
まず、ブラウザで KIE Server REST API を開きます。(デフォルトの設定でローカル上に起動している場合は、 http://localhost:8080/kie-server/docs )

KIE Server and KIE containers のメニューから、[PUT] /server/containers/{containerId} を開き、Try it out をクリックします。
下記の内容を入力します。
- containerId: mybusinessapp
- body:
{
"container-id": "mybusinessapp",
"release-id": {
"group-id": "org.kie.businessapp",
"artifact-id": "mybusinessapp",
"version": "1.0"
}
}
- Parameter content type: application/json

Execute をクリックし、下記のような実行結果が出力されればOKです。

それでは、KIEServer へデプロイした DMN を実行してみましょう。

DMN models のメニューから、[POST] /server/containers/{containerId}/dmn を開き、Try it out をクリックします。
- containerId: mybusinessapp
- body:
{
"dmn-context": {
"ドライバー情報": {
"点数": 17
},
"違反情報": {
"タイプ": "速度超過",
"制限速度": 100,
"違反時速度": 120
}
}
}
- Parameter content type: application/json
- Response content type: application/json

正しく実行できていれば、下記のような出力が帰ってくるはずです。

いかがでしたでしょうか?
VSCode拡張機能 を使うことで、BPMN モデル、DMN モデル の開発がしやすくなっていると思います。
ぜひ試してみて下さい。