java - 在运行时动态更新规则。Drools + Spring-Boot
问题描述
所以目前我正在练习使用 Drools (7.13.0.Final) 和 Spring-boot(1.5.12.RELEASE)。我在 Spring-boot 中制作了一个示例应用程序,其中包含以下类
模型:TaxiFare.java
@Data
public class TaxiFare {
private double surge;
private double netFare;
private double baseFare;
private double distanceTraveled;
}
服务:TaxiFareService.java
@Service
public class TaxiFareService {
@Autowired
private KieContainer kieContainer;
public TaxiFare getTaxiFare(TaxiFare fare) {
KieSession kieSession = kieContainer.newKieSession("rulesSession");
kieSession.insert(fare);
kieSession.fireAllRules();
kieSession.dispose();
return fare;
}
}
休息控制器:TaxiFareController.java
@RestController
public class TaxiFareController {
@Autowired
private TaxiFareService taxiFareService;
@RequestMapping(value = "/getFare", method = RequestMethod.GET)
public String getQuestions(@RequestParam(required = true) double baseFare, @RequestParam(required = true) double surge, @RequestParam(required = true) double distanceTraveled) {
TaxiFare fare = new TaxiFare();
fare.setBaseFare(baseFare);
fare.setSurge(surge);
fare.setDistanceTraveled(distanceTraveled);
taxiFareService.getTaxiFare(fare);
return String.format("NET FARE IS: %s", fare.getNetFare());
}
}
配置:
@Bean
public KieContainer kieContainer2() {
return KieServices.Factory.get().getKieClasspathContainer();
}
具有定义的规则
rule "No Surge"
when
$fareObject: TaxiFare(surge == 0.0);
then
$fareObject.setNetFare($fareObject.getBaseFare() * $fareObject.getDistanceTraveled());
end
rule "Has Surge"
when
$fareObject: TaxiFare(surge > 0.0);
then
$fareObject.setNetFare($fareObject.getSurge() * $fareObject.getBaseFare() * $fareObject.getDistanceTraveled());
end
我已经使用我在网上找到的各种 Drools + Spring 集成教程构建了这个示例应用程序。目前,规则引擎可以正常工作,但我想要做的是每次添加新规则或修改现有规则时,我希望能够在应用程序运行时动态重新加载规则文件。该应用程序被打包为 WAR 并部署在 Web 服务器中。
我已经阅读了多篇关于使用的文章,KieScanner
但没有一篇关于它的书面教程,甚至是文档本身。按照他们提供的示例代码,
KieScanner kieScanner = kieServices.newKieScanner(kieContainer);
总是导致构建失败,因为 newKieScanner 似乎无法根据提供的 kieContainer 创建 kieScanner。有没有其他方法可以为 Drools 设置动态规则或说明如何正确实施 KieScanner?
谢谢你。
解决方案
你可以试试这个,实际上效果很好
@Test
public void messageRuleFromUTFString() {
String ruleContent =
"package rules\r\n"+
"import mypackage.Message\r\n" +
"rule \"myrule\"\r\n" +
" \twhen\r\n" +
" $id : Message([\"38196-2\"] contains id)\r\n" +
" then\r\n" +
"\t\tSystem.out.println(\"Works!\");\r\n" +
"end\r\n";
KieSession kSession = null;
try {
KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
kb.add(ResourceFactory.newByteArrayResource(ruleContent.getBytes("utf-8")), ResourceType.DRL);
KnowledgeBuilderErrors errors = kb.getErrors();
for (KnowledgeBuilderError error : errors) {
System.out.println(error);
}
InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
kBase.addPackages(kb.getKnowledgePackages());
kSession = kBase.newKieSession();
kSession.insert(createMessage("38196-2"));
kSession.fireAllRules();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} finally {
if (kSession != null)
kSession.dispose();
}
}
感谢其中一位 github 用户。我的例子稍微修改为最新版本的drools: https ://github.com/ityouknow/drools-examples.git
推荐阅读
- gdscript - 我的向量 3 速度上限公式有什么问题?
- python - 为什么我的敌人 x 值不从 0 变化,即使它明显在移动?
- codeigniter - 在表单提交之前获取 form_open 中下拉列表的值
- excel - 如何过滤数据透视表中的过滤器
- c# - 当请求传入代理通过 http 时,如何从 ftp 代理返回 ftp 响应?
- git - Git 推送失败并出现错误:“GitLab:作者不是团队成员”
- c - 在 macOS 中安全地检查指针的有效性?
- excel - 如何通过引用列位置使用 Excel PowerQuery 将派生列添加到透视表
- visual-studio - VS2019 中缺少“添加-> 负载测试”
- javascript - Promise then() 方法没有按预期触发?