分享

Drools规则引擎介绍一 / 蓝讯

 邵飞翔 2018-03-07

原文地址:http://docs./drools/release/6.2.0.Final/drools-docs/html_single/index.html 

原文前面所有的步骤都可以省略,直接从安装eclipse插件开始,安装地址是:http://docs./drools/release/6.2.0.Final/drools-docs/html_single/index.html

在国内现在是可以直接update,所以不需要用zip安装之类的方法。

在eclipse的Preferences中出现了一个菜单Drools,在installed Drools里面add一个Runtime(选择官网下载后解压缩的binaries目录)。

新建一个Drools Project

src/main/java新建类DroolsTest:

package com.sample;


import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;


/
 * This is a sample class to launch a rule.
 */
public class DroolsTest {


    public static final void main(String[] args) {
        try {
            // load up the knowledge base
       KieServices ks = KieServices.Factory.get();
       KieContainer kContainer = ks.getKieClasspathContainer();
        KieSession kSession = kContainer.newKieSession("ksession-rules");


            // go !
            Message message = new Message();
            message.setMessage("Hello World");
            message.setStatus(Message.HELLO);
            kSession.insert(message);
            kSession.fireAllRules();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }


    public static class Message {


        public static final int HELLO = 0;
        public static final int GOODBYE = 1;


        private String message;


        private int status;


        public String getMessage() {
            return this.message;
        }


        public void setMessage(String message) {
            this.message = message;
        }


        public int getStatus() {
            return this.status;
        }


        public void setStatus(int status) {
            this.status = status;
        }


    }


}



src/main/resources/rules新建规则文件

package com.sample
 
import com.sample.DroolsTest.Message;
 
rule "Hello World"
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println( myMessage );
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end


rule "GoodBye"
    when
        Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( myMessage );
end


src/main/resources/META-INF新建配置文件kmodule.xml:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http:///kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
</kmodule>


点击run可以看到结果:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www./codes.html#StaticLoggerBinder for further details.
Hello World
Goodbye cruel world

讲解一下这个例子的逻辑:main函数前三行是固定写法,它加载"ksession-rules"。这个名字在kmodule.xml里面配置,它会在resources目录下的rules目录下去找规则。

main函数先写一个类型为Message.HELLO类型的消息到对象中,规则文件中规定如果类型为Message.HELLO则打印出消息并且更新对象类型Message.GOODBYE,

因为update(m)这时候规则引擎将会被再次触发,因为类型更新为Message.GOODBYE将会触发规则2,打印出新类型的消息。


怎么样在Maven中使用Drools:

drools在maven中央仓库中就有,所以不需要配置额外的maven仓库,配置如下:

