第4章 Business Central における DRL ルールの作成
Business Central で、プロジェクトに対して DRL ルールを作成して管理できます。パッケージに作成またはインポートするデータオブジェクトに基づいて、各 DRL ファイルで、ルールの条件、アクション、そしてルールに関連するその他のコンポーネントを定義します。
手順
- Business Central で、Menu → Design → Projects に移動して、プロジェクト名をクリックします。
- Add Asset → DRL file をクリックします。
参考となる DRL ファイル 名を入力し、適切な パッケージ を選択します。指定するパッケージは、必要なデータオブジェクトが割り当てられているか、またはこれから割り当てるパッケージにする必要があります。
ドメイン固有言語 (DSL) アセットがプロジェクトに定義されている場合は、Show declared DSL sentences を選択することもできます。これらの DSL アセットは、DRL デザイナーで定義する条件およびアクションに使用できるオブジェクトです。
OK をクリックして、ルールアセットを作成します。
新しい DRL ファイルが、Project Explorer の DRL パネルに追加されます。Show declared DSL sentences オプションを選択した場合は、DSLR パネルに追加されます。この DRL ファイルを割り当てたパッケージは、ファイルの上部にリストされます。
-
DRL デザイナーの左パネルの Fact types リストで、ルールに必要なすべてのデータオブジェクトとデータオブジェクトフィールドがリストされていることを確認します (それぞれを展開します)。リストされていない場合は、DRL ファイルの
importステートメントを使用してその他のパッケージから関連するデータオブジェクトをインポートするか、またはパッケージにデータオブジェクトを作成します。 データオブジェクトをすべて配置したら、DRL デザイナーの Model タブに戻り、以下のいずれかのコンポーネントで DRL ファイルを定義します。
DRL ファイル内のコンポーネント
package import function // Optional query // Optional declare // Optional global // Optional rule "rule name" // Attributes when // Conditions then // Actions end rule "rule2 name" ...-
package: (自動) これは、DRL ファイルを作成し、パッケージを選択すると定義されます。 import: このパッケージ、または DRL ファイルで使用する別のパッケージのデータオブジェクトを指定します。パッケージとデータオブジェクトはpackageName.objectNameの形式で指定し、複数のインポートは別々の行に指定します。データオブジェクトのインポート
import org.mortgages.LoanApplication;
function: (任意) DRL ファイルのルールが使用する関数を指定します。DRL ファイルの関数は、Java クラスにではなくルールのソースファイルにセマンティックコードを追加します。関数は、特に、ルールのアクション (then) 部分が繰り返し使用され、パラメーターだけがルールごとに異なる場合に便利です。DRL ファイルのルールで、関数を宣言したり、静的メソッドを関数としてインポートしたりして、ルールの アクション (then) 部分に、名前を指定して関数を使用します。ルールに関数を宣言して使用 (オプション 1)
function String hello(String applicantName) { return "Hello " + applicantName + "!"; } rule "Using a function" when // Empty then System.out.println( hello( "James" ) ); endルールに関数をインポートして使用 (オプション 2)
import function my.package.applicant.hello; rule "Using a function" when // Empty then System.out.println( hello( "James" ) ); endquery: (オプション) DRL ファイル内のルールに関連するファクトのデシジョンエンジンのワーキングメモリーを検索します。DRL ファイルにクエリー定義を追加してから、アプリケーションコードで合致する結果を取得します。クエリーは、定義した条件セットを検索するため、whenまたはthenを指定する必要はありません。クエリー名は KIE ベースでグローバルとなるため、プロジェクトにあるその他のすべてのルールクエリーと重複しないようにする必要があります。クエリーの結果に戻るには、ksession.getQueryResults("name")を使用して従来の、QueryResults定義を構成します ("name"はクエリー名)。これにより、クエリーの結果が返り、クエリーに一致したオブジェクトを取得できるようになります。DRL ファイルのルールに、クエリーと、クエリー結果パラメーターを定義します。DRL ファイルにおけるクエリー定義の例
query "people under the age of 21" $person : Person( age < 21 ) endクエリー結果を取得するためのアプリケーションコードの例
QueryResults results = ksession.getQueryResults( "people under the age of 21" ); System.out.println( "we have " + results.size() + " people under the age of 21" );
declare: (任意) DRL ファイルのルールが使用する新しいファクトタイプを宣言します。Red Hat Process Automation Manager のjava.langパッケージのデフォルトはObjectですが、必要に応じて DRL ファイルに別のタイプを宣言することもできます。DRL ファイルにファクトタイプを宣言すると、Java などの低級言語でモデルを作成せず、デシジョンエンジンに直接新しいファクトモデルを定義するようになります。新しいファクトタイプの宣言および使用
declare Person name : String dateOfBirth : java.util.Date address : Address end rule "Using a declared type" when $p : Person( name == "James" ) then // Insert Mark, who is a customer of James. Person mark = new Person(); mark.setName( "Mark" ); insert( mark ); endglobal: (オプション) DRL ファイルのルールで使用するグローバル変数を組み込みます。グローバル変数は通常、ルールの結果で使用するアプリケーションサービスなど、ルールのデータやサービスを提供し、ルールの結果で追加されるログや値など、ルールからのデータを返します。KIE セッション設定や REST 操作を使用してデシジョンエンジンのワーキングメモリーにグローバル値を設定し、DRL ファイルのルールの上にグローバル変数を宣言してから、これをルールのアクション部分 (then) で使用します。グローバル変数が複数ある場合には、DRL ファイルで別々の行を使用してください。デシジョンエンジンに対するグローバルリストの設定
List<String> list = new ArrayList<>(); KieSession kieSession = kiebase.newKieSession(); kieSession.setGlobal( "myGlobalList", list );
ルールでのグローバルリストの定義
global java.util.List myGlobalList; rule "Using a global" when // Empty then myGlobalList.add( "My global list" ); end警告グローバル変数に定数イミュータブル値がない場合には、ルールの条件設定にグローバル変数を使用しないでください。グローバル変数はデシジョンエンジンのワーキングメモリーに挿入されないため、デシジョンエンジンでは変数の値の変更を追跡できません。
グローバル変数を使用してルール間でデータを共有しないでください。ルールは常に、ワーキングメモリーの状態に関して推論し、これに対応するので、ルールからルールにデータを渡す必要がある場合には、データをファクトとしてデシジョンエンジンのワーキングメモリーにアサートしてください。
rule: DRL ファイルで各ルールを定義します。ルールは、rule "name"形式のルール名に、ルールの動作 (salience、no-loopなど) を定義する任意の属性、whenおよびthen定義が続きます。ルールのパッケージ内の各ルールには一意の名前が必要です。ルールのwhen部分には、アクションを実行するために満たす必要のある条件が含まれます。たとえば、銀行が、ローンの申し込みを 21 歳以上に限定した場合、"Underage"ルールのwhen条件はApplicant( age < 21 )になります。ルールのthen部分には、ルールの条件部分が満たされる場合に実行するアクションが含まれます。たとえば、ローンの申請者が 21 歳に満たない場合、thenアクションはsetApproved( false )になり、申込者が年齢条件を満たしていないためにローンの申し込みは承認されません。申込者の年齢制限に関するルール
rule "Underage" salience 15 when $application : LoanApplication() Applicant( age < 21 ) then $application.setApproved( false ); $application.setExplanation( "Underage" ); end少なくても、各 DRL ファイルは
packageコンポーネント、importコンポーネント、ruleコンポーネントを指定する必要があります。他のすべてのコンポーネントは任意です。以下は、ローン申し込みのデシジョンサービスの DRL ファイルの例です。
ローン申し込みの DRL ファイルの例
package org.mortgages; import org.mortgages.LoanApplication; import org.mortgages.Bankruptcy; import org.mortgages.Applicant; rule "Bankruptcy history" salience 10 when $a : LoanApplication() exists (Bankruptcy( yearOfOccurrence > 1990 || amountOwed > 10000 )) then $a.setApproved( false ); $a.setExplanation( "has been bankrupt" ); delete( $a ); end rule "Underage" salience 15 when $application : LoanApplication() Applicant( age < 21 ) then $application.setApproved( false ); $application.setExplanation( "Underage" ); delete( $application ); end
図4.1 Business Central のロール申し込み用の DRL ファイルの例

