Java Drools - 应用了哪些规则和事实列表
Java Drools - which Rules are applied and facts list
我对 drools 有点陌生,我想为一个项目了解更多,所以我在 eclipse 上用 drools 做了一个简单的程序。
工作流程非常简单,我有一个珠宝产品模型,对于每件珠宝,我都会根据名称应用一个折扣。
效果很好,但我想查看事实列表以及每个触发规则使用了哪些事实。
我有这个:
Rules.drl
package com.rule
import com.javainuse.model.Product
import com.javainuse.model.Counter
rule "Offer for Diamond"
when
productObject: Product(type=="diamond")
then
productObject.setDiscount(15);
end
rule "Offer for Gold"
when
productObject: Product(type=="gold")
then
productObject.setDiscount(25);
end
model.Product.java
package com.javainuse.model;
public class Product {
private String type;
private int discount;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getDiscount() {
return discount;
}
public void setDiscount(int discount) {
this.discount = discount;
}
}
main.DroolsTest.java
package com.javainuse.main;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collection;
import java.util.Iterator;
import org.drools.compiler.compiler.DroolsParserException;
import org.drools.compiler.compiler.PackageBuilder;
import org.drools.core.FactHandle;
import org.drools.core.RuleBase;
import org.drools.core.RuleBaseFactory;
import org.drools.core.WorkingMemory;
import com.javainuse.model.Product;
public class DroolsTest {
public static void main(String[] args) throws DroolsParserException,
IOException {
DroolsTest droolsTest = new DroolsTest();
droolsTest.executeDrools();
}
public void executeDrools() throws DroolsParserException, IOException {
PackageBuilder packageBuilder = new PackageBuilder();
String ruleFile = "/com/rule/Rules.drl";
InputStream resourceAsStream = getClass().getResourceAsStream(ruleFile);
Reader reader = new InputStreamReader(resourceAsStream);
packageBuilder.addPackageFromDrl(reader);
org.drools.core.rule.Package rulesPackage = packageBuilder.getPackage();
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(rulesPackage);
WorkingMemory workingMemory = ruleBase.newStatefulSession();
Product product = new Product();
Product product2 = new Product();
product.setType("gold");
product2.setType("diamond");
//List of facts!
workingMemory.insert(product);
workingMemory.insert(product2);
workingMemory.fireAllRules();
System.out.println("Discount for " + product.getType() + " is " + product.getDiscount());
System.out.println("Discount for " + product2.getType() + " is " + product2.getDiscount());
//how many facts
System.out.println("There are " + workingMemory.getFactCount() + " facts");
//facts handles
Collection<org.kie.api.runtime.rule.FactHandle> x = workingMemory.getFactHandles();
System.out.println("Facts Handles: " + x +"\n");
FactHandle fh;
Iterator<org.kie.api.runtime.rule.FactHandle> it = x.iterator();
while(it.hasNext())
{
fh = (FactHandle) it.next();
System.out.println("FactHandle to string "+fh.toExternalForm().toString());
}
}
}
输出:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Discount for gold is 25
Discount for diamond is 15
There are 2 facts
Facts Handles: [[fact 0:2:1889057031:1889057031:2:DEFAULT:NON_TRAIT:com.javainuse.model.Product@7098b907], [fact 0:1:93199773:93199773:1:DEFAULT:NON_TRAIT:com.javainuse.model.Product@58e1d9d]]
FactHandle to string 0:2:1889057031:1889057031:2:DEFAULT:NON_TRAIT
FactHandle to string 0:1:93199773:93199773:1:DEFAULT:NON_TRAIT
I want something like this:
Discount for gold is 25
Discount for diamond is 15
There are 2 facts: gold, diamond
gold triggered rule Offer for Gold
diamond triggered Offer for Diamond
可能吗?我检查了 WorkingMemory、Endpoint、FactHandle 的 类,但什么也没有。
您可以使用 AgendaEventListener
在规则匹配时收到通知(以及使其匹配的事实)。
有关详细信息,请参阅此 post:Drools- how to find out which all rules were matched?
希望对您有所帮助,
我找到了一个解决方案,只是为了检查规则命中时在事实列表中触发了哪些事实。
- 在 model.Product.java 上创建了一个函数
return getType();
然后在主程序上main.Droolstest.java:调用函数获取事实getfacts(workingMemory);
public void getfacts( WorkingMemory workingMemory )
{
FactHandle fh;
Collection<org.kie.api.runtime.rule.FactHandle> x = workingMemory.getFactHandles();
Iterator<org.kie.api.runtime.rule.FactHandle> it = x.iterator();
System.out.println("List of facts");
while(it.hasNext())
{
fh = (FactHandle) it.next();
Object getobj = workingMemory.getObject(fh);
//System.out.println("GetObject to string: " + ((Object)getobj));
if (getobj instanceof RuleFact) {
System.out.println("\nIt's a Fact: ");
((RuleFact) getobj).print();
}
//System.out.println("FactHandle to string "+ ((Object) fh.toExternalForm()).toString());
}
}
output:
Constructor RuleFact to gold
Constructor RuleFact to diamond
Constructor RuleFact to wood
Inserting facts on the facts list
List of facts
It's a Fact:
gold
It's a Fact:
diamond
Fire all the rules
Discount for gold is 95
Discount for diamond is 15
Discount for wood is 0
There are 2 facts
Inserting fact on the facts list
New Rule - fire all the rules
There are 3 facts
Discount for gold is 95
Discount for diamond is 15
Discount for wood is 90
List of facts
It's a Fact:
wood
It's a Fact:
gold
It's a Fact:
diamond
使用 Drools 插件在 Eclipse 中调试 drools 规则有多种选择(因为你告诉过你正在使用这个 IDE)。
考虑使用KieRuntimeLogger
获取调试信息。
获得KieSession
实例后可以注册一个新的KieRuntimeLogger
:
KieSession kSession = kContainer.newKieSession("ksession-rules");
KieRuntimeLogger kieLogger = ks.getLoggers().newFileLogger(kSession, "log");
运行 您的 drools 应用程序并检查您的项目文件夹。在那里您会找到 log.log
(原文如此!)文件,其中包含规则执行期间调用的操作列表。
这里是详细的article。
我对 drools 有点陌生,我想为一个项目了解更多,所以我在 eclipse 上用 drools 做了一个简单的程序。 工作流程非常简单,我有一个珠宝产品模型,对于每件珠宝,我都会根据名称应用一个折扣。
效果很好,但我想查看事实列表以及每个触发规则使用了哪些事实。 我有这个:
Rules.drl
package com.rule
import com.javainuse.model.Product
import com.javainuse.model.Counter
rule "Offer for Diamond"
when
productObject: Product(type=="diamond")
then
productObject.setDiscount(15);
end
rule "Offer for Gold"
when
productObject: Product(type=="gold")
then
productObject.setDiscount(25);
end
model.Product.java
package com.javainuse.model;
public class Product {
private String type;
private int discount;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getDiscount() {
return discount;
}
public void setDiscount(int discount) {
this.discount = discount;
}
}
main.DroolsTest.java
package com.javainuse.main;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collection;
import java.util.Iterator;
import org.drools.compiler.compiler.DroolsParserException;
import org.drools.compiler.compiler.PackageBuilder;
import org.drools.core.FactHandle;
import org.drools.core.RuleBase;
import org.drools.core.RuleBaseFactory;
import org.drools.core.WorkingMemory;
import com.javainuse.model.Product;
public class DroolsTest {
public static void main(String[] args) throws DroolsParserException,
IOException {
DroolsTest droolsTest = new DroolsTest();
droolsTest.executeDrools();
}
public void executeDrools() throws DroolsParserException, IOException {
PackageBuilder packageBuilder = new PackageBuilder();
String ruleFile = "/com/rule/Rules.drl";
InputStream resourceAsStream = getClass().getResourceAsStream(ruleFile);
Reader reader = new InputStreamReader(resourceAsStream);
packageBuilder.addPackageFromDrl(reader);
org.drools.core.rule.Package rulesPackage = packageBuilder.getPackage();
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(rulesPackage);
WorkingMemory workingMemory = ruleBase.newStatefulSession();
Product product = new Product();
Product product2 = new Product();
product.setType("gold");
product2.setType("diamond");
//List of facts!
workingMemory.insert(product);
workingMemory.insert(product2);
workingMemory.fireAllRules();
System.out.println("Discount for " + product.getType() + " is " + product.getDiscount());
System.out.println("Discount for " + product2.getType() + " is " + product2.getDiscount());
//how many facts
System.out.println("There are " + workingMemory.getFactCount() + " facts");
//facts handles
Collection<org.kie.api.runtime.rule.FactHandle> x = workingMemory.getFactHandles();
System.out.println("Facts Handles: " + x +"\n");
FactHandle fh;
Iterator<org.kie.api.runtime.rule.FactHandle> it = x.iterator();
while(it.hasNext())
{
fh = (FactHandle) it.next();
System.out.println("FactHandle to string "+fh.toExternalForm().toString());
}
}
}
输出:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Discount for gold is 25
Discount for diamond is 15
There are 2 facts
Facts Handles: [[fact 0:2:1889057031:1889057031:2:DEFAULT:NON_TRAIT:com.javainuse.model.Product@7098b907], [fact 0:1:93199773:93199773:1:DEFAULT:NON_TRAIT:com.javainuse.model.Product@58e1d9d]]
FactHandle to string 0:2:1889057031:1889057031:2:DEFAULT:NON_TRAIT
FactHandle to string 0:1:93199773:93199773:1:DEFAULT:NON_TRAIT
I want something like this:
Discount for gold is 25
Discount for diamond is 15
There are 2 facts: gold, diamond
gold triggered rule Offer for Gold
diamond triggered Offer for Diamond
可能吗?我检查了 WorkingMemory、Endpoint、FactHandle 的 类,但什么也没有。
您可以使用 AgendaEventListener
在规则匹配时收到通知(以及使其匹配的事实)。
有关详细信息,请参阅此 post:Drools- how to find out which all rules were matched?
希望对您有所帮助,
我找到了一个解决方案,只是为了检查规则命中时在事实列表中触发了哪些事实。
- 在 model.Product.java 上创建了一个函数
return getType();
然后在主程序上main.Droolstest.java:调用函数获取事实
getfacts(workingMemory);
public void getfacts( WorkingMemory workingMemory ) { FactHandle fh; Collection<org.kie.api.runtime.rule.FactHandle> x = workingMemory.getFactHandles(); Iterator<org.kie.api.runtime.rule.FactHandle> it = x.iterator(); System.out.println("List of facts"); while(it.hasNext()) { fh = (FactHandle) it.next(); Object getobj = workingMemory.getObject(fh); //System.out.println("GetObject to string: " + ((Object)getobj)); if (getobj instanceof RuleFact) { System.out.println("\nIt's a Fact: "); ((RuleFact) getobj).print(); } //System.out.println("FactHandle to string "+ ((Object) fh.toExternalForm()).toString()); } }
output:
Constructor RuleFact to gold
Constructor RuleFact to diamond
Constructor RuleFact to wood
Inserting facts on the facts list
List of facts
It's a Fact:
gold
It's a Fact:
diamond
Fire all the rules
Discount for gold is 95
Discount for diamond is 15
Discount for wood is 0
There are 2 facts
Inserting fact on the facts list
New Rule - fire all the rules
There are 3 facts
Discount for gold is 95
Discount for diamond is 15
Discount for wood is 90
List of facts
It's a Fact:
wood
It's a Fact:
gold
It's a Fact:
diamond
使用 Drools 插件在 Eclipse 中调试 drools 规则有多种选择(因为你告诉过你正在使用这个 IDE)。
考虑使用KieRuntimeLogger
获取调试信息。
获得KieSession
实例后可以注册一个新的KieRuntimeLogger
:
KieSession kSession = kContainer.newKieSession("ksession-rules");
KieRuntimeLogger kieLogger = ks.getLoggers().newFileLogger(kSession, "log");
运行 您的 drools 应用程序并检查您的项目文件夹。在那里您会找到 log.log
(原文如此!)文件,其中包含规则执行期间调用的操作列表。
这里是详细的article。