最近公司准备启动一个风险系统,架构中用到urule与flowable,捣鼓了好几天,踩了很多坑,算是初步写出一个demo,顺手记录一下
URule是一款基于RETE算法纯Java的开源规则引擎产品,提供了向导式规则集、脚本式规则集、决策表、决策树、评分卡及决策流共六种类型的规则定义方式,配合基于WEB的设计器,可快速实现规则的定义、维护与发布。
用来替换原有的drools规则引擎,有一部分原因是因为URule自带了配置规则的UI界面
本例中采用urule客户端与服务端分离的设计
urule的Server端,用来配置规则(知识包),并暴露给客户端,本例中知识库存储在mysql数据库中
springboot的配置可以详见URule官方文档
@Component
public class URuleServletRegistration {
@Bean
public ServletRegistrationBean registerURuleServlet(){
return new ServletRegistrationBean(new URuleServlet(),"/urule/*");
}
}
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/world?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 1234
jackson:
default-property-inclusion: non_null
urule:
repository:
databasetype: mysql
datasourcename: datasource
server:
port: 8787
@Configuration
@ImportResource({"classpath:urule-console-context.xml"})
@PropertySource(value = {"classpath:urule-console-context.properties"})
public class Config {
@Bean
public PropertySourcesPlaceholderConfigurer propertySourceLoader() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setIgnoreUnresolvablePlaceholders(true);
configurer.setOrder(1);
return configurer;
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource datasource() {
return DataSourceBuilder.create().build();
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
访问地址:http://localhost:8787/urule/frame 即可看到urule的规则配置页面
Urule的客户端,即调用规则的一方
urule:
resporityServerUrl: http://localhost:8787
knowledgeUpdateCycle: 1
server:
port: 7878
@Configuration
@ImportResource({"classpath:urule-core-context.xml"})
public class RuleConfig {
@Bean
public PropertySourcesPlaceholderConfigurer propertySourceLoader() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setIgnoreUnresolvablePlaceholders(true);
configurer.setOrder(1);
return configurer;
}
}
此Servlet用于接收Urule服务端发布的知识包(不想用这个功能可以不配)
@Component
public class URuleServletRegistration {
@Bean
public ServletRegistrationBean registerURuleServlet(){
return new ServletRegistrationBean(new KnowledgePackageReceiverServlet(),"/knowledgepackagereceiver");
}
}
@SpringBootApplication
public class RuleApplication {
public static void main(String[] args) {
SpringApplication.run(RuleApplication.class, args);
}
}
到这里Urule的服务端和客户端就都配置完了。
由于嫌官方文档的sample太麻烦,这里我自己写了个简单的规则作为测试用途
@RestController
public class RuleController {
@RequestMapping("rule")
public String rule(@RequestParam String data) throws IOException {
//创建一个KnowledgeSession对象
KnowledgeService knowledgeService = (KnowledgeService) Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
KnowledgePackage knowledgePackage = knowledgeService.getKnowledge("aaa/bag");
KnowledgeSession session = KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
Integer integer = Integer.valueOf(data);
Map param = new HashMap();
param.put("var", integer);
session.fireRules(param);
Integer result = (Integer) session.getParameter("var");
return String.valueOf(result);
}
}
访问 http://localhost:7878/rule?data=50 和 http://localhost:7878/rule?data=40
可以看到页面上分别打印500和20,执行规则成功
https://github.com/worstEzreal/urule_springboot