第5章 DMN を使用した Red Hat build of Kogito マイクロサービスのアプリケーションロジックの設計
プロジェクトを作成したら、プロジェクトの src/main/resources
ディレクトリーに、Decision Model and Notation (DMN) デシジョンモデルと Drools Rule Language (DRL) ビジネスルールを作成またはインポートできます。また、Java サービスとして動作するプロジェクトの src/main/java
ディレクトリーに Java クラスを含めるか、デシジョンから呼び出す実装を指定することもできます。
この手順の例では、基本的な Red Hat build of Kogito マイクロサービスが REST エンドポイント /persons
を提供します。このエンドポイントは、PersonDecisions.dmn
DMN モデルのサンプルをもとに自動生成され、処理されたデータをベースに意思決定を行います。
ビジネスデシジョンには、Red Hat Decision Manager サービスのデシジョンロジックが含まれます。DMN モデルや DRL ルールなど、ビジネスルールやデシジョンをさまざまな方法で定義できます。この手順の例では、DMN モデルを使用します。
前提条件
- プロジェクトを作成している。Maven プロジェクトの作成方法は 3章Red Hat build of Kogito マイクロサービスの Maven プロジェクトの作成 を参照してください。
手順
Red Hat Decision Manager サービス用に生成した Maven プロジェクトで
src/main/java/org/acme
フォルダーに移動し、以下のPerson.java
ファイルを追加します。person Java オブジェクトの例
package org.acme; import java.io.Serializable; public class Person { private String name; private int age; private boolean adult; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isAdult() { return adult; } public void setAdult(boolean adult) { this.adult = adult; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", adult=" + adult + "]"; } }
この例では、Java オブジェクトの名前、年齢、成人ステータスを設定して取得します。
src/main/resources
フォルダーに移動し、以下のPersonDecisions.dmn
DMN デシジョンモデルを追加します。図5.1
PersonDecisions
の DMN 意思決定要件ダイアグラム (DRD) 例図5.2
isAdult
デシジョンの DMN ボックス式の例図5.3 DMN データ型の例
この DMN モデルは、基本的な DMN 入力ノードと、カスタムの構造化データ型で DMN デシジョンテーブルが定義したデシジョンノードで構成されます。
VS Code では、Red Hat Business Automation Bundle VS Code 拡張機能を追加して、DMN モデラーで意思決定要件ダイアグラム (DRD)、ボックス式、およびデータタイプを設計できます。
この DMN モデルの例を迅速に作成するには、以下の
PersonDecisions.dmn
ファイルの内容をコピーします。DMN ファイルの例
<dmn:definitions xmlns:dmn="http://www.omg.org/spec/DMN/20180521/MODEL/" xmlns="https://kiegroup.org/dmn/_52CEF9FD-9943-4A89-96D5-6F66810CA4C1" xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/" xmlns:kie="http://www.drools.org/kie/dmn/1.2" xmlns:dmndi="http://www.omg.org/spec/DMN/20180521/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" xmlns:feel="http://www.omg.org/spec/DMN/20180521/FEEL/" id="_84B432F5-87E7-43B1-9101-1BAFE3D18FC5" name="PersonDecisions" typeLanguage="http://www.omg.org/spec/DMN/20180521/FEEL/" namespace="https://kiegroup.org/dmn/_52CEF9FD-9943-4A89-96D5-6F66810CA4C1"> <dmn:extensionElements/> <dmn:itemDefinition id="_DEF2C3A7-F3A9-4ABA-8D0A-C823E4EB43AB" name="tPerson" isCollection="false"> <dmn:itemComponent id="_DB46DB27-0752-433F-ABE3-FC9E3BDECC97" name="Age" isCollection="false"> <dmn:typeRef>number</dmn:typeRef> </dmn:itemComponent> <dmn:itemComponent id="_8C6D865F-E9C8-43B0-AB4D-3F2075A4ECA6" name="Name" isCollection="false"> <dmn:typeRef>string</dmn:typeRef> </dmn:itemComponent> <dmn:itemComponent id="_9033704B-4E1C-42D3-AC5E-0D94107303A1" name="Adult" isCollection="false"> <dmn:typeRef>boolean</dmn:typeRef> </dmn:itemComponent> </dmn:itemDefinition> <dmn:inputData id="_F9685B74-0C69-4982-B3B6-B04A14D79EDB" name="Person"> <dmn:extensionElements/> <dmn:variable id="_0E345A3C-BB1F-4FB2-B00F-C5691FD1D36C" name="Person" typeRef="tPerson"/> </dmn:inputData> <dmn:decision id="_0D2BD7A9-ACA1-49BE-97AD-19699E0C9852" name="isAdult"> <dmn:extensionElements/> <dmn:variable id="_54CD509F-452F-40E5-941C-AFB2667D4D45" name="isAdult" typeRef="boolean"/> <dmn:informationRequirement id="_2F819B03-36B7-4DEB-AED6-2B46AE3ADB75"> <dmn:requiredInput href="#_F9685B74-0C69-4982-B3B6-B04A14D79EDB"/> </dmn:informationRequirement> <dmn:decisionTable id="_58370567-05DE-4EC0-AC2D-A23803C1EAAE" hitPolicy="UNIQUE" preferredOrientation="Rule-as-Row"> <dmn:input id="_ADEF36CD-286A-454A-ABD8-9CF96014021B"> <dmn:inputExpression id="_4930C2E5-7401-46DD-8329-EAC523BFA492" typeRef="number"> <dmn:text>Person.Age</dmn:text> </dmn:inputExpression> </dmn:input> <dmn:output id="_9867E9A3-CBF6-4D66-9804-D2206F6B4F86" typeRef="boolean"/> <dmn:rule id="_59D6BFF0-35B4-4B7E-8D7B-E31CB0DB8242"> <dmn:inputEntry id="_7DC55D63-234F-497B-A12A-93DA358C0136"> <dmn:text>> 18</dmn:text> </dmn:inputEntry> <dmn:outputEntry id="_B3BB5B97-05B9-464A-AB39-58A33A9C7C00"> <dmn:text>true</dmn:text> </dmn:outputEntry> </dmn:rule> <dmn:rule id="_8FCD63FE-8AD8-4F56-AD12-923E87AFD1B1"> <dmn:inputEntry id="_B4EF7F13-E486-46CB-B14E-1D21647258D9"> <dmn:text><= 18</dmn:text> </dmn:inputEntry> <dmn:outputEntry id="_F3A9EC8E-A96B-42A0-BF87-9FB1F2FDB15A"> <dmn:text>false</dmn:text> </dmn:outputEntry> </dmn:rule> </dmn:decisionTable> </dmn:decision> <dmndi:DMNDI> <dmndi:DMNDiagram> <di:extension> <kie:ComponentsWidthsExtension> <kie:ComponentWidths dmnElementRef="_58370567-05DE-4EC0-AC2D-A23803C1EAAE"> <kie:width>50</kie:width> <kie:width>100</kie:width> <kie:width>100</kie:width> <kie:width>100</kie:width> </kie:ComponentWidths> </kie:ComponentsWidthsExtension> </di:extension> <dmndi:DMNShape id="dmnshape-_F9685B74-0C69-4982-B3B6-B04A14D79EDB" dmnElementRef="_F9685B74-0C69-4982-B3B6-B04A14D79EDB" isCollapsed="false"> <dmndi:DMNStyle> <dmndi:FillColor red="255" green="255" blue="255"/> <dmndi:StrokeColor red="0" green="0" blue="0"/> <dmndi:FontColor red="0" green="0" blue="0"/> </dmndi:DMNStyle> <dc:Bounds x="404" y="464" width="100" height="50"/> <dmndi:DMNLabel/> </dmndi:DMNShape> <dmndi:DMNShape id="dmnshape-_0D2BD7A9-ACA1-49BE-97AD-19699E0C9852" dmnElementRef="_0D2BD7A9-ACA1-49BE-97AD-19699E0C9852" isCollapsed="false"> <dmndi:DMNStyle> <dmndi:FillColor red="255" green="255" blue="255"/> <dmndi:StrokeColor red="0" green="0" blue="0"/> <dmndi:FontColor red="0" green="0" blue="0"/> </dmndi:DMNStyle> <dc:Bounds x="404" y="311" width="100" height="50"/> <dmndi:DMNLabel/> </dmndi:DMNShape> <dmndi:DMNEdge id="dmnedge-_2F819B03-36B7-4DEB-AED6-2B46AE3ADB75" dmnElementRef="_2F819B03-36B7-4DEB-AED6-2B46AE3ADB75"> <di:waypoint x="504" y="489"/> <di:waypoint x="404" y="336"/> </dmndi:DMNEdge> </dmndi:DMNDiagram> </dmndi:DMNDI> </dmn:definitions>
DMN モデラーを使用して VS Code でこの DMN モデルのサンプルを作成するには、以下の手順に従います。
-
空の
PersonDecisions.dmn
ファイルを開き、DMN モデラーの右上隅にある Properties アイコンをクリックし、DMN モデル Name がPersonDecisions
に設定されていることを確認します。 -
左側のパレットで DMN Input Data を選択し、ノードをキャンバスにドラッグしてから、ノードをダブルクリックして名前を
Person
とします。 -
左側のパレットで DMN Decision ノードをキャンバスにドラッグし、ノードをダブルクリックして名前を
isAdult
にし、入力ノードからリンクします。 - ノードオプションを表示するデシジョンノードを選択して Edit アイコンをクリックし、DMN ボックス式エディターを開き、ノードのデシジョンロジックを定義します。
- undefined expression フィールドをクリックし、Decision Table を選択します。
- デシジョンテーブルの左上隅をクリックして、ヒットポリシーを Unique に設定します。
タイプが
number
の入力ソースPerson.Age
で、年齢制限を、タイプがboolean
の出力ターゲットisAdult
で成人ステータスを判断できるように、入出力コラムを設定します。図5.4 デシジョンが
isAdult
の DMN デシジョンテーブルの例右上のタブで Data Types タブを選択して、以下の
tPerson
構造のデータ型とネスト化データタイプを追加します。図5.5 DMN データ型の例
- データタイプを定義したら、Editor タブを選択して、DMN モデラーキャンバスに戻ります。
-
Person 入力ノードを選択し、Properties アイコンをクリックし、Information item の下にある Data type を
tPerson
に設定します。 -
isAdult デシジョンノードを選択し、Properties アイコンをクリックして、Information 項目 で Data type がまだ
boolean
に設定されていることを確認します。デシジョンテーブルの作成時に、このデータ型を設定してください。 - DMN デシジョンサービスを保存します。
-
空の
5.1. 別のデシジョンサービスとしての DRL ルールユニットの使用
また、ルールユニットとして実装した Drools Rule Language (DRL) ファイルを使用して、Decision Model and Notation (DMN) を使用する代わりに、このサンプルデシジョンサービスを定義することもできます。
DRL ルールユニットは、ルールのモジュールおよび、実行ユニットです。ルールユニットは、ルール実行のファクトタイプの宣言を使用して、一連のルールを収集します。また、ルールユニットは、各ルールグループに固有の namespace としても機能します。1 つのルールベースには、複数のルールユニットを含めることができます。通常、ユニットだけで自己完結できるように、ユニットの全ルールはユニット宣言と同じファイルに保存します。ルールユニットの作成方法は、Designing a decision service using DRL rules を参照してください。
前提条件
- プロジェクトを作成している。Maven プロジェクトの作成方法は 3章Red Hat build of Kogito マイクロサービスの Maven プロジェクトの作成 を参照してください。
手順
DMN ファイルを使用する代わりに、サンプルプロジェクトの
src/main/resources
ディレクトリーに、以下のPersonRules.drl
ファイルを追加します。PersonRules
DRL ファイルの例package org.acme unit PersonRules; import org.acme.Person; rule isAdult when $person: /person[ age > 18 ] then modify($person) { setAdult(true) }; end query persons $p : /person[ adult ] end
このルールの例では、18 歳以上を成人として分類しているかどうかを判断します。また、ルールファイルは、ルールがルールユニット
PersonRules
に属することを宣言します。プロジェクトをビルドすると、ルールユニットが生成され、DRL ファイルに関連付けられます。ルールは OOPath 表記を使用して条件も定義します。OOPath は、Xpath のオブジェクト指向の構文拡張で、コレクションおよびフィルター制約を処理しながら、関連要素間を移動します。
以下の例のように、従来のルールパターン構文を使用して、より明示的な形式で同じルール条件を再書き込みすることもできます。
従来の表記を使用した
PersonRules
DRL ファイルの例package org.acme unit PersonRules; import org.acme.Person; rule isAdult when $person: Person(age > 18) from person then modify($person) { setAdult(true) }; end query persons $p : /person[ adult ] end