首页 > 代码库 > drools6 基本使用2

drools6 基本使用2

<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">续drools6 基本使用1</span>

8. 创建src/main/test folder,把droolsTest.java移动到test folder,把droolsTest.java改装成junit test case,执行mvn test,确保rules运行没有问题


9. 执行mvn install 把rules打包成jar文件上传到本地库


Note: 如果rule文件里面有中文,记得要把文件保存成utf-8格式,然后测试的时候保证maven的surefire plugin加上了使用utf-8的运行参数,否则会乱码出错


10. 在另外一个项目中使用drools,主要是借助kie-ci框架,实现启动load rules,动态修改rules和执行规则

maven文件改动,加入如下依赖:

<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
</dependency

java代码:创建一个ruleservice接口和实现类,实现以下方法:启动load rules(initService),动态修改(refreshService), 执行规则(fireService)

	public void initService(String groupId, String artifactId, String version)  throws NotExistsException {
		ks = KieServices.Factory.get();
		try{
			kContainer = ks.newKieContainer(ks.newReleaseId(groupId, artifactId, version));
		} catch (Exception e){
			StringBuilder sb = new StringBuilder("fail to get maven rules kmodule from groupId: [");
			sb.append(groupId).append("] artifactId: [").append(artifactId).append("] version: [").append(version).append("]");
			throw new NotExistsException(sb.toString());
		}
		if(null != kContainer)
			kSession = kContainer.newStatelessKieSession("ksession-rules");
	}

	@Override
	public void refreshService(String groupId, String artifactId, String version) throws NotExistsException {
		try{
			kContainer.updateToVersion(ks.newReleaseId(groupId, artifactId, version));
		} catch (Exception e){
			StringBuilder sb = new StringBuilder("fail to get maven rules kmodule from groupId: [");
			sb.append(groupId).append("] artifactId: [").append(artifactId).append("] version: [").append(version).append("]");
			throw new NotExistsException(sb.toString());
		}
		if(null != kContainer)
			kSession = kContainer.newStatelessKieSession("ksession-rules");
	}

	@Override
	public void fireService(Message info) {
		kSession.execute(info);
	}

11. 基本测试,对于使用drools和直接写java代码,显然使用drools可以实现动态部署,更具优势,不过有人担心性能受到影响,这里我做了一下测试,

我这里的测试是基于一个自己写的rule规则,对对象的某些字段做业务逻辑处理,选择使用java代码和使用drools,看耗时差别,当然这个测试很简陋,也没有对drools使用做优化,也没有看CPU和内存使用情况

业务逻辑代码:

public void setMatchThresholdsInfo(CustomerInfo info) {
		String temp = info.getProfessionCode();
		// boolean flag = false;
		if (null == temp || 0 == (temp.trim()).length() || "其他".equals(temp) || "其它".equals(temp) || "无业".equals(temp) || "未知".equals(temp)) {
			info.setRiskValue(info.getRiskValue() + 20);
		    info.setRiskType(info.getRiskType() + " Invalid professionCode value: " + info.getProfessionCode());
		}
		if (info.getCertificateEndDate() == null
				|| info.getCertificateEndDate().before(new Date())) {
			 info.setRiskValue(info.getRiskValue() + 80);
		     info.setRiskType(info.getRiskType() + " Invalid Certification End date value: " + info.getCertificateEndDate());
		}
		if (info.getCustomerName() == null || info.getCustomerName().trim().length() == 0) {
			info.setRiskValue(info.getRiskValue() + 80);
			info.setRiskType(info.getRiskType() + " Customer Name is null");
		}
		if (info.getCertificateId() == null || 0 == (info.getCertificateId().trim()).length()) {
			info.setRiskValue(info.getRiskValue() + 80);
			 info.setRiskType(info.getRiskType() + " Invalid Certification ID: " + info.getCertificateId());
		}
		if (null == info.isForeignFlag() ||info.isForeignFlag()) {
			info.setRiskValue(info.getRiskValue() + 20);
			info.setRiskType(info.getRiskType() + " 境外标志: " + info.getForeignFlag());
		}
		
		info.setRiskType(info.getRiskType().trim());
	}
rule规则:

//created on: May 19, 2014
package com.elulian.CustomerSecurityManagementSystem.service.impl

//list any import classes here.
import com.elulian.CustomerSecurityManagementSystem.vo.CustomerInfo
import java.util.Date

//declare any global variables here

