liteflow规则引擎使用示例和rule源扩展

背景

项目中有一些业务场景存在动态调整的情况,所以打算引进一个规则引擎来处理,其实一开始没打算用规则引擎,规则直接用Groovy脚本也能实现;后面经过分析,如果用Groovy脚本直接实现可能这个脚本会非常大,因为存在很多条件判断的情况和组合的情况,所以还是要引进一个开源规则引擎会更好。

通过对比各种规则引擎:Drools、urule、ICE、NoP、liteflow,最终选择了liteflow,主要基于以下原因:

  • liteflow够简单,使用门槛不高;深入使用功能也够强大
  • liteflow支持Groovy、Javascript、Python等各种脚本方式,学习成本较低,其他规则引擎都得重新学习脚本
  • liteflow也算是经过多轮版本演进了,看起来稳定性还可以
  • 生态较好,挺活跃的

对Liteflow规则RULE的扩展

Liteflow规则的处理方式有本地、Redis、Nacos、SQL方式,为了方便集中管理,打算采用SQL方式。
通过使用Liteflow的SQL方式,发现其实不是特别方便,Liteflow的SQL方式是将规则做成行的方式,一行行的解析并拼接成XML进行解析,通过查看数据库很难看到整个流程的全貌,维护起来不太方便。这里自己基于源码liteflow-rule-sql重新封装了一个rule,liteflow的rule是基于SPI机制,所以封装起来还是比较方便。

主要修改了com.yomahub.liteflow.parser.sqlext.SQLXmlELParser这个类。
重新实现了parseMain方法,这个方法能支持加载多个xml content内容。
修改JDBCHelper增加getContents()方法返回多个XML结果给到liteflow解析。

	@Override
	public void parseMain(List<String> pathList) throws Exception {
		List<String> contents = JDBCHelper.getInstance().getContents();
		parse(contents);
	}

	@Override
	public String parseCustom() {
		return null;
	}

使用例子

规则脚本配置

添加基于数据库的规则脚本:

 CREATE TABLE `liteflow_script` (
 `uri` VARCHAR(50) NOT NULL,
 `name` VARCHAR(100) NOT NULL COMMENT '脚本名称',
 `content` TEXT DEFAULT NULL COMMENT 'XML规则内容',
 `app_name` VARCHAR(100) NOT NULL COMMENT '所属应用',
 `extend` VARCHAR(100) DEFAULT NULL COMMENT '扩展信息',
 `flag` INT(5) DEFAULT '0' COMMENT '状态标记',
 `del_flag` INT(5) DEFAULT '0' COMMENT '逻辑删除标记',
 `create_by` VARCHAR(40) DEFAULT NULL COMMENT '创建者',
 `update_by` VARCHAR(40) DEFAULT NULL COMMENT '更新者',
 `create_date` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
 `update_date` DATETIME NULL DEFAULT NULL COMMENT '更新时间',
 `fk_domain` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '所属域',
 `fk_group` VARCHAR(100) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '所属部门',
 PRIMARY KEY (`uri`)
 );
 
 
INSERT INTO `liteflow_script` (`uri`, `name`, `content`, `app_name`, `extend`, `flag`, `del_flag`, `create_by`, `update_by`, `create_date`, `update_date`, `fk_domain`, `fk_group`) VALUES ('001', '测试脚本', '\r\n    \r\n        \r\n            \r\n        \r\n    \r\n    THEN(a, b, c, s1);\r\n', 'ucloud-demoliteflow', NULL, 0, 0, NULL, NULL, '2023-09-14 16:29:03', NULL, NULL, NULL);

liteflow规则引擎使用示例和rule源扩展_第1张图片

groovy脚本不会写的话可以先在IDE工具中添加groovy脚本和XML配置文件,然后将其拷贝到mysql配置中
liteflow规则引擎使用示例和rule源扩展_第2张图片

工程配置和示例代码

pom.xml依赖:
其中ucloud-starter-literflowrule-sql是自定义的开发的liteflow-rule规则配置(基于SQL)


<dependency>
	<groupId>com.yomahubgroupId>
	<artifactId>liteflow-spring-boot-starterartifactId>
	<version>2.11.0version>
dependency>
<dependency>
	<groupId>com.yomahubgroupId>
	<artifactId>liteflow-script-groovyartifactId>
	<version>2.11.0version>
dependency>
<dependency>
	<groupId>com.ucloudgroupId>
	<artifactId>ucloud-starter-liteflowrule-sqlartifactId>
	<version>1.0.0-SNAPSHOTversion>
dependency>

创建一些测试类:
cmp下面的是一些spring boot的liteflow组件类(参考liteflow的demo拷贝过来的)。
OrderVO,一个临时的订单类
TestLiteFlowServiceImpl是执行规则的服务,具体内容:

@Slf4j
@Service
public class TestLiteFlowServiceImpl {
    @Autowired
    private FlowExecutor flowExecutor;

    public Object execute(OrderVO orderVO) {
        Map<String, Object> params = new HashMap<>();
        params.put("order", orderVO);
        LiteflowResponse response = flowExecutor.execute2Resp("chain1", params, DefaultContext.class);
        log.info("返回结果:{}", response);
        return response.getContextBean(DefaultContext.class).getData("res");
    }
}

liteflow规则引擎使用示例和rule源扩展_第3张图片
TestController中增加两个调用入口:

    @Autowired
    private TestLiteFlowServiceImpl testLiteFlowService;
    @Autowired
    private FlowExecutor flowExecutor;
    @GetMapping("/liteflow")
    public ResultVO liteFlow() {
        OrderVO orderVO = new OrderVO("订单01", 100, 21);
        log.info("req order:", orderVO);
        Object resObj = testLiteFlowService.execute(orderVO);
        log.info("res order:", orderVO);
        return ResultVO.success(resObj);
    }

    @GetMapping("/reloadLiteFlow")
    public ResultVO reloadLiteFlow() {
        log.info("刷新配置信息");
        flowExecutor.reloadRule();
        return ResultVO.success();
    }

这个例子的执行过程是:

  • 创建一个订单数据
  • 执行规则引擎,引擎中执行a,b,c,s1三个组件,其中s1是脚本
  • s1脚本中拿到order修改其中的值然后放到context中
  • 输出修改后的order值

执行调用测试

执行脚本:
http://localhost:6018/test/liteflow
执行结果:

 c.u.p.d.controller.TestController        : req order:OrderVO(name=订单01, price=100, count=21)
ACmp executed!
BCmp executed!
CCmp executed!
规则数据:chain1, s1
请求数据:[order:OrderVO(name=订单01, price=100, count=21)]
 c.u.p.d.controller.TestController        :order:OrderVO(name=订单01, price=100, count=21)

修改脚本后刷新脚本:
http://localhost:6018/test/reloadLiteFlow

总体上集成和使用还是比较简单的。

liteflow官网地址:https://liteflow.cc/

你可能感兴趣的:(JAVA,java,后端,数据结构)