PlanConfig.java 4.61 KB
package com.bsth.service.schedule.plan;

import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.builder.model.KieSessionModel;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.internal.io.ResourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 计划配置类。
 */
@Configuration
@EnableConfigurationProperties(PlanConfigProperties.class)
public class PlanConfig {
    /** 日志记录器 */
    private static final Logger LOGGER = LoggerFactory.getLogger(PlanConfig.class);

    /** 计划配置文件 */
    @Autowired
    private PlanConfigProperties planConfigProperties;

    /**
     * 验证时刻表kieBase。
     * @return
     */
    @Bean(name = "kBaseValidateTimetable")
    public KieBase kBaseValidateTimetable() {
        KieBase kieBase = this.generateKieBase(
                "kBaseValidateTimetable",
                new String[] {this.planConfigProperties.getValidateTimetable()}
        );
        LOGGER.info("初始化 KieBase[{}]成功", "前置验证相关时刻表信息");
        return kieBase;
    }

    /**
     * 生成KieBase。
     * @param kBaseName kBase名字
     * @param drlClasspaths 规则类路径
     */
    private KieBase generateKieBase(String kBaseName, String[] drlClasspaths) {
        // Drools 6开始引入kie统一接口(jboss的jbpm工作流也使用kie接口了),整个定义方式和5差别很大
        // 这里使用全api方式配置知识库对象,不使用xml的方式,提供最大的灵活性

        // 1、创建kieservices
        KieServices kieServices = KieServices.Factory.get();

        // 2、创建KieModuleModel,默认是由kmodule.xml的方式创建,这里使用api方式闯将
        KieModuleModel kieModuleModel = kieServices.newKieModuleModel();
        // 2.1、创建KieBaseModel,类似kmodule.xml中的kbase标签
        KieBaseModel kieBaseModel1 = kieModuleModel.newKieBaseModel(kBaseName)
                .setDefault(true)
                .setEqualsBehavior(EqualityBehaviorOption.EQUALITY)
                .setEventProcessingMode(EventProcessingOption.STREAM);
        // 2.2、创建与kbase关联的KieSessionModel,类似kmodule.xml中的kbase内的ksession标签
        kieBaseModel1.newKieSessionModel("KSession1")
                .setDefault(true)
                .setType(KieSessionModel.KieSessionType.STATEFUL)
                .setClockType(ClockTypeOption.get("realtime"));

        // 3、创建KieFileSystem,将模型xml,drl等写入,TODO:以后考虑从数据库中获取
        KieFileSystem kfs = kieServices.newKieFileSystem();
        // 3.1、写入KieBaseModel(内部包含了KieSessionModel的内容了,注意之前的KieSessionModel的创建方式)
        kfs.writeKModuleXML(kieModuleModel.toXML());
        // 3.2、写入drl
        // 这里使用文件的形式写入,TODO:以后考虑从数据库中读drl写入
        // 注意kfs写的时候如果指定path,强制为src/main/resources/加上文件名,还有就是文件名不要重复否则会覆盖的
//        kfs.write(ResourceFactory.newFileResource(new File(rules_root_path + kbase_validate_timetable_drl)));
        for (String drlClasspath : drlClasspaths) {
            kfs.write(ResourceFactory.newClassPathResource(drlClasspath));
        }

        // 4、创建KieBuilder,使用KieFileSystem构建
        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
        Results results = kieBuilder.getResults();
        if (results.hasMessages(Message.Level.ERROR))
            throw new IllegalStateException("构建drools6错误:" + results.getMessages());

        // 5、获取KieContainer
        // TODO:ReleaseId用处很大,以后再议
        ReleaseId releaseId = kieServices.getRepository().getDefaultReleaseId();
        KieContainer kieContainer = kieServices.newKieContainer(releaseId);

        // 6、创建kbase
        KieBaseConfiguration kieBaseConfiguration = kieServices.newKieBaseConfiguration();
        KieBase kieBase = kieContainer.newKieBase(kBaseName, kieBaseConfiguration);

        return kieBase;
    }
}