<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
I've upgraded OptaPlanner to use the KIE api and I have some
feedback :)<br>
<br>
What I want to do:<br>
<b>Given of list of DRL's on the classpath, build a KieSession.</b><br>
<br>
Here's how I did it with the new KIE api:<br>
<br>
public KieBase newKieBase(List<String> scoreDrlList) {<br>
<font color="#cc6600">KieServices</font> kieServices =
KieServices.Factory.get();<br>
<font color="#cc6600">KieResources</font> kieResources
= kieServices.getResources();<br>
<font color="#cc6600">KieFileSystem</font>
kieFileSystem = kieServices.newKieFileSystem();<br>
for (String scoreDrl : scoreDrlList) {<br>
InputStream scoreDrlIn =
getClass().getResourceAsStream(scoreDrl);<br>
// TODO newClassPathResource() instead, but that
breaks (mfusco is looking at it)<br>
String path =
"src/main/resources/optaplanner-kie-namespace/" + scoreDrl;<br>
kieFileSystem.write(path,
kieResources.newInputStreamResource(scoreDrlIn, "UTF-8"));<br>
}<br>
<font color="#cc6600">KieBuilder</font> kieBuilder =
kieServices.newKieBuilder(kieFileSystem);<br>
kieBuilder.buildAll();<br>
<font color="#cc6600">Results</font> results =
kieBuilder.getResults();<br>
if (results.hasMessages(Message.Level.ERROR)) {<br>
throw new IllegalStateException("There are errors in
the scoreDrl's:\n"<br>
+ results.toString());<br>
} else if (results.hasMessages(Message.Level.WARNING)) {<br>
logger.warn("There are warning in the scoreDrl's:\n"<br>
+ results.toString());<br>
}<br>
<font color="#cc6600">KieContainer</font> kieContainer
= kieServices.newKieContainer(kieBuilder.get<font color="#cc6600">KieModule</font>().getReleaseId());<br>
<font color="#cc6600">KieBase</font> kieBase =
kieContainer.getKieBase();<br>
return kieBase;<br>
}<br>
<br>
public KieSession newKieSession() {<br>
...<br>
KieSession kieSession = kieBase.newKieSession();<br>
return kieSession;<br>
}<br>
<br>
<b>Feedback</b> (note: these are suggestions, not demands):<br>
<br>
1) To do this, I needed to get acquainted with <font
color="#cc6600">9 new concepts</font>:<br>
KieServices, KieResources, KieFileSystem, KieBuilder, Results,
KieModule, KieContainer, KieBase, KieSession.<br>
I only care about 2 of those:<br>
- KieSession<br>
- KieBase (= the factory to build a new KieSession, which I do
regularly).<br>
The other 7 concepts probably represent wonderful advanced features
which I might want to use later on,<br>
so they should exist,<br>
But in a simple use case like this, I should not have to see them or
deal with them.<br>
<br>
2) The kie filesystem features leaks into the simple api, even if I
don't care about the KieFileSystem at all.<br>
- I should not explicitly need to create a KieFileSystem:<br>
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();<br>
- Adding certain Resource types fails if you don't specify the
fileSystem's path. This fails for example:<br>
kieFileSystem.write(kieResources.newInputStreamResource(...));<br>
- For the default KieBase to work, the path needs to start with a <font
color="#993399">magical</font> prefix<br>
String path = "<font color="#993399">src/main/resources</font>/.../"
+ ...;<br>
<br>
3) To create a KieBase from that kieFileSystem, I need to explicitly
do 5+ calls, in the right order:<br>
- call kieServices.newKieBuilder(...)<br>
- call kieBuilder.buildAll()<br>
- call kieBuilder.getKieModule()<br>
- call kieServices.newKieContainer(...)<br>
- call kieContainer.getKieBase()<br>
Some of these have non-obvious parameters.<br>
I'd rather just call:<br>
kieFileSystem.buildKieBase()<br>
<br>
4) I don't like having to write the boilerplate code to check if the
are errors:<br>
if (results.hasMessages(Message.Level.ERROR)) {...}<br>
If there are errors, then kieFileSystem.buildKieBase() should just
throw a DroolsRuntimeException.<br>
<br>
<b>Solution</b> proposal:<br>
<br>
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.<br>
<br>
public KieBase newKieBase(List<String> scoreDrlList) {<br>
KieBaseFactory kieBaseFactory =
kieServices.newKieBaseFactory();<br>
for (String scoreDrl : scoreDrlList) {<br>
kieBaseFactory.addInputStreamResource(scoreDrl, "UTF-8");<br>
}<br>
return kieBaseFactory.buildKieBase; // throws exception upon
compilation error<br>
}<br>
<br>
Mario's KieHelper is similar, but slightly different.<br>
<br>
wkr,<br>
Geoffrey<br>
<br>
</body>
</html>