-
- ルールのすべてのコンポーネントを定義したら、DRL デザイナーの右上ツールバーで Validate をクリックし、DRL ファイルを検証します。検証に失敗したら、エラーメッセージに記載された問題に対応し、DRL ファイルの構文およびコンポーネントをすべて見直し、エラーが表示されなくなるまでファイルを検証します。
- DRL デザイナーで Save をクリックして、設定した内容を保存します。
4.1. DRL ルールへの WHEN 条件の追加
ルールの when 部分には、アクションを実行するのに必要な条件が含まれます。たとえば、銀行のローン申し込みに年齢制限 (21 歳以上) を満たす必要がある場合、"Underage" ルールの when 条件は Applicant( age < 21 ) となります。条件は、パッケージで利用可能なデータオブジェクトに基づいて、指定した一連のパターンおよび制約と、任意のバインディングその他のサポートされる DRL 要素で構成されます。
前提条件
-
packageは DRL ファイルに上部に定義されます。これはファイルの作成時に実行されているはずです。 -
ルールで使用したデータオブジェクトの
importリストが、DRL ファイルのpackage行の下に定義されます。データオブジェクトは、このパッケージか、または別の Business Central のパッケージから使用できます。 -
rule名は、package、import、または DRL ファイル全体に適用されるその他の行の下にrule "name"という形式で定義されます。同じパッケージでルール名を重複させることはできません。ルールの動作を定義する任意のルール属性 (salience、no-loopなど) は、ルール名の下のwhenセクションの前に定義します。
手順
DRL デザイナーで、ルールに
whenを入力して、条件ステートメントを追加します。whenセクションは、ルールの条件を定義するファクトパターンで構成されますが、ファクトパターンが 1 つも追加されない場合もあります。whenセクションを空にすると、条件は true であると見なされ、デシジョンエンジンでfireAllRules()呼び出しが最初に実施された場合に、thenセクションのアクションが実行されます。これは、デシジョンエンジンの状態を設定するルールを使用する場合に便利です。条件のないルール例
rule "Always insert applicant" when // Empty then // Actions to be executed once insert( new Applicant() ); end // The rule is internally rewritten in the following way: rule "Always insert applicant" when eval( true ) then insert( new Applicant() ); end一致させる最初の条件のパターンを入力し、任意で制約、バインディング、およびサポートされる DRL 要素を入力します。基本的なパターンフォーマットは
<patternBinding> : <patternType> ( <constraints> )です。パターンは、パッケージで利用可能なデータオブジェクトに基づいており、thenセクションのアクションを発生させるのに必要な条件を定義します。単純なパターン: 制約のない単純なパターンは、指定したタイプのファクトに一致します。たとえば、次は、申込者が存在することだけが条件になります。
when Applicant()
制約のあるパターン: 制約を持つパターンは、指定したタイプのファクトと、追加制限を括弧で指定したパターン (true または false) に一致します。たとえば、次は、申込者が 21 歳に満たないことを条件としています。
when Applicant( age < 21 )
バインディングのあるパターン: パターンのバインディングは簡単な参照となり、ルールのその他のコンポーネントが、定義したバターンに戻って参照します。たとえば、次の例では、
LoanApplicationのバインディングaが、underage の申込者に関連するアクションとして使用されます。when $a : LoanApplication() Applicant( age < 21 ) then $a.setApproved( false ); $a.setExplanation( "Underage" )
このルールに適用するすべての条件パターンの定義を継続します。以下は、DRL 条件を定義するいくつかのキーワードオプションです。
and: 条件コンポーネントを論理積に分類します。接中辞および接頭辞のandがサポートされます。デフォルトでは、結合演算子を指定しないと、リストされているパターンがすべてandで結合されます。// All of the following examples are interpreted the same way: $a : LoanApplication() and Applicant( age < 21 ) $a : LoanApplication() and Applicant( age < 21 ) $a : LoanApplication() Applicant( age < 21 ) (and $a : LoanApplication() Applicant( age < 21 ))
or: 条件コンポーネントを論理和に分類します。接中辞および接頭辞のorがサポートされます。// All of the following examples are interpreted the same way: Bankruptcy( amountOwed == 100000 ) or IncomeSource( amount == 20000 ) Bankruptcy( amountOwed == 100000 ) or IncomeSource( amount == 20000 ) (or Bankruptcy( amountOwed == 100000 ) IncomeSource( amount == 20000 ))
exists: 存在している必要のあるファクトおよび制約を指定します。このオプションは、初回の一致についてのみトリガーされ、後続の一致については無視されます。この要素を複数のパターンで使用する場合は、これらのパターンを括弧()で囲みます。exists ( Bankruptcy( yearOfOccurrence > 1990 || amountOwed > 10000 ) )
not: 存在するべきでないファクトおよび制約を指定します。not ( Applicant( age < 21 ) )
forall: 最初のパターンに一致するすべてのファクトが残りのすべてのパターンに一致するかどうかを検証します。forall構成が満たされると、このルールがtrueと評価されます。forall( $app : Applicant( age < 21 ) Applicant( this == $app, status = 'underage' ) )from: パターンのデータソースを指定します。Applicant( ApplicantAddress : address ) Address( zipcode == "23920W" ) from ApplicantAddress
entry-point: パターンのデータソースに対応するエントリーポイントを定義します。通常はfromと共に使用されます。Applicant() from entry-point "LoanApplication"
collect: ルールを条件の一部として使用できる、オブジェクトのコレクションを定義します。この例では、指定したそれぞれのローンについてデシジョンエンジンで保留されているすべての申し込みがListに分類されます。保留中の申し込みが 3 つ以上ある場合は、このルールが実行されます。$m : Mortgage() $a : List( size >= 3 ) from collect( LoanApplication( Mortgage == $m, status == 'pending' ) )accumulate: オブジェクトのコレクションを処理し、各要素のカスタムアクションを実行し、(制約がtrueと評価されると) 結果オブジェクトを 1 つ以上返します。このオプションは、collectよりも強力で、柔軟性が高いオプションです。accumulate( <source pattern>; <functions> [;<constraints>] )形式を使用します。この例では、min、max、およびaverageは累積関数で、各センサーのすべての測定値から、最低気温、最高気温、平均気温の値を計算します。その他のサポートされる関数には、count、sum、variance、standardDeviation、collectList、およびcollectSetがあります。$s : Sensor() accumulate( Reading( sensor == $s, $temp : temperature ); $min : min( $temp ), $max : max( $temp ), $avg : average( $temp ); $min < 20, $avg > 70 )
注記DRL ルール条件の詳細については、「DRL のルール条件 (WHEN) 」 を参照してください。
- ルールの条件コンポーネントをすべて定義したら、DRL デザイナーの右上のツールバーの Validate をクリックして、DRL ファイルの妥当性を確認します。ファイルの妥当性確認に失敗したら、エラーメッセージに記載された問題に対応し、DRL ファイルの構文およびコンポーネントをすべて見直し、エラーが表示されなくなるまで再度、ファイルを検証します。
- DRL デザイナーで Save をクリックして、設定した内容を保存します。
4.2. DRL ルールへの THEN アクションの追加
ルールの then 部分には、ルールの条件部分が満たされる場合に実行するアクションが含まれます。たとえば、ローンの申請者が 21 歳に満たない場合は、"Underage" ルールの then アクションが setApproved( false ) となり、年齢が基準に達していないためローンの申し込みは承認されません。アクションは、ルールの条件とパッケージで利用可能オブジェクトに基づいて結果を実行する 1 つ以上のメソッドで構成されます。ルールアクションの主な目的は、デシジョンエンジンのワーキングメモリーでデータの挿入、削除、または変更を行うことです。
前提条件
-
packageは DRL ファイルに上部に定義されます。これはファイルの作成時に実行されているはずです。 -
ルールで使用したデータオブジェクトの
importリストが、DRL ファイルのpackage行の下に定義されます。データオブジェクトは、このパッケージか、または別の Business Central のパッケージから使用できます。 -
rule名は、package、import、または DRL ファイル全体に適用されるその他の行の下にrule "name"という形式で定義されます。同じパッケージでルール名を重複させることはできません。ルールの動作を定義する任意のルール属性 (salience、no-loopなど) は、ルール名の下のwhenセクションの前に定義します。
手順
-
DRL デザイナーで、ルールの
whenセクションの後にthenを入力して、アクションステートメントを追加します。 ルールの条件に基づいて、ファクトパターンに対して実行するアクションを 1 つ以上入力します。
以下は、DRL アクションを定義するためのキーワードオプションの例です。
set: これを使用してフィールドの値を設定します。$application.setApproved ( false ); $application.setExplanation( "has been bankrupt" );
modify: ファクトの変更するフィールドを指定し、デシジョンエンジンに変更を通知します。このメソッドを使用することで、ファクトの更新に対する構造化されたアプローチを提供します。このメソッドは、update操作とオブジェクトフィールドを変更する setter 呼び出しを組み合わせたものです。modify( LoanApplication ) { setAmount( 100 ), setApproved ( true ) }update: フィールドと、更新される関連ファクト全体を指定して、その変更をデシジョンエンジンに通知します。ファクトが変更されたら、更新された値の影響を受ける可能性がある別のファクトを変更する前にupdateを呼び出す必要があります。この追加設定を回避するには、代わりにmodifyメソッドを使用します。LoanApplication.setAmount( 100 ); update( LoanApplication );
insert:newファクトをデシジョンエンジンに挿入します。insert( new Applicant() );
insertLogical: デシジョンエンジンにnewファクトを論理挿入する場合に使用します。デシジョンエンジンはファクトの挿入、取り消しに対して論理的な決定を行う役割を担います。通常の挿入または記述による挿入の後は、ファクトは明示的に取り消される必要があります。論理挿入後にファクトを挿入したルールの条件が true ではなくなった場合、挿入されたファクトは自動的に取り消されます。insertLogical( new Applicant() );
delete: デシジョンエンジンからオブジェクトを削除します。キーワードretractも DRL でサポートされており、同じアクションを実行しますが、DRL のコードでは、キーワードinsertとの整合性を考慮してdeleteが通常推奨されます。delete( Applicant );
注記DRL ルールアクションの詳細については、「DRL におけるルールアクション (THEN)」 を参照してください。
- ルールのアクションコンポーネントをすべて定義したら、DRL デザイナーの右上のツールバーの Validate をクリックして、DRL ファイルの妥当性を確認します。ファイルの妥当性確認に失敗したら、エラーメッセージに記載された問題に対応し、DRL ファイルの構文およびコンポーネントをすべて見直し、エラーが表示されなくなるまでファイルを検証します。
- DRL デザイナーで Save をクリックして、設定した内容を保存します。