How to load and execute a rule from Guvnor at runtime (no change-set xml file)
drools, java
Solution
The architecture of Drools is oriented towards packages, not individual rules. Although you can filter out rules during loading, I would not recommend you do that. You should instead either separate the rules in different packages or use rule attributes like enabled or agenda filters to logically disable the rules.
Having said that, you can use either the KnowledgeAgent or the KnowledgeBuilder directly to load remote packages. Guvnor uses standard naming conventions for the URL for the packages. The URL will be:
<guvnor-url>/org.drools.guvnor.Guvnor/package/<your_pkg_name>/<version>
So, for instance, if your name package name is "some.pkg", and you have guvnor deployed to a local instance in jboss AS 7, the URL could be:
http://localhost:8080/guvnor-5.4.0.Final-jboss-as-7.0/org.drools.guvnor.Guvnor/package/some.pkg/LATEST
Using the KnowledgeBuilder, you can do:
// load package
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newUrlResource( "http://localhost:8080/guvnor-5.4.0.Final-jboss-as-7.0/org.drools.guvnor.Guvnor/package/some.pkg/LATEST" ),
ResourceType.PKG );
// create the knowledge base
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
// add the package to the kbase
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
The above will load the whole package into your knowledge base. If you really want to load a single rule instead (not recommended), you can remove other rules from the package before adding to the kbase:
for( KnowledgePackage kpkg : kbuilder.getKnowledgePackages() ) {
// need to clone the rule references for iteration
Collection<Rule> rules = new ArrayList<Rule>( kpkg.getRules() );
for( Rule rule : rules ) {
if( ! RULE_YOU_WANT.equals( rule.getName() ) ) {
// NOT recommended as you are using internal APIs
((KnowledgePackageImp)kpkg).removeRule( rule );
}
}
}
Hope it helps.
Problem
I'd like to, provided a package and rule name, retrieve that rule from Guvnor and run it. I'd like to do this all without pre-defining any resources in a change-set.xml file. I'm unable to find any examples of this online or as part of any drools documentation. Currently, I'm stuck on just figuring out how to get the rule into my application. So.. Given the package and rule name of a specific rule in Guvnor, how can I import that rule into my application at runtime (so that it will work for rules created after the application has launched)? thanks!