版权声明:欢迎转载,转载请说明出处https://csdn.yanxml.com。大数据Github项目地址https://github.com/SeanYanxml/bigdata。 https://blog.csdn.net/u010416101/article/details/87887894
前言
本章主要探讨Drools的动态加载.有很多时候,规则文件是存储在数据库或其他地方,这就要求我们对于Drools规则
文件的装配过程和装配过程中关键的几个对象非常熟悉,例如:KieFileSystem / KieModule/ KieBase / KieContainer / KieSession...
.
本章主要对应项目内的drools-filesystem
内容.
基础配置: JDK 1.7 + Eclipse Mar + Maven
依赖: Drools插件(非必须)
本章主要对应项目内的drools-quickstart
子模块.
Github地址: https://github.com/SeanYanxml/drools-train
动态加载方式
- Method1 - 通过KieModuleModel装载
package com.yanxml.drools.filesystem;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message.Level;
import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.io.KieResources;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class KieFileSystemTest {
@Test
public void test(){
KieServices kieServices = KieServices.Factory.get();
KieResources resources = kieServices.getResources();
// 构建 kmodule.xml配置文件
KieModuleModel kieModuleModel = kieServices.newKieModuleModel(); //1
KieBaseModel baseModel = kieModuleModel.newKieBaseModel("FileSystemKBase").addPackage("rules");//2
baseModel.newKieSessionModel("FileSystemKSession"); //3
// 加载 kmodule.xml配置文件 和 .drl规则文件
KieFileSystem fileSystem = kieServices.newKieFileSystem();
String xml = kieModuleModel.toXML();
System.out.println(xml); //4
fileSystem.writeKModuleXML(xml);
// 自动加载drl 规则文件
// fileSystem.write(resources
// .newClassPathResource("kiefilesystem/KieFileSystemTest.drl"));
fileSystem.write("src/main/resources/rules/rule.drl",resources
.newClassPathResource("kiefilesystem/KieFileSystemTest.drl"));//6 加载了两个drl配置文件
// 根据 kmodule.xml配置文件 和 .drl规则文件 加载KieContainer模型
KieBuilder kieBuilder = kieServices.newKieBuilder(fileSystem);
kieBuilder.buildAll(); //7
// 获取构建的结果 如果存在异常的情况 作相应的处理
if(kieBuilder.getResults().hasMessages(Level.ERROR)){
throw new RuntimeException("Build Errors:\n"
+ kieBuilder.getResults().toString());
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
kieContainer.getKieBase("FileSystemKBase");
KieSession kieSession = kieContainer.newKieSession("FileSystemKSession");
kieSession.fireAllRules();
}
}
- 先创建KieModuleModel;
- 再创建KieBaseModel;
- 然后创建 KieSessionModel;
- 创建完成之后可以生产一个xml文件,就是kmodule.xml文件了;
- 将这个xml文件写入到KieFileSystem中;
- 然后将规则文件等写入到KieFileSystem中;
- 最后通过KieBuilder进行构建就将该kmodule加入到KieRepository中了。这样就将自定义的kmodule加入到引擎中了,就可以按照之前的方法进行使用了。
- Method2 - 直接装载
package com.yanxml.drools.filesystem;
import org.junit.Test;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieContainer;
/**
* 生产环境所用的KieFileSystem。都是用于动态加载。与KieFileSyetmTest略有差别。
*
* */
public class DynamicKieFileSystemTest {
@Test
public void test(){
String ruleFilePath = "package com.yanxml.drools.files \n rule \"Test KieFileSystem\" \n when \n then \n System.out.println( \"hello, KieFileSystem\" ); \n end";
try {
// 设置时间格式
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
Resource resource = kieServices.getResources().newFileSystemResource(ruleFilePath);
System.out.println(resource.toString());
resource.setResourceType(ResourceType.DRL);
kfs.write(resource);// 将XML配置文件写入kieFileSystem内
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
if (kieBuilder.getResults().getMessages(Message.Level.ERROR).size() > 0) {
throw new RuntimeException(kieBuilder.getResults().getMessages().toString());
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
KieBase kBase = kieContainer.getKieBase();
kBase.newKieSession().fireAllRules();
//放入缓存
} catch (Exception e) {
}
}
}
- Method 3(与Method 2 比较相似)
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem();
FileInputStream fis = new FileInputStream( "sale/sale.drl" );
kfs.write( "src/main/resources/sale.drl",
ks.getResources().newInputStreamResource( fis ) );
KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll();
Results results = kieBuilder.getResults();
if( results.hasMessages( Message.Level.ERROR ) ){
System.out.println( results.getMessages() );
throw new IllegalStateException( "### errors ###" );
}
KieContainer kieContainer =
ks.newKieContainer( ks.getRepository().getDefaultReleaseId() );
// CEP - get the KIE related configuration container and set the EventProcessing (from default cloud) to Stream
KieBaseConfiguration config = ks.newKieBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
KieBase kieBase = kieContainer.newKieBase( config );
// KieSession kieSession = kieContainer.newKieSession();
KieSession kieSession = kieBase.newKieSession();