Tech_SD_RulesEnginne_Drools
背景: 工业领域逻辑复杂, 构建系统架构考虑将逻辑分离独立, 形成子系统, 基于现阶段的主流开源规则引擎解决方案,采用 IBM - drools.

So a general rule of thumb when doing your knowledge engineering is :
- Bad
1. Monolithic
2. Leaky
- Good
1. De-couple knowledge responsibilities
2. Encapsulate knowledge
3. Provide semantic abstractions for those encapsulations
协作间的逻辑创建 与 使用 进行分离, 规则消费方只需要得到一个结论,而无需持有规则相关条件信息。

drools 解析

coflict resultion
按照优先级: Salience, LIFO .
事件模型
Event 包里包含了规则引擎的事件机制, 规则激发,对象被 asserted , 可使用事件机制来进行 AOP 编程.
规则文件可以为 .drl, xml, xls, csv
Dev-Environment
IDEA-Maven
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.36.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.36.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.36.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.36.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
<version>7.36.0.Final</version>
</dependency>
项目结构规范:
1. drools 项目的 kmodule.xml 需要在 main -> resources -> META-IN 目录下,否则运行时报错: 无法找到资源文件
2. drools 项目的规则文件必须在 main -> resources, 规则文件可按照分类在不同的目录中, 其所在的目录就是 kmodule.xml 文件中引用的包名.

kmodule.xml 配置文件的基本配置形式
<?xml version="1.0" encoding="UTF-8" ?> <kmodule xmlns="http://www.drools.org/xsd/kmodule"> <kbase name="kbase_unique" packages="rules.defaultRule"> <ksession name="defaultSession" /> </kbase> </kmodule>
- kmodule 可包含一到多个 kbase, 分别对应drl 规则文件
- kbase name 属性值唯一。
- packages 对应 drl文件所在resouces目录下的路径。 drl 文件中的 package 与此无关联。
- 多个包用逗号分隔,默认会扫描 resouces 目录下所有包含子目录规则。
- kbase default 属性,标识当前 kiebase 是否默认,如果是莫容嗯则不用名称即可查到,每个module 至多一个默认kieBase.
- kbase 下面可有一个或多个 ksession, 其name属性必须设置,且必须唯一。
可用 IDEA 的快捷方式生成 drools rule file



注意 dialect "mvel"
注意 Import java package
package rules.defaultRule;
dialect "mvel"
import org.example.Product;
rule "defaultRule"
when
pp : Product ( prePrice <= 500)
then
double prePrice = pp.getPrePrice();
pp.setRealPrice(prePrice * 0.50);
System.out.println(pp.getName() + "price : " + pp.getRealPrice());
end

运行测试代码:

此处注意 规则过滤 m2

property change Listener
fact 对象是 JavaBean, 为其实现一个 property change listener, 意味着当一个 fact 改变时,RE 会自动进行响应。
不需要调用 modifyObject() 方法来通知 workingMemory() ,
Proxy libraries 会实现这一切,要让 property change listener 生效,要将fact 设置为 动态 dynamic 模式,将 assertObject() 方法第二个参数设置为 true.
然后再 Java Bean 中加入 PropertyChangeSupport 实例和两个方法。
最后在 JavaBean 的 setter 方法中通知 PropertyChangeSuppoert
2020-05-07
note: drools 与外部接口数据交互



接下来将处理流程抽象化, 放在简单工厂里. 且开放特定的逻辑处理给 developer.

reference:
https://www.drools.org/download/download.html
https://www.cnblogs.com/yuebintse/p/5768046.html
验证 drools rules 可以解析 POJO 内 集合字段,字面值,注意用取值的方法似乎因 strict-model 受限。

1. 调用取值方法,信息


2. 采用 字面值, 注意文档所示也是 字段的限定条件


2020-05-09
drools rule 规则
LHS : 绑定变量名: Object ( field 约束 )
在 pattern 部分, 如果在当前规则的 LHS 部分的其他 pattern 要使用这个对象, 可以通过为该对象绑定设定一个绑定变量名来实现对其的引用,
对于绑定变量名,通常做法时添加一个 “$" 前缀, 可以和 Fact 对象区分开来, 绑定变量可以用于对象上, 可以用于对象属性上。
field 约束 是指当前对象里 相关字段的条件限制。
2020-05-21 23:25:44
rule "defaultRule" lock-on-active agenda-group "specify group" when $perf : Entity(name == "perf") $ref : Entity(name == "chl") $innerService : innerService(); then collectResult(processSample($perf,$ref),$innerService); end
KieServices services = KieServices.Factory.get(); KieContainer container = services.getKieClasspathContainer(); KieSession session = container.newKieSession("defaultSession"); session.getAgenda().getAgendaGroup("specify group").setFocus();
drools official document
purpose :
1. official technology
2. eng