rule "Profession Rule"
       //include attributes such as "salience" here... 
       
    when
       //conditions
       info : CustomerInfo (null == professionCode || 0 == (info.getProfessionCode().trim()).length() || "其他".equals(professionCode) || "其它".equals(professionCode) || "无业".equals(professionCode) || "未知".equals(professionCode))
    then
       //actions
       info.setRiskValue(info.getRiskValue() + 20);
       info.setRiskType(info.getRiskType() + " Invalid professionCode value: " + info.getProfessionCode());
end

rule "Certification End date Rule"
       
    when
        //conditions
        info : CustomerInfo (null == certificateEndDate || certificateEndDate.before(new Date()))
    then
        //actions
       info.setRiskValue(info.getRiskValue() + 80);
       info.setRiskType(info.getRiskType() + " Invalid Certification End date value: " + info.getCertificateEndDate());

end

rule "Customer Name Rule"
        
    when
        //conditions
         info : CustomerInfo (null == customerName || 0 == (info.getCustomerName().trim()).length())
    then
        //actions
         info.setRiskValue(info.getRiskValue() + 80);
         info.setRiskType(info.getRiskType() + " Customer Name is null");

end

rule "Certification ID Rule"
       
    when
        //conditions
        info : CustomerInfo (null == certificateId || 0 == (info.getCertificateId().trim()).length())
    then
        //actions
        info.setRiskValue(info.getRiskValue() + 80);
        info.setRiskType(info.getRiskType() + " Invalid Certification ID: " + info.getCertificateId());
end

/*
rule "Certification ID Rule 2"
   
    when
        //use regx here to check digital and length later
        info : CustomerInfo ("身份证" == certificateType && (15 != (info.getCertificateId().trim()) || 18 != (info.getCertificateId().trim())))
    then
        info.setRiskValue(info.getRiskValue() + 80);
        info.setRiskType(info.getRiskType() + " Invalid Certification ID: " + info.getCertificateId());
end
*/        

rule "Foregin Flag Rule"
        
    when
        info : CustomerInfo (null == foreignFlag || true == foreignFlag)
    then
        //actions
        info.setRiskValue(info.getRiskValue() + 20);
        info.setRiskType(info.getRiskType() + " 境外标志: " + info.getForeignFlag());
end

//execute after all other rules are fired
rule "Trim Risk Type Rule"
    salience -9999
    when 
        info : CustomerInfo (true)
    then 
        info.setRiskType(info.getRiskType().trim());
end

测试代码:

@Test
	public void testExeuctionTime(){
		long recordsNumber = 100000;
		long start = System.currentTimeMillis();
		long used = 0;
		for(int i = 0; i < recordsNumber ; i++){
			CustomerInfo info = new CustomerInfo();
			info.setRiskType("");
			info.setRiskValue(0);
			thresholdService.setCustomerThresholdsInfo(info);
		}
		used = System.currentTimeMillis() - start;
		System.out.println(used);
		
		start = System.currentTimeMillis();
		used = 0;
		for(int i = 0; i < recordsNumber; i++){
			CustomerInfo info = new CustomerInfo();
			info.setRiskType("");
			info.setRiskValue(0);
			thresholdService.setMatchThresholdsInfo(info);
		}
		used = System.currentTimeMillis() - start;
		System.out.println(used);
	}

测试结果:

recordsNumber = 10

54
424

recordsNumber = 100

23
713
[Thread-3] WARN org.drools.core.rule.constraint.MvelConstraint - Exception jitting: null == certificateEndDate || certificateEndDate.before(
new Date()) This is NOT an error and NOT prevent the correct execution since the constraint will be evaluated in intrepreted mode
[Thread-4] WARN org.drools.core.rule.constraint.MvelConstraint - Exception jitting: null == customerName  ||  0 == (info.getCustomerName().t
rim()).length() This is NOT an error and NOT prevent the correct execution since the constraint will be evaluated in intrepreted mode
[Thread-2] WARN org.drools.core.rule.constraint.MvelConstraint - Exception jitting: null == professionCode || 0 == (info.getProfessionCode()
.trim()).length() || "鍏朵粬".equals(professionCode) || "鍏跺畠".equals(professionCode) || "鏃犱笟".equals(professionCode) || "鏈煡".equal
s(professionCode) This is NOT an error and NOT prevent the correct execution since the constraint will be evaluated in intrepreted mode
[Thread-5] WARN org.drools.core.rule.constraint.MvelConstraint - Exception jitting: null == certificateId  ||  0 == (info.getCertificateId()
.trim()).length() This is NOT an error and NOT prevent the correct execution since the constraint will be evaluated in intrepreted mode

recordsNumber = 10000

406

70937

更多rules warning。。。。。。。。有机会和时间要研究下如何调优