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


 

 2020-05-08

验证 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 )

reference : https://docs.jboss.org/drools/release/7.36.0.Final/drools-docs/html_single/index.html#_improved_multi_threading_behaviour



 

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 }
View Code

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:

  1. MatchCreateEvent , MatchCanceledEvent
  2. BeforeMatchFiredEvent , AfterMatchedFiredEvent
  3. AgendaGroupPushedEvent , AgendaGroupPoppedEvent
  4. ObjectInsertEvent , ObjectDeletedEvent , ObjectUpdatedEvent
  5. ProcessCompletedEvent 
  6. ProcessNodeLeftEvent, ProcessNodeTriggeredEvent
  7. 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 }
View Code

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.

 

可采用监听器功能。

https://docs.jboss.org/drools/release/7.36.0.Final/drools-docs/html_single/index.html#property-change-listeners-con_decision-engine

 

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 位于第一优先级.以决定后续规则是否继续

 

posted @ 2020-04-11 11:12  君子之行  阅读(368)  评论(0)    收藏  举报