    <dependencies>
      <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-bom</artifactId>
        <type>pom</type>
        <version>...</version>
        <scope>import</scope>
      </dependency>
      ...
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-compiler</artifactId>
      <scope>runtime</scope>
    </dependency>
    ...
  <dependencies>



运行时:

这里说的运行时是指:如果你部署二进制形式的规则(KnowledgePackage对象或者KnowledgeBase对象),这样可以让你的运行时非常轻量化。可以用drools-compiler来生成规则包然后把它们部署到运行时环境。运行时环境只需要drool-core.jar和knowledge-api.jar来运行。

Rule Workbench(规则工作台)

需要Eclipse3.4以上(GEF插件3.4以上)

要不然就是用JBoss的IDE,集成好了。

通过http://www./drools/downloads.html 链接找到对应的Drools plug-in安装地址。

Drools运行时:

这里的运行时表示的是jar包集合,其实就是下载的不同版本的Drools。Eclipse需要一个默认的的Drools运行时。

从源代码构建Drools:

Drools和jBPM使用Git来做版本控制。链接为:https://github.com/droolsjbpm

比如guvnor子项目,build方法如下:

$ git clone git@github.com:droolsjbpm/guvnor.git
...
$ cd guvnor
$ mvn clean install -DskipTests -Dfull
...
从6.0开始KIE,Drools(包括工作台),jBPM(包括设计器和控制台),OptaPlanner将共享相同的版本号。

KIE是什么?

KIE是一个被Drools和jBPM共享的底层库,它提供一个统一的基本方法、编程模型来构建,部署且提供了工具集。

KIE的结构:

Drools规则引擎介绍一


OptaPlanner是一个本地搜索和优化工具,它现在是一个和Drools和jBPM同样的顶级项目。

Dashboard Builder是一个强大的报表工具。它独立于Drools和jBPM。

UberFire是工作台项目的基础组件,他提供了类似Eclipse样式的工作台能力(比如插件)。它也是独立于Drools和jBPM。

Guvnor在5.0里面承担了太多的职责。在6.0里面它将专注于封装UberFire插件用户构建web的IDE。

Drools和jBPM工作台的发行版本使用UberFire作为基础然后加上一些插件Guvnor以及Drools、jBPM自己的插件像decision table,guided editor,BPMN2 designer,human task。


KIE的生命周期

编辑

用可视化工具例如DRL BPMN2,decision table, class models等 编辑知识库(knowledge)

构建

把上一步编辑的知识库构建为部署单元,对于KIE这个部署单元就是jar。

测试

把jar部署到应用前请测试

部署

把jar部署到一个应用可以使用的位置

KIE使用maven风格的仓库

使用(Utilize)

加载jar然后提供一个KieSession对象,这样应用就可以和它交互了。

运行

系统通过KieSession的API和它交互

工作

用户通过UI或者命令行调用到它

管理

管理所有的KIESession或者KIEContainer


构建,部署,使用和运行

6.0引入了一个新配合和方法来build知识库,而5.0是用编程的方式,当然这个编程的方式为了向后兼容还是可用的。

KIE项目或者模块其实就是一个Maven的项目或者模块,仅仅在META-INF目录下面多了一个kmodule.xml。这个文件是用来描述选择那些知识库和配置知识库的session。它可以通过spring或者OSGI BluePrints来提供xml支持。


虽然maven可以构建和部署KIE项目,但有个插件,它会生成很多类文件,可以提供校验功能并且运行速度会更快。

示例图:

Drools规则引擎介绍一


org.kie.api.core.builder内容

Drools规则引擎介绍一

KieContainer

Drools规则引擎介绍一

Example 4.2. 创建KieContainer



Example 4.3. kmodule.xml中配置KieBase示例


Table 4.1. kbase 属性

Attribute name Default value Admitted values Meaning
name none any The name with which retrieve this KieBase from the KieContainer. This is the only mandatory attribute.
includes none any comma separated list A comma separated list of other KieBases contained in this kmodule. The artifacts of all these KieBases will be also included in this one.
packages all any comma separated list By default all the Drools artifacts under the resources folder, at any level, are included into the KieBase. This attribute allows to limit the artifacts that will be compiled in this KieBase to only the ones belonging to the list of packages.
default false true, false Defines if this KieBase is the default one for this module, so it can be created from the KieContainer without passing any name to it. There can be at most one default KieBase in each module.
equalsBehavior identity identity, equality Defines the behavior of Drools when a new fact is inserted into the Working Memory. With identity it always create a new FactHandle unless the same object isn't already present in the Working Memory, while with equality only if the newly inserted object is not equal (according to its equal method) to an already existing fact.
eventProcessingMode cloud cloud, stream When compiled in cloud mode the KieBase treats events as normal facts, while in stream mode allow temporal reasoning on them.
declarativeAgenda disabled disabled, enabled Defines if the Declarative Agenda is enabled or not.

Example 4.4. 从KieContainer中解析出KieBases 和 KieSessions 


因为KSession2_1 和 KSession2_2 是不同的类型,一个是stateful,一个是stateless。所以他们使用的方法是不同的,如果用错了会抛出RunTimeException。


使用Maven来构建

KIE插件使得artifact会被校验和预编译,所以建议一直使用这个插件。如下图

Example 4.7. 在pom.xml中增加KIE plugin 


用程序来定义KieModule

其实也可以用程序来定义KieModule里面的KieBase和KieSession。要做到这一点需要先创建一个KieFileSystem。它是一个虚拟的文件系统,然后把项目中的所有资源添加进去。

Drools规则引擎介绍一

像其他的核心组件一样,你也可以从KieServices中获取KieFileSystem。



Example 4.8. 用编程方式达到 kmodule.xml 同样效果的例子


下面还要给KieFileSystem加上其他必须的artifacts:

Example 4.9. Adding Kie artifacts to a KieFileSystem



Example 4.10. Creating and adding a Resource with an explicit type



Example 4.11. Building the contents of a KieFileSystem and creating a KieContainer



Example 4.12. Checking that a compilation didn't produce any error



Example 4.13. Setting the severity using properties


4.2.3 部署

4.2.3.1 KieBase

KieBase是一个应用的知识定义集合的仓库。它包含Rules,processes,functions和type models。KieBase本身不包含任何数据。由KieBase创建的Session可以用来插入数据,然后用Session来启动进程实例。KieBase可以从KieContainer(包含了KieModule)中取到。


有时候,在OSGI环境中,KieBase需要解析不在默认类加载器中定义的类型。这时候就需要KieBaseConfiguration,它有一个额外的类加载器,当KieContainer创建KieBase的时候可以传递给它。

Example 4.14. Creating a new KieBase with a custom ClassLoader


4.2.3.2 KieSession和 KieBase修改

KieSession会在“运行”章节详细讨论。KieBase创建了KieSession对象并且保持了引用。当修改KieBase的时候这些改动也会被应用到KieSession中。这个引用默认是一个Java弱引用。当然有一个可选的boolean参数可以控制这个引用。

4.2.3.3 KieScanner

KieScanner 可以持续监控你的Maven Repository(不同于普通的maven)看看有没有一个新的Kie项目被安装。一个包含这个Kie项目的新的发布版本会被发布KieContainer中。KieScanner需要依赖kie-ci.jar包。


下面的例子显示KieScanner怎么注册到KieContainer的:

Example 4.15. Registering and starting a KieScanner on a KieContainer

在上面的例子里KieScanner被配置为按固定时间间隔启动。也可以调用scanNow()函数启动。如果KieScanner发现maven仓库中有KieContainer用到的新版本项目,它会自动下载新版本并触发一个增量构建。这时候KieContainer中的所有KieBase和KieSession都更新为新版本了。

KieScanner只会选择SNAPSHOT,版本范围,或者LATEST设置中的修改。运行时指定了版本号,则不会被更新。


4.2.3.4 Maven的版本号和依赖

Maven有一些机制可以来管理版本号和应用。应用可以指定版本发布。或则使用SNAPSHOT发布。可以通过提供特定范围的版本号或者使用SNAPSHOT机制。

StackOverFlow网站提供了一个非常好的解释:

http:///questions/30571/how-do-i-tell-maven-to-use-the-latest-version-of-a-dependency 

如果你总是要使用最新版本,Maven有两个重点可以用而不用使用版本范围这个方法。你需要小心使用这些参数因为你已经不再控制这些插件和依赖关系。

当你依赖一个插件或者依赖,你可以再version字段使用LATEST或者RELEASE。LATEST表示最新的发布版本或者SNAPSHOT版本。RELEASE表示最新的RELEASE版本,不包含SNAPSHOT版本。总而言之,最好不要不设定具体的版本。废话省略。

详情请看Maven的POM的语法描述:

http://books./mvnref-book/reference/pom-relationships-sect-pom-syntax.html

http://books./mvnref-book/reference/pom-relationships-sect-project-dependencies.html


下面是一个例子:


显示申明一个版本(除非版本冲突,否则总是这个版本):


(废话不详说)

4.2.3.5 Settings.xml和远程仓库安装:

(废话不详说)


4.2.4 运行

4.2.4.1 KieBase

KieBase是应用知识库。它包含规则,processes,函数,和类型模型。KieBase本身不包含任何数据。从KieBase中创建的session可以被插入数据,可以从session中创建processes。当KieBase定义的时候,KieBase可以从KieContainer中包含的KieModels中获取。


Example 4.16. Getting a KieBase from a KieContainer

4.2.4.2 KieSession

KieSession保存和执行运行时数据。它是从KieBase中创建。


4.2.4.3 Kie运行时

kie运行时给Rules,processes提供全局设置、注册channel等方法。


4.2.4.3.1.1 Globals(全局对象)

规则引擎可以看到Globals命名对象。但是改变Globals里面的值不会重算Rules。Globals再提供静态信息方面很有效。比如在规则的RHS中提供服务。或者接收从规则引擎返回的平均值。当你在LHS中使用Globals的时候,保证它不可变,或者至少改变不会影响规则的行为。

global应该如下定义:

global java.util.List list

废话省略

4.2.4.4 事件模型

event包提供了规则引擎的事件,比如规则被触发或者对象被断言。这样就可以从应用的主流程中分离日志或者监听事件。

KieRuntimeEventManager


RuleRuntimeEventManager




待续......

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多