From e4821f82249bddb443a1f6a6e403087cab659c6d Mon Sep 17 00:00:00 2001
From: Trygve Laugstøl <trygvis@inamo.no>
Date: Fri, 1 Jan 2021 20:35:28 +0100
Subject: Migrating to Drools.

---
 src/main/java/io/trygvis/rules/acme/AcmeIo.java    | 81 ++++++++++++++++++++++
 src/main/java/io/trygvis/rules/acme/AcmeMyApp.java |  6 ++
 .../java/io/trygvis/rules/acme/AcmeObject.java     | 16 +++++
 src/main/java/io/trygvis/rules/acme/AcmeOps.java   |  4 ++
 src/main/java/io/trygvis/rules/dba/Cluster.java    |  9 +++
 src/main/java/io/trygvis/rules/dba/Container.java  | 17 +++++
 src/main/java/io/trygvis/rules/dns/DnsEntry.java   | 19 +++++
 src/main/java/io/trygvis/rules/engine/Main.java    | 36 ++++++++++
 .../java/io/trygvis/rules/machine/Machine.java     |  9 +++
 .../java/io/trygvis/rules/terraform/Machine.java   |  4 ++
 src/main/resources/META-INF/kmodule.xml            | 10 +++
 src/main/resources/io/trygvis/rules/acme/acme.drl  | 30 ++++++++
 src/main/resources/io/trygvis/rules/dba/dba.drl    |  1 +
 .../resources/io/trygvis/rules/machine/machine.drl | 14 ++++
 14 files changed, 256 insertions(+)
 create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeIo.java
 create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeMyApp.java
 create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeObject.java
 create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeOps.java
 create mode 100644 src/main/java/io/trygvis/rules/dba/Cluster.java
 create mode 100644 src/main/java/io/trygvis/rules/dba/Container.java
 create mode 100644 src/main/java/io/trygvis/rules/dns/DnsEntry.java
 create mode 100644 src/main/java/io/trygvis/rules/engine/Main.java
 create mode 100644 src/main/java/io/trygvis/rules/machine/Machine.java
 create mode 100644 src/main/java/io/trygvis/rules/terraform/Machine.java
 create mode 100644 src/main/resources/META-INF/kmodule.xml
 create mode 100644 src/main/resources/io/trygvis/rules/acme/acme.drl
 create mode 100644 src/main/resources/io/trygvis/rules/dba/dba.drl
 create mode 100644 src/main/resources/io/trygvis/rules/machine/machine.drl

(limited to 'src')

diff --git a/src/main/java/io/trygvis/rules/acme/AcmeIo.java b/src/main/java/io/trygvis/rules/acme/AcmeIo.java
new file mode 100644
index 0000000..67dd4cb
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/acme/AcmeIo.java
@@ -0,0 +1,81 @@
+package io.trygvis.rules.acme;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
+import org.drools.core.common.DefaultFactHandle;
+import org.kie.api.runtime.rule.FactHandle;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+public class AcmeIo {
+    private final ObjectMapper mapper;
+
+    public AcmeIo() {
+        var factory = new YAMLFactory();
+        factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID);
+        factory.enable(YAMLGenerator.Feature.USE_NATIVE_OBJECT_ID);
+        mapper = new ObjectMapper(factory);
+        mapper.findAndRegisterModules();
+    }
+
+    public List<Object> load(String file) throws IOException {
+        var parser = mapper.getFactory().createParser(new File(file));
+
+        var objects = mapper.readValues(parser, AcmeObject.class).readAll(new ArrayList<>());
+
+        List<Object> items = new ArrayList<>(objects.size());
+        for (AcmeObject object : objects) {
+            try {
+                var type = Class.forName(object.type);
+                var x = mapper.treeToValue(object.data, type);
+                items.add(x);
+            } catch (ClassNotFoundException e) {
+                throw new IOException(e);
+            }
+        }
+
+        return items;
+    }
+
+    public void dump(String s, Collection<FactHandle> factHandles) throws IOException {
+        var out = new File("out");
+
+        if (!out.isDirectory()) {
+            if (!out.mkdirs()) {
+                throw new IOException("Could not create directory: " + out);
+            }
+        }
+
+        List<Map.Entry<String, Object>> facts = new ArrayList<>(factHandles.size());
+        for (var handle : factHandles) {
+            if (handle instanceof DefaultFactHandle h) {
+                facts.add(new AbstractMap.SimpleImmutableEntry<>(
+                        h.getObjectClassName(),
+                        h.getObject()));
+            }
+        }
+
+        facts.sort(Map.Entry.comparingByKey());
+
+        var factory = mapper.getFactory();
+        try (var writer = new FileWriter(new File(out, s + ".yaml"));
+             var g = factory.createGenerator(writer)) {
+            for (Map.Entry<String, Object> fact : facts) {
+                g.writeObject(new AcmeObject(
+                        fact.getKey(),
+                        mapper.valueToTree(fact.getValue())
+                ));
+            }
+        }
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java b/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java
new file mode 100644
index 0000000..a1340e7
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java
@@ -0,0 +1,6 @@
+package io.trygvis.rules.acme;
+
+public class AcmeMyApp {
+    public String environment;
+    public String dockerTag;
+}
diff --git a/src/main/java/io/trygvis/rules/acme/AcmeObject.java b/src/main/java/io/trygvis/rules/acme/AcmeObject.java
new file mode 100644
index 0000000..a75c4ba
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/acme/AcmeObject.java
@@ -0,0 +1,16 @@
+package io.trygvis.rules.acme;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public final class AcmeObject {
+    public String type;
+    public ObjectNode data;
+
+    public AcmeObject() {
+    }
+
+    public AcmeObject(String type, ObjectNode data) {
+        this.type = type;
+        this.data = data;
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/acme/AcmeOps.java b/src/main/java/io/trygvis/rules/acme/AcmeOps.java
new file mode 100644
index 0000000..147fcfa
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/acme/AcmeOps.java
@@ -0,0 +1,4 @@
+package io.trygvis.rules.acme;
+
+public class AcmeOps {
+}
diff --git a/src/main/java/io/trygvis/rules/dba/Cluster.java b/src/main/java/io/trygvis/rules/dba/Cluster.java
new file mode 100644
index 0000000..949d9ae
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/dba/Cluster.java
@@ -0,0 +1,9 @@
+package io.trygvis.rules.dba;
+
+public class Cluster {
+    public String name;
+
+    public Cluster(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/dba/Container.java b/src/main/java/io/trygvis/rules/dba/Container.java
new file mode 100644
index 0000000..6df939d
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/dba/Container.java
@@ -0,0 +1,17 @@
+package io.trygvis.rules.dba;
+
+public class Container {
+    public Cluster cluster;
+    public String name;
+    public String machineRole;
+    public String image;
+    public String tag;
+
+    public Container(Cluster cluster, String name, String machineRole, String image, String tag) {
+        this.cluster = cluster;
+        this.name = name;
+        this.machineRole = machineRole;
+        this.image = image;
+        this.tag = tag;
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/dns/DnsEntry.java b/src/main/java/io/trygvis/rules/dns/DnsEntry.java
new file mode 100644
index 0000000..e7d9f4c
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/dns/DnsEntry.java
@@ -0,0 +1,19 @@
+package io.trygvis.rules.dns;
+
+public class DnsEntry {
+    public String fqdn;
+    public String type;
+
+    public DnsEntry(String fqdn, String type) {
+        this.fqdn = fqdn;
+        this.type = type;
+    }
+
+    public static DnsEntry a(String fqdn) {
+        return new DnsEntry(fqdn, "A");
+    }
+
+    public static DnsEntry aaaa(String fqdn) {
+        return new DnsEntry(fqdn, "AAAA");
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/engine/Main.java b/src/main/java/io/trygvis/rules/engine/Main.java
new file mode 100644
index 0000000..3730c28
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/engine/Main.java
@@ -0,0 +1,36 @@
+package io.trygvis.rules.engine;
+
+import io.trygvis.rules.acme.AcmeIo;
+import org.drools.core.audit.WorkingMemoryConsoleLogger;
+import org.drools.core.common.DefaultFactHandle;
+import org.kie.api.KieServices;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+
+import java.io.IOException;
+
+public class Main {
+    public static void main(String[] args) throws IOException {
+        var io = new AcmeIo();
+
+        var objects = io.load("acme.yaml");
+
+        var services = KieServices.Factory.get();
+        var container = services.getKieClasspathContainer();
+        var session = container.newKieSession();
+
+        for (var object : objects) {
+            System.out.println("object = " + object);
+            session.insert(object);
+        }
+
+        var logger = new WorkingMemoryConsoleLogger(session);
+        session.addEventListener((AgendaEventListener) logger);
+        session.addEventListener((RuleRuntimeEventListener) logger);
+        session.fireAllRules();
+
+        io.dump("phase-1", session.getFactHandles());
+
+        session.dispose();
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/machine/Machine.java b/src/main/java/io/trygvis/rules/machine/Machine.java
new file mode 100644
index 0000000..b58aeb2
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/machine/Machine.java
@@ -0,0 +1,9 @@
+package io.trygvis.rules.machine;
+
+public class Machine {
+    public String name;
+
+    public Machine(String name) {
+        this.name = name;
+    }
+}
diff --git a/src/main/java/io/trygvis/rules/terraform/Machine.java b/src/main/java/io/trygvis/rules/terraform/Machine.java
new file mode 100644
index 0000000..01bea77
--- /dev/null
+++ b/src/main/java/io/trygvis/rules/terraform/Machine.java
@@ -0,0 +1,4 @@
+package io.trygvis.rules.terraform;
+
+public class Machine {
+}
diff --git a/src/main/resources/META-INF/kmodule.xml b/src/main/resources/META-INF/kmodule.xml
new file mode 100644
index 0000000..911fdc6
--- /dev/null
+++ b/src/main/resources/META-INF/kmodule.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://www.drools.org/xsd/kmodule"
+         xsi:schemaLocation="http://www.drools.org/xsd/kmodule https://www.drools.org/xsd/kmodule_7_1.xsd">
+
+  <kbase packages="io.trygvis.rules,io.trygvis.rules.acme,io.trygvis.rules.dba,io.trygvis.rules.machine"
+         default="true">
+    <ksession name="Default" default="true"/>
+  </kbase>
+</kmodule>
diff --git a/src/main/resources/io/trygvis/rules/acme/acme.drl b/src/main/resources/io/trygvis/rules/acme/acme.drl
new file mode 100644
index 0000000..2439ddb
--- /dev/null
+++ b/src/main/resources/io/trygvis/rules/acme/acme.drl
@@ -0,0 +1,30 @@
+package io.trygvis.rules.acme;
+
+import io.trygvis.rules.dba.Cluster;
+import io.trygvis.rules.dba.Container;
+
+rule "Ops"
+when
+    $ops: AcmeOps()
+then
+    var cluster = new Cluster("acme-ops");
+    insert(cluster);
+    insert(new Container(cluster, "app", "pdb", "postgresql", "11"));
+    insert(new Container(cluster, "app", "n8n", "n8n", "0.84.1"));
+end
+
+rule "MyApp"
+when
+    $app: AcmeMyApp()
+then
+    var cluster = new Cluster("acme-" + $app.environment);
+    insert(cluster);
+
+    var tag = $app.dockerTag;
+    insert(new Container(cluster, "app", "statera", "statera", tag));
+    insert(new Container(cluster, "app", "statera-console", "statera-console", tag));
+    insert(new Container(cluster, "app", "4tune-web", "4tune-web", tag));
+    insert(new Container(cluster, "app", "4tune-api", "4tune-api", tag));
+    insert(new Container(cluster, "db", "pdb", "postgresql", "13"));
+    insert(new Container(cluster, "db", "mdb", "mongodb", "3.2"));
+end
diff --git a/src/main/resources/io/trygvis/rules/dba/dba.drl b/src/main/resources/io/trygvis/rules/dba/dba.drl
new file mode 100644
index 0000000..7beceef
--- /dev/null
+++ b/src/main/resources/io/trygvis/rules/dba/dba.drl
@@ -0,0 +1 @@
+package io.trygvis.rules.dba;
diff --git a/src/main/resources/io/trygvis/rules/machine/machine.drl b/src/main/resources/io/trygvis/rules/machine/machine.drl
new file mode 100644
index 0000000..45df925
--- /dev/null
+++ b/src/main/resources/io/trygvis/rules/machine/machine.drl
@@ -0,0 +1,14 @@
+package io.trygvis.rules.machine;
+
+import io.trygvis.rules.dba.Cluster;
+import io.trygvis.rules.dba.Container;
+import io.trygvis.rules.machine.Machine;
+import io.trygvis.rules.dns.DnsEntry;
+
+rule "New machine"
+when
+    $container: Container()
+then
+    insert(DnsEntry.a($container.name + ".machine.acme.org"));
+    insert(DnsEntry.aaaa($container.name + ".machine.acme.org"));
+end
-- 
cgit v1.2.3