From ad37c37e2211c3640402e38382de87925319b4cc Mon Sep 17 00:00:00 2001 From: Will Gilbert Date: Tue, 16 May 2017 09:47:48 -0400 Subject: [PATCH] Add beginnings of 'Fire' demo based on DROOLS example --- easyrules-gradle/build.gradle | 9 +++ .../org/easyrules/samples/fire/Alarm.groovy | 9 +++ .../samples/fire/CancelAlarmRule.groovy | 27 +++++++ .../samples/fire/EverythingOKRule.groovy | 27 +++++++ .../org/easyrules/samples/fire/Fire.groovy | 8 ++ .../easyrules/samples/fire/Launcher.groovy | 75 +++++++++++++++++++ .../samples/fire/RaiseAlarmRule.groovy | 27 +++++++ .../org/easyrules/samples/fire/Room.groovy | 8 ++ .../easyrules/samples/fire/Sprinkler.groovy | 11 +++ .../easyrules/samples/fire/TheWorld.groovy | 15 ++++ .../samples/fire/ThereIsAnAlarmRule.groovy | 26 +++++++ .../samples/fire/TurnSprinklerOnRule.groovy | 28 +++++++ 12 files changed, 270 insertions(+) create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Alarm.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/CancelAlarmRule.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/EverythingOKRule.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Fire.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Launcher.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/RaiseAlarmRule.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Room.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Sprinkler.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TheWorld.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/ThereIsAnAlarmRule.groovy create mode 100644 easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TurnSprinklerOnRule.groovy diff --git a/easyrules-gradle/build.gradle b/easyrules-gradle/build.gradle index 3fd2838..6b695c4 100644 --- a/easyrules-gradle/build.gradle +++ b/easyrules-gradle/build.gradle @@ -22,6 +22,11 @@ NB: Use '--quiet' or '-q' to supress Gradle build output lines ./gradlew HelloWorld -q Obligatory 'Hello, world' example where the input is evaluated by a rule. + ./gradlew Fire -q + Copied from DROOLS examples. Create some rooms with sprinklers, start a fire. + The sprinklers will turn on an alarm will be raised. Put out the fire, the + sprinklers will turn off and the alarm will be silenced. + ./gradlew Shop -P person=Tommy -P age=15 Rule to evaluate drinking age (US 21); Name and age can be passed in via the command line or system properties; Default is 'Tom' at age '17'. @@ -113,6 +118,10 @@ task HelloWorld (dependsOn: 'classes', type: JavaExec) { main = 'org.easyrules.samples.helloworld.Launcher' } +task Fire (dependsOn: 'classes', type: JavaExec) { + main = 'org.easyrules.samples.fire.Launcher' +} + task Scheduling (dependsOn: 'classes', type: JavaExec) { main = 'org.easyrules.samples.scheduling.Launcher' } diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Alarm.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Alarm.groovy new file mode 100644 index 0000000..5c908e6 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Alarm.groovy @@ -0,0 +1,9 @@ +package org.easyrules.samples.fire + + +@groovy.transform.TupleConstructor +@groovy.transform.EqualsAndHashCode +@groovy.transform.ToString +class Alarm { + String name +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/CancelAlarmRule.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/CancelAlarmRule.groovy new file mode 100644 index 0000000..9ef5f8d --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/CancelAlarmRule.groovy @@ -0,0 +1,27 @@ +package org.easyrules.samples.fire + +import org.easyrules.annotation.Action +import org.easyrules.annotation.Condition +import org.easyrules.annotation.Rule +import org.easyrules.annotation.Priority + +@Rule +class CancelAlarmRule { + + def theWorld + + @Condition + boolean when() { + theWorld.alarm != null && theWorld.fires.size() == 0 + } + + @Action + def then() { + theWorld.alarm = null + println( "Cancel the Alarm"); + } + + @Priority + int getPriority() { 0 } + +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/EverythingOKRule.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/EverythingOKRule.groovy new file mode 100644 index 0000000..d2427ca --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/EverythingOKRule.groovy @@ -0,0 +1,27 @@ +package org.easyrules.samples.fire + +import org.easyrules.annotation.Action +import org.easyrules.annotation.Condition +import org.easyrules.annotation.Rule +import org.easyrules.annotation.Priority + +@Rule +class EverythingOKRule { + + def theWorld + + @Condition + boolean when() { + def anyOn = theWorld.sprinklers.any{it.isOn()} + (anyOn == false) && (theWorld.alarm == null) + } + + @Action + def then() { + println 'To Fire Station: Everything is OK' + } + + @Priority + int getPriority() { 10 } + +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Fire.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Fire.groovy new file mode 100644 index 0000000..c64d678 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Fire.groovy @@ -0,0 +1,8 @@ +package org.easyrules.samples.fire + +@groovy.transform.TupleConstructor +@groovy.transform.EqualsAndHashCode +@groovy.transform.ToString +class Fire { + Room room; +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Launcher.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Launcher.groovy new file mode 100644 index 0000000..f426d12 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Launcher.groovy @@ -0,0 +1,75 @@ +package org.easyrules.samples.fire + +import static org.easyrules.core.RulesEngineBuilder.aNewRulesEngine + +import org.easyrules.api.RulesEngine + +class Launcher { + + static void main(String... args) { + + def label = 'FIRE ALARM'.replaceAll(/./){it+' '} + def width = 80 + + println """${'='*width} + |${label.center width } + |${'='*width}""".stripMargin() + + + // Define some room names + def names = ['Kitchen', 'Bedroom', 'Office', 'Livingroom'] + + // Create rooms for each name; Install a sprinkler in each room; Add to rules engine + def rooms = new HashMap() + def sprinklers = [] + + names.each { name -> + def room = new Room(name) + rooms[name] = room + sprinklers << new Sprinkler(room) + } + + def theWorld = new TheWorld(sprinklers) + + // Create a rules engine + RulesEngine rulesEngine = aNewRulesEngine() + .named("Fire Alarm Demo") + .build() + + // Register rules + rulesEngine.registerRule(new EverythingOKRule(theWorld:theWorld)) + rulesEngine.registerRule(new RaiseAlarmRule(theWorld:theWorld)) + rulesEngine.registerRule(new ThereIsAnAlarmRule(theWorld:theWorld)) + rulesEngine.registerRule(new CancelAlarmRule(theWorld:theWorld)) + rulesEngine.registerRule(new TurnSprinklerOnRule(theWorld:theWorld)) + + // Fire the rules + rulesEngine.fireRules() + + pause('Start some fires') + + def kitchenFire = new Fire( rooms['Kitchen'] ) + def officeFire = new Fire( rooms['Office'] ) + + theWorld.fires << kitchenFire + theWorld.fires << officeFire + + // Fire the rules + rulesEngine.fireRules() + + pause('Put out the fires') + theWorld.fires.remove kitchenFire + theWorld.fires.remove officeFire + + // Fire the rules + rulesEngine.fireRules() + + } + + public static void pause(message) { + println "\n>>>>>> Press enter to '$message' <<<<<<" + def keyboard = new Scanner(System.in) + keyboard.nextLine() + } + +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/RaiseAlarmRule.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/RaiseAlarmRule.groovy new file mode 100644 index 0000000..dfcd475 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/RaiseAlarmRule.groovy @@ -0,0 +1,27 @@ +package org.easyrules.samples.fire + +import org.easyrules.annotation.Action +import org.easyrules.annotation.Condition +import org.easyrules.annotation.Rule +import org.easyrules.annotation.Priority + +@Rule +class RaiseAlarmRule { + + def theWorld + + @Condition + boolean when() { + theWorld.fires.size() > 0 + } + + @Action + def then() { + theWorld.alarm = new Alarm() + println( "Raise the Alarm"); + } + + @Priority + int getPriority() { 0 } + +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Room.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Room.groovy new file mode 100644 index 0000000..995e645 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Room.groovy @@ -0,0 +1,8 @@ +package org.easyrules.samples.fire + +@groovy.transform.TupleConstructor +@groovy.transform.EqualsAndHashCode +@groovy.transform.ToString +class Room { + String name; +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Sprinkler.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Sprinkler.groovy new file mode 100644 index 0000000..435a8a7 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/Sprinkler.groovy @@ -0,0 +1,11 @@ +package org.easyrules.samples.fire + +@groovy.transform.TupleConstructor +@groovy.transform.EqualsAndHashCode +@groovy.transform.ToString +class Sprinkler { + Room room; + boolean on; + + boolean isOn() {on} +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TheWorld.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TheWorld.groovy new file mode 100644 index 0000000..e6cb030 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TheWorld.groovy @@ -0,0 +1,15 @@ +package org.easyrules.samples.fire + +@groovy.transform.TupleConstructor +@groovy.transform.EqualsAndHashCode +@groovy.transform.ToString +class TheWorld { + + Sprinkler[] sprinklers + Alarm alarm = null + def fires = [] + + TheWorld(sprinklers) { + this.sprinklers = sprinklers + } +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/ThereIsAnAlarmRule.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/ThereIsAnAlarmRule.groovy new file mode 100644 index 0000000..23b15ba --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/ThereIsAnAlarmRule.groovy @@ -0,0 +1,26 @@ +package org.easyrules.samples.fire + +import org.easyrules.annotation.Action +import org.easyrules.annotation.Condition +import org.easyrules.annotation.Rule +import org.easyrules.annotation.Priority + +@Rule +class ThereIsAnAlarmRule { + + def theWorld + + @Condition + boolean when() { + theWorld.alarm != null + } + + @Action + def then() { + println 'To Fire Station: There is an Alarm' + } + + @Priority + int getPriority() { 0 } + +} diff --git a/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TurnSprinklerOnRule.groovy b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TurnSprinklerOnRule.groovy new file mode 100644 index 0000000..b4ea254 --- /dev/null +++ b/easyrules-gradle/src/main/groovy/org/easyrules/samples/fire/TurnSprinklerOnRule.groovy @@ -0,0 +1,28 @@ +package org.easyrules.samples.fire + +import org.easyrules.annotation.Action +import org.easyrules.annotation.Condition +import org.easyrules.annotation.Rule +import org.easyrules.annotation.Priority + +@Rule +class TurnSprinklerOnRule { + + def theWorld + + @Condition + boolean when() { + theWorld.fires.size() > 0 + } + + @Action + def then() { + theWorld.fires.each{ fire -> + println "Turn sprinkler on in room: ${fire.room.name}" + } + } + + @Priority + int getPriority() { 0 } + +}