Drools Complicated Facts

I watched how to simplify some of my rules, which are written manually in the DRL, it becomes difficult to maintain.

Search through google has led to the fact that "decision tables are the best way to go to forawad".

But, unfortunately, our facts are very complex, so at the moment the slobbering table converter cannot cope with such complexity on the facts,

So, the first question is, how do developers usually deal with handling very complex facts in the drools knowledge base?

For example, we have facts such as

Person->List<Cars>->List<Insurances>->Each insurance Has List<History> 

Now I need to write a rule: "A person has a bad story for his insurance claim." Then I find it very difficult to put it in a speadsheet, where it is easier to manually write this rule in the drl file.

Thanks for the help. Any help on the above example is also very good.

+4
source share
2 answers

For complex rules like this, we use Drools patterns. You write a rule template with an extension of parameters to fill in the fields, and you have much more flexibility when the actual values ​​come from filling in the skeleton rule.

This feature is built into Drools Guvnor, but writing complex rule patterns through the GUI is somewhat tedious. I also wrote standalone Java to populate drl file templates from lists of values ​​extracted from property files, and recently developed the SmartGWT web application that allows the user to populate rule values ​​and generate DRLs.

Edit: Add a sample program. DroolsTemplateBuilder creates a list of TestType objects that have fields that map to the template keys in Test.drl. The generated DRL is printed and also compiled into pkg, which is written to the Test.pkg file.

Libraries: antlr-3.3.jar, antlr-runtime-3.3.jar, drools-compiler-5.2.0.Final.jar, drools-core-5.2.0.Final.jar, drools-templates-5.2.0.Final. jar, ecj-4.2.jar, knowledge-api-5.2.0.Final.jar, mvel2-2.1.0.drools.jar (this may not be all necessary).

Note. The libraries used in this example are 5.2.0, and some features may differ in newer versions. build.xml should clearly indicate how to structure your project.

DroolsTemplateBuilder.java:

 package some.test.pkg; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import org.drools.builder.KnowledgeBuilder; import org.drools.builder.KnowledgeBuilderError; import org.drools.builder.KnowledgeBuilderFactory; import org.drools.builder.ResourceType; import org.drools.common.DroolsObjectOutputStream; import org.drools.definitions.impl.KnowledgePackageImp; import org.drools.io.ResourceFactory; import org.drools.template.ObjectDataCompiler; public class DroolsTemplateBuilder { private String filePath; private String drl; public static void main(String[] args) { DroolsTemplateBuilder test = new DroolsTemplateBuilder(); test.filePath = args[0] + File.separator + "Test.drl"; test.runTest(); } public void runTest() { buildPackage(); writeRulePackageToFile(); } public void buildPackage() { Collection<Object> templateList = new ArrayList<Object>(); templateList.add(new TestType(1, "John", "Manager")); templateList.add(new TestType(2, "Peter", "CEO")); templateList.add(new TestType(3, "Kate", "Engineer")); try { ObjectDataCompiler converter = new ObjectDataCompiler(); InputStream templateStream = new FileInputStream(filePath); String myDrl = inputStreamToString(templateStream, 200); // I use this ##### replacement instead of just a newline in the // template // because of windows/linux issues with newline and carriage return. // Drools template // builder, at least in 5.2.0, was very picky about the template // structure, including // where newlines are expected. myDrl = myDrl.replaceAll("#####", "\n"); InputStream tempStream = new ByteArrayInputStream(myDrl.getBytes()); drl = converter.compile(templateList, tempStream); System.out.println(drl); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } } public void writeRulePackageToFile() { try { KnowledgeBuilder kBuilder = KnowledgeBuilderFactory .newKnowledgeBuilder(); Reader rdr = new StringReader(drl); kBuilder.add(ResourceFactory.newReaderResource(rdr), ResourceType.DRL); if (kBuilder.hasErrors()) { System.out.println("Drools blew up on"); for (KnowledgeBuilderError err : kBuilder.getErrors()) { System.out.println(err.getMessage()); } } else { String outFile = filePath.replaceFirst("\\.drl", ".pkg"); OutputStream os = new FileOutputStream(outFile); ObjectOutputStream oos = new DroolsObjectOutputStream(os); KnowledgePackageImp kPackage = (KnowledgePackageImp) kBuilder .getKnowledgePackages().iterator().next(); oos.writeObject(kPackage); oos.close(); } } catch (Exception e) { System.out.println("Exception " + e.getMessage()); } } public String inputStreamToString(final InputStream is, final int bufferSize) { final char[] buffer = new char[bufferSize]; final StringBuilder out = new StringBuilder(); try { final Reader in = new InputStreamReader(is, "UTF-8"); try { for (;;) { int rsz = in.read(buffer, 0, buffer.length); if (rsz < 0) break; out.append(buffer, 0, rsz); } } finally { in.close(); } } catch (Exception ex) { System.out.println("Something went wrong: " + ex.getMessage()); } return out.toString(); } } 

Test.drl:

 template header id name title ##### package some.test.pkg; template "sampleTemplate" rule "id filter_@ {row.rowNumber}" no-loop true dialect "java" when $t : TestType(id=="@{id}") then System.out.println("Doing something special..."); end end template template "anotherSample" rule "another rule_@ {row.rowNumber}" no-loop true dialect "java" when $t : TestType((name=="@{name}") || (title=="@{title}")) then System.out.println("Doing something else..."); end end template 

TestType.java:

 package some.test.pkg; public class TestType { private int id; private String name; private String title; public TestType(int id, String name, String title) { this.id = id; this.name = name; this.title = title; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } 

build.xml

 <project name="TemplateTest" basedir="." default="jar"> <property name="src.dir" value="src" /> <property name="build.dir" value="build" /> <property name="drl.dir" value="${basedir}/drl" /> <property name="classes.dir" value="${build.dir}/classes" /> <property name="jar.dir" value="${build.dir}/jar" /> <property name="lib.dir" value="${basedir}/lib" /> <path id="compile.classpath"> <fileset dir="${lib.dir}" includes="*.jar" /> </path> <path id="run.classpath"> <fileset dir="${jar.dir}" includes="*.jar" /> <fileset dir="${lib.dir}" includes="*.jar" /> </path> <target name="clean"> <delete dir="${classes.dir}" /> <delete dir="${jar.dir}" /> </target> <target name="compile" depends="clean"> <mkdir dir="${classes.dir}" /> <mkdir dir="${jar.dir}" /> <javac includeantruntime="false" srcdir="${src.dir}" classpathref="compile.classpath" destdir="${classes.dir}" /> </target> <target name="jar" depends="compile"> <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"> </jar> </target> <target name="run" depends="jar" description="run"> <java classpathref="run.classpath" classname="some.test.pkg.DroolsTemplateBuilder" fork="true"> <arg value="${drl.dir}" /> </java> </target> </project> 
+3
source

We also use Templates, and our facts (and the resulting rules) are quite complex. The values ​​in the template table are used in the rules for method calls, setting the rule "parameters", timer values, etc.

Templates help when rule settings are tabular. If access control is a concern, you may need several templates with the same logic, only different values. (Easy to do in guvnor by simply copying the 1st template).

0
source

Source: https://habr.com/ru/post/1485574/


All Articles