Skip to content

Instantly share code, notes, and snippets.

@kroepke
Last active August 29, 2015 14:02
Show Gist options
  • Save kroepke/528a7df1efd471491a1b to your computer and use it in GitHub Desktop.
Save kroepke/528a7df1efd471491a1b to your computer and use it in GitHub Desktop.
@Singleton
public class DroolsEngine implements RulesEngine {
private static final Logger log = LoggerFactory.getLogger(DroolsEngine.class);
private final KieServices kieServices;
private ReleaseId currentReleaseId;
private final KieContainer kieContainer;
private final KieSession session;
@Inject
public DroolsEngine() {
kieServices = KieServices.Factory.get();
currentReleaseId = kieServices.newReleaseId("org.graylog2", "dynamic-rules", "1.0");
createAndDeployJar(kieServices, currentReleaseId, "");
kieContainer = kieServices.newKieContainer(currentReleaseId);
session = kieContainer.newKieSession();
}
@Override
public boolean addRule(String ruleSource) {
ReleaseId newReleaseId = nextRelease(currentReleaseId);
try {
createAndDeployJar(kieServices, newReleaseId, ruleSource);
currentReleaseId = newReleaseId;
} catch (IllegalArgumentException e) {
log.error("Could not add rule to engine, syntax errors found.");
return false;
}
kieContainer.updateToVersion(newReleaseId);
return true;
}
@Override
public int evaluate(Message message) {
session.insert(message);
return session.fireAllRules();
}
private ReleaseId nextRelease(ReleaseId releaseId) {
final List<String> versionParts = Splitter.on('.').limit(2).splitToList(releaseId.getVersion());
int newMinor = Integer.parseInt(versionParts.get(1)) + 1;
return kieServices.newReleaseId(releaseId.getGroupId(),
releaseId.getArtifactId(),
versionParts.get(0) + "." + newMinor);
}
private static KieModule createAndDeployJar(KieServices ks, ReleaseId releaseId, String... drls) {
byte[] jar = createJar(ks, releaseId, drls);
// Deploy jar into the repository
final KieModule kieModule = deployJarIntoRepository(ks, jar);
return kieModule;
}
private static byte[] createJar(KieServices ks,
ReleaseId releaseId,
String... drls) {
KieFileSystem kfs = ks.newKieFileSystem()
.generateAndWritePomXML(releaseId);
for (int i = 0; i < drls.length; i++) {
if (drls[i] != null) {
kfs.write("src/main/resources/r" + i + ".drl", drls[i]);
}
}
KieBuilder kb = ks.newKieBuilder(kfs).buildAll();
final Results results = kb.getResults();
if (results.hasMessages(Level.ERROR)) {
log.warn("Compiling new rules failed: ", results.getMessages(Level.ERROR));
throw new IllegalArgumentException("Rules syntax error");
}
InternalKieModule kieModule = (InternalKieModule) ks.getRepository().getKieModule(releaseId);
final byte[] bytes = kieModule.getBytes();
return bytes;
}
private static KieModule deployJarIntoRepository(KieServices ks, byte[] jar) {
Resource jarRes = ks.getResources().newByteArrayResource(jar);
return ks.getRepository().addKieModule(jarRes);
}
@Test
public void addedRuleIsVisibleInSession() {
final DroolsEngine engine = new DroolsEngine();
String rule = "import org.graylog2.plugin.Message;\n" +
"declare Message\n" +
" @role( event )\n" +
"end\n" +
"\n" +
"rule \"test matcher\"\n" +
"when\n" +
" $m : Message( filterOut == false )\n" + // , source == "test"
"then\n" +
" modify($m) { setFilterOut(true) }\n" +
"end\n";
final boolean valid = engine.addRule(rule);
assertTrue(valid, "Rule should compile without errors");
final int rulesFired = engine.evaluate(new Message("test message", "test", DateTime.now()));
assertEquals(rulesFired, 1, "rule should have matched");
}
java.lang.NullPointerException
at java.io.FilterOutputStream.write(FilterOutputStream.java:97)
at org.drools.compiler.compiler.io.memory.MemoryFileSystem.writeJarEntries(MemoryFileSystem.java:437)
at org.drools.compiler.compiler.io.memory.MemoryFileSystem.writeJarEntries(MemoryFileSystem.java:430)
at org.drools.compiler.compiler.io.memory.MemoryFileSystem.writeJarEntries(MemoryFileSystem.java:430)
at org.drools.compiler.compiler.io.memory.MemoryFileSystem.writeJarEntries(MemoryFileSystem.java:430)
at org.drools.compiler.compiler.io.memory.MemoryFileSystem.zip(MemoryFileSystem.java:387)
at org.drools.compiler.compiler.io.memory.MemoryFileSystem.writeAsBytes(MemoryFileSystem.java:365)
at org.drools.compiler.kie.builder.impl.MemoryKieModule.getBytes(MemoryKieModule.java:64)
at org.graylog2.rules.DroolsEngine.createJar(DroolsEngine.java:122)
at org.graylog2.rules.DroolsEngine.createAndDeployJar(DroolsEngine.java:96)
at org.graylog2.rules.DroolsEngine.addRule(DroolsEngine.java:66)
at org.graylog2.rules.DroolsEngineTest.addedRuleIsVisibleInSession(DroolsEngineTest.java:37)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment