`
Wangwei86609
  • 浏览: 3701 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Osmanthus 规则引擎1.0发布了

阅读更多

Osmanthus 是什么?

 Osmanthus 是一款JAVA实现的轻量级开源的规则引擎框架,它是基于MVEL组件实现的,相比drools使用更容易且更轻量级;支持复杂的规则集,例如:决策树,评分卡等;配置规则可以像配置流程一样;支持规则的并行的执行。

 

源码地址:https://github.com/wangwei86609/osmanthus

 

另注:该框架还在持续更新中,欢迎广大编程爱好者积极参与该框架的开发和维护。

 

Osmanthus 目标

取代drools,实现一款更加强大的规则引擎框架。

 

核心特征

轻量级JAVA实现,且宜用

基于XML文件规则配置,规则更容易维护,且后期升级空间会更大

支持MVEL表达式语言,使规则中Condition 和 Action配置更方便,不需要硬编码

对规则做了很好的抽象,实现复杂规则例如:决策树和决策树林,评分卡等等

可以并行执行规则

 

Osmanthus使用

让我们实现如下流程规则集,该规则集相当复杂,包含了:决策树,评分看,并行规则,并行规则合并:



 对于以上如此复杂的规则,在Osmanthus中是很容易实现的,定义如下xml的规则的配置文件,详见源码

<?xml version="1.0" encoding="UTF-8"?>
<flow id="flow1">
    <start id="start" toNodeId="feerule"/>
    <ruleset id="feerule" fromNodeId="start" toNodeId="split1" external="true"/>
    <split id="split1" fromNodeId="feerule">
        <constraint toNodeId="card">
            <condition><![CDATA[fee>1]]></condition>
        </constraint>
        <constraint toNodeId="end">
            <condition><![CDATA[fee<=1]]></condition>
        </constraint>
    </split>
    <ruleset id="card" fromNodeId="split1" toNodeId="mlines" external="true"/>
    <parallel id="mlines" fromNodeId="card">
        <line toNodeId="p1"/>
        <line toNodeId="p2"/>
    </parallel>
    <rule id="p1" fromNodeId="mlines" toNodeId="end">
        <condition><![CDATA[1==1]]></condition>
        <action><![CDATA[rule1="p1"]]></action>
    </rule>
    <rule id="p2" fromNodeId="mlines" toNodeId="mlines2">
        <condition><![CDATA[2==2]]></condition>
        <action><![CDATA[rule2="p2"]]></action>
    </rule>
    <parallel id="mlines2" fromNodeId="p2">
        <line toNodeId="p3"/>
        <line toNodeId="p4"/>
    </parallel>
    <rule id="p3" fromNodeId="mlines2" toNodeId="merge">
        <condition><![CDATA[1==1]]></condition>
        <action><![CDATA[rule3="p3"]]></action>
    </rule>
    <rule id="p4" fromNodeId="mlines2" toNodeId="merge">
        <condition><![CDATA[2==2]]></condition>
        <action><![CDATA[rule4="p4"]]></action>
    </rule>
    
    <merge id="merge" fromNodeId="p3,p4" lineCnt="2" toNodeId="p5"/>
    
    <rule id="p5" fromNodeId="merge" toNodeId="end">
        <condition><![CDATA[2==2]]></condition>
        <action><![CDATA[rule5="p5"]]></action>
    </rule>
    <end id="end"/>
</flow>

 

执行规则代码:

package org.wei86609.osmanthus;

import junit.framework.TestCase;

import org.wei86609.osmanthus.event.Event;

public class OsmanthusExecutorTest extends TestCase {

    public void testExecute() {
        Event event=new Event();
        event.setEventId("flow1");
        event.add("salary", 5000);
        event.add("weight", 500);
        event.add("isBlackName", true);
        event.add("fee", 500);
        event.add("name", "test");
        event.add("reg", "12312");
        try {
            OsmanthusExecutor executor=  new OsmanthusExecutor();
            executor.newEvent(event, null);

            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

 

输出结果:

2017-07-02 23:12:47,644-DEBUG [pool-1-thread-1]->(FlowEngine.java:37) Osmanthus start to execute the event[Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=500, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]]
2017-07-02 23:12:47,896-DEBUG [pool-1-thread-1]->(FlowEngine.java:41) Node is blank, will get the first node [start] of flow to execute.
2017-07-02 23:12:47,896-DEBUG [pool-1-thread-1]->(EmptyNodeExecutor.java:13) The empty node[start] of the event{Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=500, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]} executed.
2017-07-02 23:12:47,899-DEBUG [pool-1-thread-1]->(GeneralRuleSetExecutor.java:33) The ruleset[feerule] of the event{Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=500, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]} has [8] rules
2017-07-02 23:12:47,976-DEBUG [pool-1-thread-1]->(RuleExecutor.java:22) The node[step2] of the event {flow1} condition=[salary>3500 && salary<=5000] is true and action=[fee=(salary-3500)*0.03]
2017-07-02 23:12:47,977-DEBUG [pool-1-thread-1]->(GeneralRuleSetExecutor.java:64) The node[step2] of the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]} is exclusive, remain nodes will not be executed.
2017-07-02 23:12:47,978-DEBUG [pool-1-thread-1]->(SplitRuleExecutor.java:18) Split[split1] of the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]} has [2] Constraints
2017-07-02 23:12:47,978-DEBUG [pool-1-thread-1]->(SplitRuleExecutor.java:21) Split[split1] of the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]} Constraint's condition [fee>1] result is true, will link to Node[card].
2017-07-02 23:12:47,978-DEBUG [pool-1-thread-1]->(GeneralRuleSetExecutor.java:33) The ruleset[card] of the event{Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=500, reg=12312, name=test, salary=5000}]} has [4] rules
2017-07-02 23:12:47,979-DEBUG [pool-1-thread-1]->(RuleExecutor.java:22) The node[gc2] of the event {flow1} condition=[isBlackName] is true and action=[weight=weight-200]
2017-07-02 23:12:47,980-DEBUG [pool-1-thread-1]->(RuleExecutor.java:22) The node[gc3] of the event {flow1} condition=[name=='test'] is true and action=[weight=weight-500]
2017-07-02 23:12:47,982-DEBUG [pool-1-thread-1]->(RuleExecutor.java:22) The node[gc4] of the event {flow1} condition=[reg ~= "[1-9][0-9]{4,}"] is true and action=[weight=weight-600]
2017-07-02 23:12:47,983-DEBUG [pool-1-thread-1]->(ParallelRuleExecutor.java:21) Parallel[mlines] of the event {flow1} has [2] thread lines
2017-07-02 23:12:47,984-DEBUG [pool-1-thread-1]->(FlowEngine.java:44) Osmanthus execute the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, reg=12312, name=test, salary=5000}]} end
2017-07-02 23:12:47,984-DEBUG [pool-1-thread-2]->(FlowEngine.java:37) Osmanthus start to execute the event[Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={isBlackName=true, fee=45.0, weight=-800, reg=12312, name=test, salary=5000}]]
2017-07-02 23:12:47,985-DEBUG [pool-1-thread-3]->(FlowEngine.java:37) Osmanthus start to execute the event[Event [eventId=flow1, threadId=pool-1-thread-3, model=FIRST, parameters={isBlackName=true, fee=45.0, weight=-800, reg=12312, name=test, salary=5000}]]
2017-07-02 23:12:48,032-DEBUG [pool-1-thread-2]->(RuleExecutor.java:22) The node[p1] of the event {flow1} condition=[1==1] is true and action=[rule1="p1"]
2017-07-02 23:12:48,033-DEBUG [pool-1-thread-2]->(EmptyNodeExecutor.java:13) The empty node[end] of the event{Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={isBlackName=true, fee=45.0, weight=-800, reg=12312, name=test, rule1=p1, salary=5000}]} executed.
2017-07-02 23:12:48,033-DEBUG [pool-1-thread-2]->(FlowEngine.java:44) Osmanthus execute the event {Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={isBlackName=true, fee=45.0, weight=-800, reg=12312, name=test, rule1=p1, salary=5000}]} end
2017-07-02 23:12:48,070-DEBUG [pool-1-thread-3]->(RuleExecutor.java:22) The node[p2] of the event {flow1} condition=[2==2] is true and action=[rule2="p2"]
2017-07-02 23:12:48,070-DEBUG [pool-1-thread-3]->(ParallelRuleExecutor.java:21) Parallel[mlines2] of the event {flow1} has [2] thread lines
2017-07-02 23:12:48,070-DEBUG [pool-1-thread-2]->(FlowEngine.java:37) Osmanthus start to execute the event[Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, reg=12312, name=test, salary=5000, rule2=p2}]]
2017-07-02 23:12:48,070-DEBUG [pool-1-thread-3]->(FlowEngine.java:44) Osmanthus execute the event {Event [eventId=flow1, threadId=pool-1-thread-3, model=FIRST, parameters={isBlackName=true, fee=45.0, weight=-800, reg=12312, name=test, rule2=p2, salary=5000}]} end
2017-07-02 23:12:48,070-DEBUG [pool-1-thread-1]->(FlowEngine.java:37) Osmanthus start to execute the event[Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, reg=12312, name=test, salary=5000, rule2=p2}]]
2017-07-02 23:12:48,115-DEBUG [pool-1-thread-2]->(RuleExecutor.java:22) The node[p3] of the event {flow1} condition=[1==1] is true and action=[rule3="p3"]
2017-07-02 23:12:48,116-DEBUG [pool-1-thread-2]->(MergeNodeExecutor.java:16) Merge[merge] of the event {Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, reg=12312, name=test, rule3=p3, salary=5000, rule2=p2}]} has [0] threads need to merge
2017-07-02 23:12:48,116-DEBUG [pool-1-thread-1]->(RuleExecutor.java:22) The node[p4] of the event {flow1} condition=[2==2] is true and action=[rule4="p4"]
2017-07-02 23:12:48,117-DEBUG [pool-1-thread-1]->(MergeNodeExecutor.java:16) Merge[merge] of the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, rule4=p4, reg=12312, name=test, salary=5000, rule2=p2}]} has [0] threads need to merge
2017-07-02 23:12:48,117-DEBUG [pool-1-thread-2]->(MergeNodeExecutor.java:18) Merge[merge] of the event {Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, reg=12312, name=test, rule3=p3, salary=5000, rule2=p2}]} will merge all threads
2017-07-02 23:12:48,117-DEBUG [pool-1-thread-1]->(MergeNodeExecutor.java:18) Merge[merge] of the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, rule4=p4, reg=12312, name=test, salary=5000, rule2=p2}]} will merge all threads
2017-07-02 23:12:48,117-DEBUG [pool-1-thread-2]->(RuleExecutor.java:22) The node[p5] of the event {flow1} condition=[2==2] is true and action=[rule5="p5"]
2017-07-02 23:12:48,117-DEBUG [pool-1-thread-1]->(RuleExecutor.java:22) The node[p5] of the event {flow1} condition=[2==2] is true and action=[rule5="p5"]
2017-07-02 23:12:48,118-DEBUG [pool-1-thread-2]->(EmptyNodeExecutor.java:13) The empty node[end] of the event{Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, rule5=p5, reg=12312, name=test, rule3=p3, salary=5000, rule2=p2}]} executed.
2017-07-02 23:12:48,118-DEBUG [pool-1-thread-1]->(EmptyNodeExecutor.java:13) The empty node[end] of the event{Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, rule5=p5, rule4=p4, reg=12312, name=test, salary=5000, rule2=p2}]} executed.
2017-07-02 23:12:48,118-DEBUG [pool-1-thread-2]->(FlowEngine.java:44) Osmanthus execute the event {Event [eventId=flow1, threadId=pool-1-thread-2, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, rule5=p5, reg=12312, name=test, rule3=p3, salary=5000, rule2=p2}]} end
2017-07-02 23:12:48,118-DEBUG [pool-1-thread-1]->(FlowEngine.java:44) Osmanthus execute the event {Event [eventId=flow1, threadId=pool-1-thread-1, model=FIRST, parameters={fee=45.0, isBlackName=true, weight=-800, rule5=p5, rule4=p4, reg=12312, name=test, salary=5000, rule2=p2}]} end

 

 

 

  • 大小: 29.8 KB
分享到:
评论

相关推荐

    英敏特月度热点成分:桂花 Ingredient Newsletter - 【BPC vol2】- Osmanthus - final.pdf

    英敏特月度热点成分:桂花 Ingredient Newsletter - 【BPC vol2】- Osmanthus - final.pdf

    osmanthus:BubbleTeam的模拟服务器

    osmanthus(桂花)这个名字的由来:公司大神的框架Pomelo(柚子), 于是也想弄个水果当名字,不想水果太火热了,npm上基本都注册完了。那就用花吧,刚好园区里的桂花开了,就它了。 osmanthus?这是个什么东东? ...

    桂花OfMYB1和OfMYB2基因的克隆与表达特性分析

    桂花OfMYB1和OfMYB2基因的克隆与表达特性分析,丁海琴,曾祥玲,桂花(Osmanthus fragrance)属于木犀科木犀属植物,具有非常重要的园林应用价值和经济价值。研究利用转录组测序获得的表达序列信息,�

    桂花花瓣醇酰基转移酶基因的克隆与表达分析

    桂花花瓣醇酰基转移酶基因的克隆与表达分析,刘偲,曾祥玲,本试验从桂花品种'柳叶金桂'(Osmanthus fragrans'Liuye Jingui' )花瓣中克隆得到一个醇酰基转移酶基因,命名为OfAAT1。该基因全长1386bp, 编码46

    4种景观林对空气微生物的抑制作用 (2010年)

    为了探讨不同林地对空气微生物的影响,以浙江林学院东湖校区为样地,采用自然沉降法,于春季对樟树 Cin-namomum camphora,桂花 Osmanthus fragrans,杨梅 Myrica rubra和黄皮刚竹 Phyllostachys viridis林的空气微生物...

    桂花切花品种筛选 (2006年)

    对17个桂花Osmanthus fragrans品种的小花花冠径、着花繁密程度、花色、花香程度、花枝形态等特点进行调查研究。选择生长正常的健康植株采样,其中繁殖器官样本数为10,营养器官样本数为20。根据切花分级标准与桂花的...

    桂花在城市绿化中的应用 (2001年)

    桂花(Osmanthus fragrans)在亚洲热带地区的长江流域栽培十分普遍,应用广泛,现将桂花城市绿化中的应用作一概述。

    360天擎杀毒软件

    杀毒软件,也称反病毒软件或防毒软件,是用于消除电脑病毒、特洛伊木马和恶意软件等计算机威胁的一类软件。

Global site tag (gtag.js) - Google Analytics