欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[Drools Demos] 其 (三) : 动态加载规则文件

程序员文章站 2022-03-03 15:54:42
...

前言

本章主要探讨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();
		
	}

}

  1. 先创建KieModuleModel;
  1. 再创建KieBaseModel;
  2. 然后创建 KieSessionModel;
  3. 创建完成之后可以生产一个xml文件,就是kmodule.xml文件了;
  4. 将这个xml文件写入到KieFileSystem中;
  5. 然后将规则文件等写入到KieFileSystem中;
  6. 最后通过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();

(*) drools dynamic