plan : foucus drools engine
1. 2020-05-22 10:09:04
go on 3.1
2020-05-25 10:05:34


1. (kesesion) type : stateless , stateful .
stateless : in a stateless KIE session, data from a previous invocation of the KIE session ( the previous session state ) is discarded between session invocation.
stateful : data is retained.
由之前的 KIE session 调用得到的数据状态,前者无状态, 后者有状态。
无状态 应用如下类似场景: Validation, Calculation, Routing and filtering
The dollar sign ($) is optional and helps to differentiate between variable names and field names.
官方文档中的示例


建议采用不可变对象,来构建新的对象包含了验证的结果, 官方可能仅仅示例

注意,此种调用方式需要在 ksession 配置 default = "true" 指定默认
stateless 中 execute() = fireAllRules() + dispose()
CommandFactory
BatchExecutor


3.1.1 Global variables in stateless KIE sessions
无状态下的 全局变量, 委托全局变量, 执行范围全局变量
全局变量 线程不安全

委托全局变量的优先级会高于 全局变量
execution-scoped globals : Command object 设置, CommandExecutor interface execute
注意下 insert 的 id key 位置

2020-05-27
有状态KIE会话则依赖于规则中的 Modify 语句来 将更改通知给 drools 引擎。
drool 引擎对更改进行推理,并评估对后续规则执行的应项。该过程是drools引擎使用 inference and truth maintenance
功能的一部分,且在有状态 KIE 会话中至关重要。




2020-05-27 11:05:03



2020-05-28
KIE session pool 处理 session 瓶颈

pool 的关停使用 shutdown();
Drools engine inserts facts



注意 logical insertions , fact objects must override the equals and hashCode


2020-05-30 11:11:40
drools 支持两种 fact 等同机制
identity : (默认) drools 使用 identityHashMap 存储所有插入的 fact, 返回一个新的 FactHandler 对象。如再次插入事实,将返回原始FactHandle 对象
而忽略针对同一事实的重复插入,此模式,两个fact 对于 drools 来说是相同的,当它们具有相同的 identy.
equality : 使用HashMap to store all inserted facts. 使用 equals() 判别, The drools engine returns a new FactHandle object only if the inserted fact is not euqla
to an existing fact, 此模式下, two facts are the same for the drools engine if they are composed the same way.
regardless of identity. use this mode when you want objects to be assessed based on feature equality instead of explicit identity.





Execution control
fireAllRules() 之后, drools engine cycles repeatedly throw two phase.
1. Agenda evaluation
2. working memory actions

当 Agenda 存在多个规则时,一个规则的执行可能导致另一条规则从agenda删除, 为避免此情况
可定义执行顺序
rule salience,
agenda groups,
activation groups
rule units for DRL rule
============================================================
1. rule salience
整型,数值越大优先级越高,默认的是0, 可为负数。优先级排布会导致结果不同。


Agenda 需要设置 setFocus();


假定 report 的规则必须在 calculation 之前执行,application 要遵循此顺序。

注意,如果一个规则归属了 agendaGroup, 另一个可能会造成 conflict 的规则如果不属于任何 agenda.
则会在后续执行, 此处可能会埋下隐患。
暂时想到的是,为每一条规则,可能会造成冲突的,全部归属到相应的 agenda-group.

取消属于某个 agenda-group
Activation groups for rules
划分到同一组的 rule 有一个激活之后,其他的自动失效。
activation-group "report"
当触发一个之后,其他的 agenda 相关联的 rule 从 agenda 移除。
rule execution modees and thread safety
how and when executes rules
- Passive mode : default
- Active model :
应用场景:
Passive mode : application explicitly calls fireAllRules() . is best for applications that require direct control over rule evaluation and execution,
or complex event processing (CEP) 伪时钟
Active model : application calls fireUntilHalt( ), the drools engine starts in active mode and evaluates rules continually until the user or application explicitly calls halt();
for more complex event processing (CEP) . active model is also optimal for CEP app that use active queries.
注意避免同时使用 二者。特别是在多线程中。
submit()
在 active mode 中线程安全, group and perform operations on a KIE session in a thread-safe, atomic action.

