Drools Rule Language
2.1 You specify the package and data object in the format packageName.objectName, with multiple imports on separate lines.
2.2 example: import org.mortgages.LoanApplication;
3.1 在drl里面定义函数
function String hello(String applicantName) {
return "Hello " + applicantName + "!";
}
3.2 实际也可以直接import java 的static function: import static org.example.applicant.MyFunctions.hello;
查询fact,其实可以用java访问替代
4.1 Queries in DRL files search the working memory of the Drools engine for facts related to the rules in the DRL file
4.2 not yet supported
4.3 支持对入参的赋值
query contains(String $s, String $c)
$s := String( this.contains( $c ) )
end
rule PersonNamesWithA when
$p : Person()
contains( $p.name, "a"; )
then
end
5.1 在DSL里面定义数据类型
5.1.1 支持extend,java访问
5.2 是否有实际应用场景?
6.1 Rule attributes
6.1.1 salience 优先级
6.1.2 enabled
6.1.3 date-effective
6.1.4 date-expires
6.1.5 no-loop
6.1.6 agenda-group
就是分组,通过setFocus指定优先执行,具体看drools engine里面的说明
6.1.7 activation-group :only one rule can be activated
6.1.8 duration 执行时长:A long integer value defining the duration of time in milliseconds after which the rule can be activated, if the rule conditions are still met.
6.1.9 timer
6.1.10 calendar
A Quartz calendar definition for scheduling the rule.
6.1.11 auto-focus
a focus is automatically given to the agenda group to which the rule is assigned
6.1.12 lock-on-active
6.1.13 ruleflow-group
rules can fire only when the group is activated by the associated rule flow(纯规则不用,和jbpm有关)
6.1.14 dialect
A string identifying either JAVA or MVEL as the language to be used the dialect “JAVA” rule consequences support only Java 5 syntax
6.2 定时控制
6.2.1 Generally, a rule that is controlled by a timer becomes active when the rule is triggered and the rule consequence is executed repeatedly
6.2.2 When the Drools engine is in passive mode, rule consequences of timed rules are evaluated only when fireAllRules() is invoked again
6.2.3 可以通过ksconf.setOption( TimedRuleExecutionOption.YES );触发定时执行
// You can additionally set a FILTERED specification on the TimedRuleExecutionOption option
KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
conf.setOption( new TimedRuleExecutionOption.FILTERED(new TimedRuleExecutionFilter() {
public boolean accept(Rule[] rules) {
return rules[0].getName().equals("MyRule");
}
}) );
7.1 also known as the Left Hand Side (LHS) of the rule
7.2 每一行代表一个判断,默认连接词为and
7.3 defined keyword conjunctions (such as and, or, or not)
7.4 支持nest access properties in patterns
7.6 注意点
7.6.1 避免修改fact
7.6.2 避免随机fact
7.7 Bound variables in patterns and constraints
7.7.1 Bound variables can help you define rules more efficiently or more consistently with how you annotate facts in your data model.
7.7.2 绑定pattern
rule "simple rule"
when
$p : Person()
then
System.out.println( "Person " + $p );
end
A pattern in a DRL rule condition is the segment to be matched by the Drools engine.
7.7.3 bind variables to properties in pattern constraints
// Two persons of the same age:
Person( $firstAge : age ) // Binding
Person( age == $firstAge ) // Constraint expression
7.8 Nested constraints and inline casts
7.9 Date literal in constraints
7.9.1 By default, the Drools engine supports the date format dd-mmm-yyyy
7.9.2 修改:drools.dateformat=“dd-mmm-yyyy hh:mm”
7.9.3 Person( bornBefore < “27-Oct-2009” )
7.10 Supported operators in DRL pattern constraints
7.10.1 .(), #
7.10.2 !. (interpreted as != null)
- Person( $streetName : address!.street )
- Person( address != null, $streetName : address.street )
7.10.3 []
operator to access a List value by index or a Map value by key.
7.10.4 <, <=, >, >=
7.10.5 ==, !=
7.10.6 &&, ||
7.10.7 matches, not matches
7.10.8 contains, not contains
7.10.9 memberOf, not memberOf
7.10.10 soundslike
7.10.11 str
// Verify what the String starts with:
Message( routingValue str[startsWith] "R1" )
// Verify what the String ends with:
Message( routingValue str[endsWith] "R2" )
// Verify the length of the String:
Message( routingValue str[length] 17 )
7.10.12 in, notin
7.11 supports the following rule condition elements (keywords)
7.11.1 and
7.11.2 or
注意可以不同对象之间or
pensioner : (Person( sex == "f", age > 60 ) or Person( sex == "m", age > 65 ))
//Infix `or`:
Color( colorType : type ) or Person( favoriteColor == colorType )
//Infix `or` with grouping:
(Color( colorType : type ) or (Person( favoriteColor == colorType ) and Person( favoriteColor == colorType ))
// Prefix `or`:
(or Color( colorType : type ) Person( favoriteColor == colorType ))
7.11.3 exists
7.11.4 not
7.11.5 not/forall
循环,整体判断
rule "All full-time employees have red ID badges"
when
forall( $emp : Employee( type == "fulltime" )
Employee( this == $emp, badgeColor = "red" ) )
then
// True, all full-time employees have red ID badges.
end
rule "Not all employees have health and dental care"
when
not ( forall( $emp : Employee()
HealthCare( employee == $emp )
DentalCare( employee == $emp ) )
)
then
// True, not all employees have health and dental care.
end
7.11.6 from
Use this to specify a data source for a pattern
rule "Validate zipcode"
when
Person( $personAddress : address )
Address( zipcode == "23920W" ) from $personAddress
then
// Zip code is okay.
end
Using from with lock-on-active rule attribute can result in rules not being executed
rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
$p : Person()
$a : Address( city == "Raleigh" ) from $p.address
then
modify ($p) {} // Apply discount to the person.
end
The pattern that contains a from clause cannot be followed by another pattern starting with a parenthesis
7.11.7 entry-point
Use this to define an entry point, or event stream
rule "Authorize withdrawal"
when
WithdrawRequest( $ai : accountId, $am : amount ) from entry-point "ATM Stream"
CheckingAccount( accountId == $ai, balance > $am )
then
// Authorize withdrawal.
end
KieSession session = ...
// Create a reference to the entry point:
EntryPoint atmStream = session.getEntryPoint("ATM Stream");
// Start inserting your facts into the entry point:
atmStream.insert(aWithdrawRequest);
7.11.8 collect
import java.util.List
rule "Raise priority when system has more than three pending alarms"
when
$system : System()
$alarms : List( size >= 3 )
from collect( Alarm( system == $system, status == 'pending' ) )
then
// Raise priority because `$system` has three or more `$alarms` pending.
end
7.11.9 accumulate
rule "Average profit"
when
$order : Order()
accumulate( OrderItem( order == $order, $cost : cost, $price : price );
$avgProfit : average( 1 - $cost / $price ) )
then
// Average profit for `$order` is `$avgProfit`.
end
rule "Apply 10% discount to orders over US$ 100,00"
when
$order : Order()
$total : Number( doubleValue > 100 )
from accumulate( OrderItem( order == $order, $value : value ),
sum( $value ) )
then
// apply discount to $order
end
<result pattern> from accumulate( <source pattern>,
init( <init code> ),
action( <action code> ),
reverse( <reverse code> ),
result( <result expression> ) )
rule R
example
dialect "mvel"
when
String( $l : length )
$sum : Integer() from accumulate (
Person( age > 18, $age : age ),
init( int sum = 0 * $l; ),
action( sum += $age; ),
reverse( sum -= $age; ),
result( sum )
)
eval
7.12 OOPath syntax with graphs of objects in DRL rule conditions
7.12.1 OOPath是XPath的面向对象语法扩展,用于浏览DRL规则条件约束下的对象。
7.12.2 对比
rule "Find all grades for Big Data exam"
when
$student: Student( $plan: plan )
$exam: Exam( course == "Big Data" ) from $plan.exams
$grade: Grade() from $exam.grades
then
// Actions
end
Example rule that browses a graph of objects with OOPath syntax
rule "Find all grades for Big Data exam"
when
Student( $grade: /plan/exams[course == "Big Data"]/grades )
then
// Actions
end
7.12.3 语法
examples
Student( $grade: /plan/exams#AdvancedExam[ course == "Big Data", level > 3 ]/grades )
Student( $grade: /plan/exams/grades[ result > ../averageResult ] )
/和?/区别
8.1 The then part of the rule (also known as the Right Hand Side (RHS) of the rule) contains the actions to be performed when the conditional part of the rule has been met.
8.2 Supported rule action methods in DRL
8.2.1 java set
modify( LoanApplication ) {
setAmount( 100 ),
setApproved ( true )
}
8.2.3 update
LoanApplication.setAmount( 100 );
update( LoanApplication );
8.2.4 insert-参考engine
8.2.5 delete
8.3 Other rule action methods from drools variable
使用drools获取当前runtime 信息
8.3.1 drools.getRule().getName(): Returns the name of the currently firing rule.
8.3.2 drools.getMatch(): Returns the Match that activated the currently firing rule.
8.3.3 drools.getKieRuntime().halt(): Terminates rule execution if a user or application previously called fireUntilHalt()
8.3.4 drools.getKieRuntime().getAgenda(): Returns a reference to the KIE session Agenda
8.3.5 具体参考java doc getRuleMatch/KieRuntime
8.4 Advanced rule actions with conditional and named consequences
8.4.1 使用DO 分支
8.4.2 使用break 分支
break blocks any further condition evaluation
rule "Give free parking and 10% discount to over 60 Golden customer and 5% to Silver ones"
when
$customer : Customer( age > 60 )
if ( type == "Golden" ) do[giveDiscount10]
else if ( type == "Silver" ) break[giveDiscount5]
$car : Car( owner == $customer )
then
modify($car) { setFreeParking( true ) };
then[giveDiscount10]
modify($customer) { setDiscount( 0.1 ) };
then[giveDiscount5]
modify($customer) { setDiscount( 0.05 ) };
end
9.1 DRL supports single-line comments prefixed with a double forward slash // and multi-line comments enclosed with a forward slash and asterisk /* … */
10.2 1st Block: Error code
10.3 2nd Block: Line and column in the DRL source where the error occurred
10.4 3rd Block: Description of the problem
10.5 4th Block: Component in the DRL source (rule, function, query) where the error occurred
10.6 5th Block: Pattern in the DRL source where the error occurred (if applicable)
10.7 error code
;
11.1 Rule units are groups of data sources, global variables, and DRL rules that function together for a specific purpose
11.2 Rule units are experimental in Drools 7. Only supported in Red Hat build of Kogito.
11.3 需要创建对应java class
11.3.1
11.3.2 package org.mypackage.myunit
unit AdultUnit
rule Adult
when
$p : Person(age >= adultAge) from persons
then
System.out.println($p.getName() + " is adult and greater than " + adultAge);
end
12.1 Define the property and value of pattern constraints from left to right
12.1.1 ensure that the fact property name is on the left side of the operator and that the value (constant or a variable) is on the right side
12.2 Use equality operators more than other operator types in pattern constraints when possible
12.3 List the most restrictive rule conditions first
12.4 Avoid iterating over large collections of objects with excessive from clauses
12.5 Use Drools engine event listeners instead of System.out.println statements in rules for debug logging
12.6 Use the drools-metric module to identify the obstruction in your rules
<logger name="org.drools.metric.util.MetricLogUtils" level="trace"/>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-jmx</artifactId> <!-- Discover more registries at micrometer.io. -->
</dependency>
Example Java code for Micrometer
Metrics.addRegitry(new JmxMeterRegistry(s -> null, Clock.SYSTEM));