此内容没有您所选择的语言版本。
Chapter 18. Creating DRL rules in Business Central
You can create and manage DRL rules for your project in Business Central. In each DRL rule file, you define rule conditions, actions, and other components related to the rule, based on the data objects you create or import in the package.
Procedure
-
In Business Central, go to Menu
Design Projects and click the project name. -
Click Add Asset
DRL file. Enter an informative DRL file name and select the appropriate Package. The package that you specify must be the same package where the required data objects have been assigned or will be assigned.
You can also select Show declared DSL sentences if any domain specific language (DSL) assets have been defined in your project. These DSL assets will then become usable objects for conditions and actions that you define in the DRL designer.
Click Ok to create the rule asset.
The new DRL file is now listed in the DRL panel of the Project Explorer, or in the DSLR panel if you selected the Show declared DSL sentences option. The package to which you assigned this DRL file is listed at the top of the file.
-
In the Fact types list in the left panel of the DRL designer, confirm that all data objects and data object fields (expand each) required for your rules are listed. If not, you can either import relevant data objects from other packages by using
import
statements in the DRL file, or create data objects within your package. After all data objects are in place, return to the Model tab of the DRL designer and define the DRL file with any of the following components:
Components in a DRL file
package import function // Optional query // Optional declare // Optional global // Optional rule "rule name" // Attributes when // Conditions then // Actions end rule "rule2 name" ...
-
package
: (automatic) This was defined for you when you created the DRL file and selected the package. import
: Use this to identify the data objects from either this package or another package that you want to use in the DRL file. Specify the package and data object in the formatpackageName.objectName
, with multiple imports on separate lines.Importing data objects
import org.mortgages.LoanApplication;
function
: (optional) Use this to include a function to be used by rules in the DRL file. Functions in DRL files put semantic code in your rule source file instead of in Java classes. Functions are especially useful if an action (then
) part of a rule is used repeatedly and only the parameters differ for each rule. Above the rules in the DRL file, you can declare the function or import a static method from a helper class as a function, and then use the function by name in an action (then
) part of the rule.Declaring and using a function with a rule (option 1)
function String hello(String applicantName) { return "Hello " + applicantName + "!"; } rule "Using a function" when // Empty then System.out.println( hello( "James" ) ); end
Importing and using the function with a rule (option 2)
import function my.package.applicant.hello; rule "Using a function" when // Empty then System.out.println( hello( "James" ) ); end
query
: (optional) Use this to search the decision engine for facts related to the rules in the DRL file. You add the query definitions in DRL files and then obtain the matching results in your application code. Queries search for a set of defined conditions and do not requirewhen
orthen
specifications. Query names are global to the KIE base and therefore must be unique among all other rule queries in the project. To return the results of a query, construct a traditionalQueryResults
definition usingksession.getQueryResults("name")
, where"name"
is the query name. This returns a list of query results, which enable you to retrieve the objects that matched the query. Define the query and query results parameters above the rules in the DRL file.Example query definition in a DRL file
query "people under the age of 21" $person : Person( age < 21 ) end
Example application code to obtain query results
QueryResults results = ksession.getQueryResults( "people under the age of 21" ); System.out.println( "we have " + results.size() + " people under the age of 21" );
declare
: (optional) Use this to declare a new fact type to be used by rules in the DRL file. The default fact type in thejava.lang
package of Red Hat Process Automation Manager isObject
, but you can declare other types in DRL files as needed. Declaring fact types in DRL files enables you to define a new fact model directly in the decision engine, without creating models in a lower-level language like Java.Declaring and using a new fact type
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 ); end
global
: (optional) Use this to include a global variable to be used by rules in the DRL file. Global variables typically provide data or services for the rules, such as application services used in rule consequences, and return data from rules, such as logs or values added in rule consequences. Set the global value in the working memory of the decision engine through a KIE session configuration or REST operation, declare the global variable above the rules in the DRL file, and then use it in an action (then
) part of the rule. For multiple global variables, use separate lines in the DRL file.Setting the global list configuration for the decision engine
List<String> list = new ArrayList<>(); KieSession kieSession = kiebase.newKieSession(); kieSession.setGlobal( "myGlobalList", list );
Defining the global list in a rule
global java.util.List myGlobalList; rule "Using a global" when // Empty then myGlobalList.add( "My global list" ); end
WarningDo not use global variables to establish conditions in rules unless a global variable has a constant immutable value. Global variables are not inserted into the working memory of the decision engine, so the decision engine cannot track value changes of variables.
Do not use global variables to share data between rules. Rules always reason and react to the working memory state, so if you want to pass data from rule to rule, assert the data as facts into the working memory of the decision engine.
rule
: Use this to define each rule in the DRL file. Rules consist of a rule name in the formatrule "name"
, followed by optional attributes that define rule behavior (such assalience
orno-loop
), followed bywhen
andthen
definitions. Each rule must have a unique name within the rule package. Thewhen
part of the rule contains the conditions that must be met to execute an action. For example, if a bank requires loan applicants to have over 21 years of age, then thewhen
condition for an"Underage"
rule would beApplicant( age < 21 )
. Thethen
part of the rule contains the actions to be performed when the conditional part of the rule has been met. For example, when the loan applicant is under 21 years old, thethen
action would besetApproved( false )
, declining the loan because the applicant is under age.Rule for loan application age limit
rule "Underage" salience 15 when $application : LoanApplication() Applicant( age < 21 ) then $application.setApproved( false ); $application.setExplanation( "Underage" ); end
At a minimum, each DRL file must specify the
package
,import
, andrule
components. All other components are optional.The following is an example DRL file in a loan application decision service:
Example DRL file for a loan application
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
Figure 18.1. Example DRL file for a loan application in Business Central
-
- After you define all components of the rule, click Validate in the upper-right toolbar of the DRL designer to validate the DRL file. If the file validation fails, address any problems described in the error message, review all syntax and components in the DRL file, and try again to validate the file until the file passes.
- Click Save in the DRL designer to save your work.
18.1. Adding WHEN conditions in DRL rules
The when
part of the rule contains the conditions that must be met to execute an action. For example, if a bank requires loan applicants to have over 21 years of age, then the when
condition of an "Underage"
rule would be Applicant( age < 21 )
. Conditions consist of a series of stated patterns and constraints, with optional bindings and other supported DRL elements, based on the available data objects in the package.
Prerequisites
-
The
package
is defined at the top of the DRL file. This should have been done for you when you created the file. -
The
import
list of data objects used in the rule is defined below thepackage
line of the DRL file. Data objects can be from this package or from another package in Business Central. -
The
rule
name is defined in the formatrule "name"
below thepackage
,import
, and other lines that apply to the entire DRL file. The same rule name cannot be used more than once in the same package. Optional rule attributes (such assalience
orno-loop
) that define rule behavior are below the rule name, before thewhen
section.
Procedure
In the DRL designer, enter
when
within the rule to begin adding condition statements. Thewhen
section consists of zero or more fact patterns that define conditions for the rule.If the
when
section is empty, then the conditions are considered to be true and the actions in thethen
section are executed the first time afireAllRules()
call is made in the decision engine. This is useful if you want to use rules to set up the decision engine state.Example rule without conditions
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
Enter a pattern for the first condition to be met, with optional constraints, bindings, and other supported DRL elements. A basic pattern format is
<patternBinding> : <patternType> ( <constraints> )
. Patterns are based on the available data objects in the package and define the conditions to be met in order to trigger actions in thethen
section.Simple pattern: A simple pattern with no constraints matches against a fact of the given type. For example, the following condition is only that the applicant exists.
when Applicant()
Pattern with constraints: A pattern with constraints matches against a fact of the given type and the additional restrictions in parentheses that are true or false. For example, the following condition is that the applicant is under the age of 21.
when Applicant( age < 21 )
Pattern with binding: A binding on a pattern is a shorthand reference that other components of the rule can use to refer back to the defined pattern. For example, the following binding
a
onLoanApplication
is used in a related action for underage applicants.when $a : LoanApplication() Applicant( age < 21 ) then $a.setApproved( false ); $a.setExplanation( "Underage" )
Continue defining all condition patterns that apply to this rule. The following are some of the keyword options for defining DRL conditions:
and
: Use this to group conditional components into a logical conjunction. Infix and prefixand
are supported. By default, all listed patterns are combined withand
when no conjunction is specified.// 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
: Use this to group conditional components into a logical disjunction. Infix and prefixor
are supported.// 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
: Use this to specify facts and constraints that must exist. This option is triggered on only the first match, not subsequent matches. If you use this element with multiple patterns, enclose the patterns with parentheses()
.exists ( Bankruptcy( yearOfOccurrence > 1990 || amountOwed > 10000 ) )
not
: Use this to specify facts and constraints that must not exist.not ( Applicant( age < 21 ) )
forall
: Use this to verify whether all facts that match the first pattern match all the remaining patterns. When aforall
construct is satisfied, the rule evaluates totrue
.forall( $app : Applicant( age < 21 ) Applicant( this == $app, status = 'underage' ) )
from
: Use this to specify a data source for a pattern.Applicant( ApplicantAddress : address ) Address( zipcode == "23920W" ) from ApplicantAddress
entry-point
: Use this to define anEntry Point
corresponding to a data source for the pattern. Typically used withfrom
.Applicant() from entry-point "LoanApplication"
collect
: Use this to define a collection of objects that the rule can use as part of the condition. In the example, all pending applications in the decision engine for each given mortgage are grouped in aList
. If three or more pending applications are found, the rule is executed.$m : Mortgage() $a : List( size >= 3 ) from collect( LoanApplication( Mortgage == $m, status == 'pending' ) )
accumulate
: Use this to iterate over a collection of objects, execute custom actions for each of the elements, and return one or more result objects (if the constraints evaluate totrue
). This option is a more flexible and powerful form ofcollect
. Use the formataccumulate( <source pattern>; <functions> [;<constraints>] )
. In the example,min
,max
, andaverage
are accumulate functions that calculate the minimum, maximum, and average temperature values over all the readings for each sensor. Other supported functions includecount
,sum
,variance
,standardDeviation
,collectList
, andcollectSet
.$s : Sensor() accumulate( Reading( sensor == $s, $temp : temperature ); $min : min( $temp ), $max : max( $temp ), $avg : average( $temp ); $min < 20, $avg > 70 )
NoteFor more information about DRL rule conditions, see Section 16.8, “Rule conditions in DRL (WHEN)”.
- After you define all condition components of the rule, click Validate in the upper-right toolbar of the DRL designer to validate the DRL file. If the file validation fails, address any problems described in the error message, review all syntax and components in the DRL file, and try again to validate the file until the file passes.
- Click Save in the DRL designer to save your work.
18.2. Adding THEN actions in DRL rules
The then
part of the rule contains the actions to be performed when the conditional part of the rule has been met. For example, when a loan applicant is under 21 years old, the then
action of an "Underage"
rule would be setApproved( false )
, declining the loan because the applicant is under age. Actions consist of one or more methods that execute consequences based on the rule conditions and on available data objects in the package. The main purpose of rule actions is to insert, delete, or modify data in the working memory of the decision engine.
Prerequisites
-
The
package
is defined at the top of the DRL file. This should have been done for you when you created the file. -
The
import
list of data objects used in the rule is defined below thepackage
line of the DRL file. Data objects can be from this package or from another package in Business Central. -
The
rule
name is defined in the formatrule "name"
below thepackage
,import
, and other lines that apply to the entire DRL file. The same rule name cannot be used more than once in the same package. Optional rule attributes (such assalience
orno-loop
) that define rule behavior are below the rule name, before thewhen
section.
Procedure
-
In the DRL designer, enter
then
after thewhen
section of the rule to begin adding action statements. Enter one or more actions to be executed on fact patterns based on the conditions for the rule.
The following are some of the keyword options for defining DRL actions:
set
: Use this to set the value of a field.$application.setApproved ( false ); $application.setExplanation( "has been bankrupt" );
modify
: Use this to specify fields to be modified for a fact and to notify the decision engine of the change. This method provides a structured approach to fact updates. It combines theupdate
operation with setter calls to change object fields.modify( LoanApplication ) { setAmount( 100 ), setApproved ( true ) }
update
: Use this to specify fields and the entire related fact to be updated and to notify the decision engine of the change. After a fact has changed, you must callupdate
before changing another fact that might be affected by the updated values. To avoid this added step, use themodify
method instead.LoanApplication.setAmount( 100 ); update( LoanApplication );
insert
: Use this to insert anew
fact into the decision engine.insert( new Applicant() );
insertLogical
: Use this to insert anew
fact logically into the decision engine. The decision engine is responsible for logical decisions on insertions and retractions of facts. After regular or stated insertions, facts must be retracted explicitly. After logical insertions, the facts that were inserted are automatically retracted when the conditions in the rules that inserted the facts are no longer true.insertLogical( new Applicant() );
delete
: Use this to remove an object from the decision engine. The keywordretract
is also supported in DRL and executes the same action, butdelete
is typically preferred in DRL code for consistency with the keywordinsert
.delete( Applicant );
NoteFor more information about DRL rule actions, see Section 16.9, “Rule actions in DRL (THEN)”.
- After you define all action components of the rule, click Validate in the upper-right toolbar of the DRL designer to validate the DRL file. If the file validation fails, address any problems described in the error message, review all syntax and components in the DRL file, and try again to validate the file until the file passes.
- Click Save in the DRL designer to save your work.