consider the insertions as an atomic operation and to wait until all the insertions are complete before evaluating the rules again.
此处根据需要研究 (2020.06.02 )
Fact propagation model
- Lazy ( default) : Facts are propagationed in batch collections at rule execution. not in real time as the facts are individually inserted by app.
as a result, the order in which the facts are ultimately propagated through the drools engine may be different from the order in which the facts were individually inserted
- Immediate : Facts are propagated immediately in the order that they are inserted by a user or app.
- Eager : Facts are propagated lazily ( in batch collections), but before rule execution. The Drools engine uses this progagation behavior for rules that have the the no-loop or lock-on-active attribute
Agenda evaluation filters

AgendaFilter object in the filter interface
allow or deny the evaluation of specified rules during agenda evaluation.
specify an agenda filter as part of a fireAllRules() call

Rule Unit execution control
rule runits are helpeful when you want to cordinate rule execution so that the execution of one rule unit triggers the start of another rule unit and so on.
implement the RuleUnit interface
<dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>7.36.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>7.36.0.Final</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <version>7.36.0.Final</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-internal</artifactId> <version>7.36.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-ruleunit</artifactId> <version>7.38.0.Final</version> </dependency>

package org.srdc.droolsOfficalDemo.ruleUnit; import org.drools.ruleunit.DataSource; import org.drools.ruleunit.RuleUnit; import org.srdc.droolsOfficalDemo.Person; public class AgeCheckUnit implements RuleUnit { private int adultAge; private DataSource<Person> persons; public AgeCheckUnit() { } public AgeCheckUnit(DataSource<Person> personParam,int age){ this.adultAge = age; this.persons = personParam; } // A global variable in this rule unit: public int getAdultAge() { return adultAge; } // A data source of 'Persons' in this rule unit public DataSource<Person> getPersons() { return persons; } // Life-cycle methods: @Override public void onStart(){ } @Override public void onEnd(){ } }
adultAge 是可以在该 rule unit 范围内都可以访问的全局变量.
| Method | Invoked when |
| onStart() | rule unit execution starts |
| onEnd() | rule unit execution ends |
| onSuspend() | rule unit exection is suspended (used only with runUntilHalt() ) |
| onResume() | rule unit execution is resumed ( used only wiht runUntilHalt() |
| onYield(RuleUnit other) | The consequence of a rule in the rule unit triggers the execution of a different rule unit |
OOPath 是 XPath 面向对象语法扩展,在集合和过滤约束时浏览相关元素, 特别适用于 graph of objects.
add one or more rules to a rule unit, by default, all the rules in a DRL file are automatically associated with a rule unit that follows the naming convention of the DRL file name.
if the drl file is in the same package and has the same name as a class that implements the RuleUnit interface, then all of the rules in that DRL file implicitly belong to that rule unit.
ex: all the rules in the AdultUnit.drl file in the org.mypackage.myunit package are automatically part of the rule unit org.mypackage.myunit.AdultUnit.



Phreak 算法 ( rule 评估规则算法)
基于 Rete algorithms, 增加如下
1. three layers of contextual memory : Node, segment, and rule memory types
2. Rule-based, segment-based, and node-based linking
3. Lazy (delayed) rule evaluation
4. stack-based evaluations with pause and resume
5. Isolated rule evaluation
6. Set-oriented propagations


此节未研究,了解该算法内部运算机制时要深入到官方 doc 程度。
CEP ( complex event process ) 此章节放在后续。
drool engine 使用 复杂事件处理来检测和处理事件集合中的多个事件,以发现事件之间存在的关系,并从事件及其关系中推断新数据.
事件触发机制.

queries
quiries with the drools engine to retrieve fact sets based on fact patterns as they are used in rules. The patterns might alos use optional parameters.
while a query iterates over a result collection, you can use any identifier taht is bound to the query to access the corresponding fact or fact rield by calling the get() method with the binding variable name as the argument.
if the binding refers to a fact object, you can retrieve the fact handle by calling getFactHandle() with the variable name as the parameter.




drl
package legacyEcatRules;
dialect "java"
import org.srdc.droolsOfficalDemo.Person
query "people under the age of 21"
$person : Person (age < 21)
end
java code
1 package org.srdc.droolsOfficalDemo; 2 3 import org.kie.api.KieServices; 4 import org.kie.api.runtime.KieContainer; 5 import org.kie.api.runtime.KieSession; 6 import org.kie.api.runtime.KieSessionsPool; 7 import org.kie.api.runtime.rule.QueryResults; 8 import org.kie.api.runtime.rule.QueryResultsRow; 9 10 public class QueryRunner { 11 12 public static void main(String ... args){ 13 KieServices services = KieServices.Factory.get(); 14 KieContainer container = services.getKieClasspathContainer(); 15 KieSessionsPool pool = container.newKieSessionsPool(3); 16 KieSession session = pool.newKieSession(); 17 18 Person samplePerson1 = new Person(); 19 samplePerson1.setAge(20); 20 samplePerson1.setName("sample1"); 21 Person samplePerson2 = new Person(); 22 samplePerson2.setAge(20); 23 samplePerson2.setName("sample2"); 24 25 Person samplePerson3 = new Person(); 26 samplePerson3.setAge(20); 27 samplePerson3.setName("sample3"); 28 29 Person notMatchPerson = new Person(); 30 notMatchPerson.setAge(33); 31 32 session.insert(samplePerson1); 33 session.insert(samplePerson2); 34 session.insert(samplePerson3); 35 session.insert(notMatchPerson); 36 session.fireAllRules(); 37 38 QueryResults results = session.getQueryResults("people under the age of 21"); 39 System.out.println("we have " + results.size() + " people under the age of 21"); 40 41 System.out.println("These people are under the age of 21"); 42 43 for (QueryResultsRow row : results ) { 44 Person person = (Person) row.get("$person"); 45 System.out.println(person.getName() + "\n"); 46 } 47 48 session.dispose(); 49 pool.shutdown(); 50 } 51 }
Live queries
在实时变化,通过遍历返回集合的方式来调用查询和处理结果很困难,为此,
drool 提供了实时查询,该查询使用附加的listener 进行更改事件,而不是返回可迭代的结果集合。
live query 通过创建视图并发布视图内容的更改事件而保持打开状态。


ref : http://blog.athico.com/2010/07/glazed-lists-examples-for-drools-live.html
2020-06-08
event listener : log, debug
add or remove listeners for drools engine events, such as as fact insertions and rule executions. With drolls engine event listeners, you can be notified of drools engine activity and separate your logging and auditing work from the core of your application.
supports the following default event listeners for the agenda and working memory:
1. AgendaEventListener
2. WorkingMemoryEventListener

for each event listener, drools engine supports the following specific that you can specify to be monitored:
- MatchCreateEvent , MatchCanceledEvent
- BeforeMatchFiredEvent , AfterMatchedFiredEvent
- AgendaGroupPushedEvent , AgendaGroupPoppedEvent
- ObjectInsertEvent , ObjectDeletedEvent , ObjectUpdatedEvent
- ProcessCompletedEvent
- ProcessNodeLeftEvent, ProcessNodeTriggeredEvent
- ProcessStartEvent

drools engine also supprots the follwoing agenda and working memory event listeners for debug logging :
- DebugAgendaEventListener
- DebugRuleRuntimeEventListener
the event listeners implement the same supported event-listener methods and include a debug print statement by default. You can add a specific supported event to be monitored and documented, or monitor all agenda or working memory activity.

drools engine uses the java logging API SLF4J for system logging.
for the logging utility that you want to use, add the relevant dependency to your maven project or save the relevant XML configuration file in the org.drools package of your drools distribution :
图例 logback

performance tuning considerations with the drools engine
important principle
1. Use sequential mode for stateless KIE sessions that do not require important drools engine updates.
sequential mode is an advanced rule base configuration in the drools engine that enables the drools engine to evaluate rules one time in the order that they are listed in the drools engine agenda without regard to changes in the working memory.
but important update may not be applied to your rules.
Sequential mode applies to stateless KIE sessions only.
开启方法: set the system property drools.sequential to true.
2. Use simple operations with event listeners
limit the number of event listeners and the type of operations they perform.
use event listeners for simple operations, such as :
1. debug logging and setting properties.
2. Complicated operations, such as network calls, in listeners can impede rule execution.
after you finish working with a KIE session, remove the attached event listeners so that the session can be cleaned :
ref : https://docs.jboss.org/drools/release/7.36.0.Final/drools-docs/html_single/index.html#phreak-sequential-mode-con_decision-engine
1. drools 资源库里 同一个 package 里的 rule 的名称必须唯一,且用双括号包含起来。
2. rule file 里可定义 function,用于可复用功能且仅仅是参数不同, 能达到此效果的还可以从 java code 中 import static 方法,
注意在 rule 的 then 部分调用。

declare
@position 注释会覆写 默认的参数顺序

org.drools.definition.type package, can be used to annotate original pojos on the classpath.
currently only fields on classes can be annotated. Inheritance of classes is supported
but not interface or methods.

key-point :
query 可调用其他 query, 此query 与 可选查询参数结合一起可提供 derivation query ,
it is also possible to mix both positional and named, but positional must come first, separated by a semi colon ( 分号)
在此阶段,不能将表达式与变量混合使用。 这是一个调用另一个查询的查询示例。
"z" 将始终是 “输出” 变量。
“?" 符号标识查询仅是拉式查询,一旦返回结果, 由于基础数据发生更改,将不再收到进一步结果。

as previously methiond you can use live "open" queries to reactively receive changes over time from the query result, as the underlying
data it queries against changes.


the algorithm uses stacks to handle recursion, so the method stack will not blow up.
use as input argument for a query both the field of a fact as in:

and more in general any kind of valid expression like in

暂不支持:
list and Map unification
expression unification - pred( xxxx)
2020-06-11
declarations in DRL files define new fact types or metadata for types to be used by rules in the DRL file
New fact type:
默认是 Object, 声明的事实类型可以直接在 drools rules 中定义新的事实模型,而无需使用 Java之类的较低级语言创建模型,也可以在已经构建域模型并且要用
主要在推理过程中使用的其他实体补充该模型时声明新的类型。
Metadata for fact types:
可以将@key ( value ) 格式的元数据与新事实或现有事实相关联。 元数据可以是事实属性未标识的任何类型的数据,且在该事实类型的所有实例之间是一只的。
元数据可以在运行时由 drools 引擎查询,且在推理过程中使用。

每个属性类型可用 valid Java type, including another class that you create or a fact type that you previously declared.
address 是同属为自定义类型。
注意采用了默认的 setter gettter

===================================================
在声明新的类型时, drools engine 在 compile time 编译期, 生成一对一 JavaBeans 映射。

枚举
支持以 enum<factType> 格式声明枚举类型,后跟以逗号分隔的以分号结尾的值列表。
4.15 , 4.16 跳过

global 是为规则提供数据或服务,例如 规则结果中使用的 app service ,并从规则返回数据,例如在规则结果中添加的日志或值。
可以通过 KIE session 配置或 rest 操作在 drools rule 的工作内存中设置全局值,

do not use global variables to establish condtitions in rules unless a global variable has a constant immutable value.
global variables are not inserted into the working memory of the drools engine,so drools engine can not
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 drools engine.
如果在多个 package 里声明了相同名称的 global 变量,则它们之间共享这个 global variable.
Rules attributes in drl


| attribute | define | comment |
| no-loop |
a boolean value, when the option is selected, the rule cannot be reactived(looped) if a consequence of the rule re-triggers a previously met condition. When the condition is not selected, the rule can be looped in these circumstances. Example: no-loop true |
默认是 no-loop : false 该项禁止已经触发过的规则再次触发。 |
| auto-focus |
a boolean value, applicable only to rules within agenda groups. When the option is selected, the next time the rule is activated, a focus is automatically given to the agenda group to which the rule is assigned. |
|
| agenda-group |
a string identifying an agenda group to which you want to assign the rule. Agenda groups allow you to partition the agenda to provide more execution control over groups of rules. only rules in an agenda group that has acquired a focus are able to be actived. agenda-group "GroupName" |
agenda-group 分区, 必须使用 setFocus 来激活该partitin规则
注意有未分区的 rules 是否会有交集。 |
| activation-group |
a string identifying an activation ( or XOR) group which you want to assign the rule. In activation groups, only one rule can the activated. the first rule to fire will cancel all pending activations of all rules in the activation group. activation-group "GroupName" |
在该 partition 内的规则只会触发一个, 其他会自动cancel |
| ruleflow-group |
a string identifying a rule flow group. In rule flow groups, rules can fire only when the group is activated by the associated rule flow. ruleflow-group "GroupName" |
此功用与 rule flow 结合使用,有待商榷(官方) |
| lock-on-active |
a boolean value, applicable only to rules within rule flow groups or agenda groups. When the option is selected, the next time the ruleflow group for the rule becomes active or the agenda groups for the rule receives a focus, the rule cannot be activated again until the ruleflow group is no longer active or the agenda group loses the focus.
this is a stronger version of the no-loop attribute, because the activation of a matching rule is discarded regardless of the origin of the update (not only by the rule itself). this attribute is ideal for calculation rules where you have a number of rules that modify a fact and you do not want any rule re-matching and firing again.
lock-on-active true |
|
| date-effective | 规则生效起始日 | |
| date-expires | 规则失效日期 | |
| duration | ||
| timer | ||
| calendar |
该章节有关 timer 的部分,因在目前项目中暂未使用,暂且略过。
2020-06-16

在 when 部分的 多个单行排布的 rule condition, 默认是采用 and 连接, or, not

模式匹配


1. no condition, 该 pattern 将会匹配所有 Person Type, 可以是 classes, superClasses , event interfaces.


drools 使用标准 JDK introspector class 来实现此映射,遵循 JavaBeans specification.
for optional drools engine performance, 建议使用直接的 属性访问, 替代 getter.
getter 内不要有状态属性,必须是简单的取值。
当属性无法被访问时,drools 会寻找相应的 getter 方法

可嵌套访问相关的属性值。 ( retrieve condition )

注意: zai stateful KIE sessions, use nested accessors carefully because the working memory of the frools engine is not aware of any of the nested values and does not detect when they change.
可以使用 任何返回 boolean 的 Java 表达式作为括号内的约束, Java 表达式可以与其他表达式增强功能 (例如属性访问) 混合使用

可以使用 evaluation priority by using parentheses, as in any logical or mathematical expression :


note: 注意只读,不要基于可变状态的值。

The == operator uses null-safe equals( ) semantics instead of the usual same sametics.
the pattern Person( firstName == "John" ) is similar to
java.util.Objects.equals ( person.getFirstName(), "John" )
The != operator uses null-safe ! equals() semantics instead of the usual not same semantics.
If the field and the value of a constraint are of different types,
the drools engine uses type coercion to resolve the confilict and reduce compilation error.




2020-06-18
a pattern in a drl rule condition is the segment to be matched by the drools engine.
a pattern can potentially match each fact that is inserted into the working memory of the frools engine.
a pattern can also contain constraints to futher define the facts to be matched.
模式可以包含约束,以进一步定义要匹配的事实。


with no contraints, a pattern maches a fact of the given type.
in the working memory of the drools engine

you can bind variables to patterns and constraints to refer to matched objects in other portions of a rule.
Bound variables can help you define rules more efficiently or more consistently with how you annotate facts in your
data model.
使用 $variable 定义





# case 抽象类的子类型





opertor
. 用于获取 nested object
# 用于 subtype 类型转换

!. 值非null 的 约束下 取值

[ ] 基于 index 访问 list 或者 基于 key 访问 map

< , <= , > , >= 可比较对象,具有自然顺序的属性
若是时间 < 表示之前

==, != 相当于 Java 里的 equals( ) 和 ! equals ( ) method in constraints.
&&, || 相当于 and, or
matches, not matches 正则表达式匹配
正则表达式是 String literal, 可解析为正则表达式的 variables 也是被支持的。
该类操作符仅支持 String 属性。
如果matches against a nul value, 返回 false,
如果 not matches against a null value, 永远返回 true.
Java 中 regular expression 必须以 \\ to escape.
contains, not contains
to verify whether a field that is an Array or a Collection contains or does not contain a specifieed value.
these operators apply to Array or Collection properties.
can also use these operators in place of String.contains() and !String.contains() constraints checks.
对 field 值的精细化操作
str
可验证 a String starts with or ends with , 以及该字符串的
in, notin

use these operators to specify more than one possible value to match in a constraint (compound value restriction).
this functionality of compound value restriction is supported only in the in or notin oeprators
这些运算符的第二个操作数必须是用括号括起来的值的逗号分隔列表。
可以提供值作为 variable, iterals, return values, or qualified identifier.
使用 == 或 != 在内部将这些运算符重写为多个限制的列表。
| Operator type | Operators | Notes |
| Nested or null-safe property access | .() , !. | Not standard Java semantics |
| List or Map access | [] | Not standard Java semantics |
| Constraint binding | : | Not standard Java semantics |
| Multiplicative | *, /% | |
| Additive | +, - | |
| Shift | >>, >>>, << | |
| Relational | <,<=,>,>=, instanceof | |
| Equallity | == , != |
Uses equals() and !equals() semantics, not standard Java same and not same semantics |
| Non-short-circuiting AND | & | |
| Non-short-circuiting exclusive OR | ^ | |
| Non-short-circuiting inclusive OR | | | |
| Logical AND | && | |
| Logical OR | || | |
| Ternary | ? : | |
| Comma-separated AND | , |
2020-06-22
FROM, EntryPoint
package config.defaultRules;
dialect "java"
import ort.techRoad.drlFromEntryPoint.*;
rule "Validate zipcode"
when
Person( $personAddress : address )
Address ( zipCode == "23920W") from $personAddress
then
System.out.println("active person");
end
1 package ort.techRoad.drlFromEntryPoint; 2 3 import org.kie.api.KieServices; 4 import org.kie.api.runtime.KieContainer; 5 import org.kie.api.runtime.KieSession; 6 import org.kie.api.runtime.KieSessionsPool; 7 8 import java.util.ArrayList; 9 import java.util.List; 10 11 public class RuleSourcesProvider { 12 13 private KieSession kieSession; 14 15 private KieSession setUpRuleEnv(){ 16 KieServices services = KieServices.Factory.get(); 17 KieContainer container = services.getKieClasspathContainer(); 18 19 KieSessionsPool pool = container.newKieSessionsPool(3); 20 return pool.newKieSession(); 21 } 22 23 private List<Person> buildData(){ 24 25 Person p1 = new Person(); 26 p1.setName("p1-name"); 27 p1.setAge(1); 28 29 Address adr1 = new Address(); 30 adr1.setZipCode("23920W"); 31 p1.setAddress(adr1); 32 33 Person p2 = new Person(); 34 p2.setName("p2-name"); 35 p2.setAge(2); 36 37 Address adr2 = new Address(); 38 adr2.setZipCode("20032W"); 39 p2.setAddress(adr2); 40 41 List<Person> persons = new ArrayList<>(); 42 persons.add(p1); 43 persons.add(p2); 44 return persons; 45 } 46 47 public static void main(String... args){ 48 49 RuleSourcesProvider ruleProvider = new RuleSourcesProvider(); 50 KieSession session = ruleProvider.setUpRuleEnv(); 51 52 List<Person> persons = ruleProvider.buildData(); 53 persons.stream().forEach(e -> session.insert(e)); 54 session.fireAllRules(); 55 session.dispose(); 56 } 57 }
from






注意 from 相关的 pattern 用括号括起来。
配合 entry point
from 配合 entry-point 作为入口点

rule "Authorize withoutrawal"
when
WithdrawRequest( $ai : accountId, $am : amount) from entry-point "ATM Stream"
CheckingAccount( accountId == $ai, balance > $am )
then
System.out.println("active entry point");
end
Collection
Java 集合 List, LinkedList 和 HashSet 或者自己的类



给定系统评估 Drools 引擎的工作内存中的所有待处理警报,并将其分组在列表中。
可使用嵌套from
accumulate
为了规则和应用程序中获得最佳性能,该格式是首选的。

accumulate( <source pattern>; <function> [; <constraints>] )
collection 的增强版,在对集合的迭代中使用自定义的操作,例如 function,进行相应的评估。
average, min, max, 三者属于累加函数
count, sum, collectList, collectSet
RLS
注意 work memory , FactHandle

1 /* 2 * Copyright 2005 Red Hat, Inc. and/or its affiliates. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.drools.core.spi; 18 19 import java.io.Serializable; 20 import java.util.Collection; 21 import java.util.Map; 22 23 import org.drools.core.WorkingMemory; 24 import org.drools.core.common.InternalFactHandle; 25 import org.drools.core.definitions.rule.impl.RuleImpl; 26 import org.drools.core.factmodel.traits.Thing; 27 import org.drools.core.factmodel.traits.TraitableBean; 28 import org.drools.core.rule.Declaration; 29 import org.drools.core.util.bitmask.BitMask; 30 import org.kie.api.internal.runtime.beliefs.Mode; 31 import org.kie.api.runtime.Channel; 32 import org.kie.api.runtime.rule.EntryPoint; 33 import org.kie.api.runtime.rule.FactHandle; 34 import org.kie.api.runtime.rule.RuleContext; 35 36 /** 37 * KnowledgeHelper implementation types are injected into consequenses 38 * instrumented at compile time and instances passed at runtime. It provides 39 * convenience methods for users to interact with the WorkingMemory. 40 * <p> 41 * Of particular interest is the update method as it allows an object to 42 * be modified without having to specify the facthandle, because they are not 43 * passed to the consequence at runtime. To achieve this the implementation will 44 * need to lookup the fact handle of the object form the WorkingMemory. 45 */ 46 public interface KnowledgeHelper 47 extends 48 RuleContext, 49 Serializable { 50 51 void setActivation(final Activation agendaItem); 52 53 void reset(); 54 55 56 /** 57 * Asserts an object 58 * 59 * @param object - 60 * the object to be asserted 61 */ 62 InternalFactHandle insert(Object object) ; 63 64 FactHandle insertAsync( Object object ); 65 66 /** 67 * Asserts an object specifying that it implement the onPropertyChange 68 * listener 69 * 70 * @param object - 71 * the object to be asserted 72 * @param dynamic - 73 * specifies the object implements onPropertyChangeListener 74 */ 75 InternalFactHandle insert(Object object, 76 boolean dynamic) ; 77 78 InternalFactHandle insertLogical(Object object) ; 79 80 InternalFactHandle insertLogical(Object object, boolean dynamic) ; 81 82 InternalFactHandle insertLogical(Object object, Mode belief) ; 83 84 InternalFactHandle insertLogical(Object object, Mode... beliefs) ; 85 86 void cancelRemainingPreviousLogicalDependencies(); 87 88 InternalFactHandle getFactHandle(Object object); 89 90 InternalFactHandle getFactHandle(InternalFactHandle handle); 91 92 void update(FactHandle handle, Object newObject); 93 94 void update(FactHandle newObject); 95 void update(FactHandle newObject, BitMask mask, Class<?> modifiedClass); 96 97 void update(Object newObject); 98 void update(Object newObject, BitMask mask, Class<?> modifiedClass); 99 100 /** 101 * @deprecated Use delete 102 */ 103 void retract(FactHandle handle) ; 104 105 /** 106 * @deprecated Use delete 107 */ 108 void retract(Object handle); 109 110 111 void delete(Object handle); 112 void delete(Object object, FactHandle.State fhState); 113 114 void delete(FactHandle handle); 115 void delete(FactHandle handle, FactHandle.State fhState); 116 117 Object get(Declaration declaration); 118 119 /** 120 * @return - The rule name 121 */ 122 RuleImpl getRule(); 123 124 Tuple getTuple(); 125 126 Activation getMatch(); 127 128 WorkingMemory getWorkingMemory(); 129 130 EntryPoint getEntryPoint( String id ); 131 132 Channel getChannel( String id ); 133 134 Map<String, Channel> getChannels(); 135 136 void setFocus(String focus); 137 138 Declaration getDeclaration(String identifier); 139 140 void halt(); 141 142 <T> T getContext(Class<T> contextClass); 143 144 <T, K> T don( K core, Class<T> trait, boolean logical ); 145 146 <T, K> T don( K core, Class<T> trait, Mode... modes ); 147 148 <T, K> T don( K core, Class<T> trait ); 149 150 <T, K> T don( Thing<K> core, Class<T> trait ); 151 152 <T, K> T don( K core, Collection<Class<? extends Thing>> trait, boolean logical ); 153 154 <T, K> T don( K core, Collection<Class<? extends Thing>> trait, Mode... modes ); 155 156 <T, K> T don( K core, Collection<Class<? extends Thing>> trait ); 157 158 <T, K> Thing<K> shed( Thing<K> thing, Class<T> trait ); 159 160 <T, K, X extends TraitableBean> Thing<K> shed( TraitableBean<K,X> core, Class<T> trait ); 161 162 InternalFactHandle bolster( Object object ); 163 164 InternalFactHandle bolster( Object object, Object value ); 165 166 ClassLoader getProjectClassLoader(); 167 168 default void run(String ruleUnitName) { 169 throw new UnsupportedOperationException(); 170 } 171 172 default void run(Object ruleUnit) { 173 throw new UnsupportedOperationException(); 174 } 175 176 default void run(Class<?> ruleUnitClass) { 177 throw new UnsupportedOperationException(); 178 } 179 180 default void guard(Object ruleUnit) { 181 throw new UnsupportedOperationException(); 182 } 183 184 default void guard(Class<?> ruleUnitClass) { 185 throw new UnsupportedOperationException(); 186 } 187 }
RHS , set 赋值,
modify 值, update 更新
注意二者区别在于 update : the entire related fact to be updated and to nofity the drools engine of the vhsnhr.
after a fact has changed, you must call update before chaning another fact that might be affected by the updated value.
to avoid this added step, use the modify method instead.
可采用监听器功能。

insert
insert ( new <object> )
insertLogical dools 引擎负责对事实的插入和撤回进行逻辑决策。
在常规或声明的插入之后,必须明确撤回事实。 进行逻辑插入后,如果插入事实的规则中的条件不再成。
则插入的事实将自动撤回。
delete
用于从 drools engine 中删除对象。
delete ( <object> )
advanced rule actions with condition and named consequences
rules 可以拆分,
rule "Give 10$ discount and free parking to customers older than 60"
when
$customer : Customer( age > 60)
if ($customer.age > 70) do[giveDiscount]
$car : Car( owner = $customer)
then
modify($car) { setFreeParking(true)};
then[giveDiscount]
modify($customer){setDiscount(0.1)}
end


error message



2020-12-31 22:02:57
salience 位于第一优先级.以决定后续规则是否继续



浙公网安备 33010602011771号