For those a bit confused by this. As we've not talked about the new kie stuff in
detail. We now have two approaches. One is convention and configuration based - which is
now the preferred way of doing things. The other is the pragmatic layer, as below. The
additional concepts such as KieModule is due to our improved deployment mechanism - which
is now maven module based. We'll try and do a detailed write up of this for end users
soon.
In the mean time I've done a series of examples, which demonstrates both the
convention and the api approach - both on their own and used in conjunction:
https://github.com/droolsjbpm/drools/tree/master/drools-examples-api
The simplest example needs an empty kmodule.xml file:
https://github.com/droolsjbpm/drools/blob/master/drools-examples-api/defa...
then session can be created from just two lines:
https://github.com/droolsjbpm/drools/blob/master/drools-examples-api/defa...
The kmodule.xml is necessary for discovery, from that we can find all the drl, bpmn2 files
for the kiebase - without the user having to specify each file individually.
However we now support kiemodules. These are named kiebases that are available for lookup,
and deployed via maven. Further one kiemodule can now "include" resources from
other kiemodules - s owe have better composition.
This works really well for CDI, where can now remove all boiler plate code and simply use
annotations to inject sessions:
https://github.com/droolsjbpm/drools/blob/master/drools-examples-cdi/cdi-...
Mark
On 25 Mar 2013, at 15:56, Geoffrey De Smet <ge0ffrey.spam(a)gmail.com> wrote:
I've upgraded OptaPlanner to use the KIE api and I have some
feedback :)
What I want to do:
Given of list of DRL's on the classpath, build a KieSession.
Here's how I did it with the new KIE api:
public KieBase newKieBase(List<String> scoreDrlList) {
KieServices kieServices = KieServices.Factory.get();
KieResources kieResources = kieServices.getResources();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
for (String scoreDrl : scoreDrlList) {
InputStream scoreDrlIn = getClass().getResourceAsStream(scoreDrl);
// TODO newClassPathResource() instead, but that breaks (mfusco is
looking at it)
String path = "src/main/resources/optaplanner-kie-namespace/" +
scoreDrl;
kieFileSystem.write(path, kieResources.newInputStreamResource(scoreDrlIn,
"UTF-8"));
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
Results results = kieBuilder.getResults();
if (results.hasMessages(Message.Level.ERROR)) {
throw new IllegalStateException("There are errors in the
scoreDrl's:\n"
+ results.toString());
} else if (results.hasMessages(Message.Level.WARNING)) {
logger.warn("There are warning in the scoreDrl's:\n"
+ results.toString());
}
KieContainer kieContainer =
kieServices.newKieContainer(kieBuilder.getKieModule().getReleaseId());
KieBase kieBase = kieContainer.getKieBase();
return kieBase;
}
public KieSession newKieSession() {
...
KieSession kieSession = kieBase.newKieSession();
return kieSession;
}
Feedback (note: these are suggestions, not demands):
1) To do this, I needed to get acquainted with 9 new concepts:
KieServices, KieResources, KieFileSystem, KieBuilder, Results, KieModule,
KieContainer, KieBase, KieSession.
I only care about 2 of those:
- KieSession
- KieBase (= the factory to build a new KieSession, which I do regularly).
The other 7 concepts probably represent wonderful advanced features which I might want to
use later on,
so they should exist,
But in a simple use case like this, I should not have to see them or deal with them.
2) The kie filesystem features leaks into the simple api, even if I don't care about
the KieFileSystem at all.
- I should not explicitly need to create a KieFileSystem:
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
- Adding certain Resource types fails if you don't specify the fileSystem's path.
This fails for example:
kieFileSystem.write(kieResources.newInputStreamResource(...));
- For the default KieBase to work, the path needs to start with a magical prefix
String path = "src/main/resources/.../" + ...;
3) To create a KieBase from that kieFileSystem, I need to explicitly do 5+ calls, in the
right order:
- call kieServices.newKieBuilder(...)
- call kieBuilder.buildAll()
- call kieBuilder.getKieModule()
- call kieServices.newKieContainer(...)
- call kieContainer.getKieBase()
Some of these have non-obvious parameters.
I'd rather just call:
kieFileSystem.buildKieBase()
4) I don't like having to write the boilerplate code to check if the are errors:
if (results.hasMessages(Message.Level.ERROR)) {...}
If there are errors, then kieFileSystem.buildKieBase() should just throw a
DroolsRuntimeException.
Solution proposal:
A) Write a facade class that presumes there is only 1 module and the user doesn't
need (or want to) to access any of those 7 other concepts.
public KieBase newKieBase(List<String> scoreDrlList) {
KieBaseFactory kieBaseFactory = kieServices.newKieBaseFactory();
for (String scoreDrl : scoreDrlList) {
kieBaseFactory.addInputStreamResource(scoreDrl, "UTF-8");
}
return kieBaseFactory.buildKieBase; // throws exception upon compilation error
}
Mario's KieHelper is similar, but slightly different.
wkr,
Geoffrey
_______________________________________________
rules-dev mailing list
rules-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-dev