Skip to content

Commit

Permalink
Merge pull request #77 from will-gilbert/master
Browse files Browse the repository at this point in the history
Implemented DROOLS 'Fire' demo as an EasyRules demo
  • Loading branch information
fmbenhassine authored May 17, 2017
2 parents 71a3802 + 731142c commit 3439574
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 8 deletions.
20 changes: 12 additions & 8 deletions easyrules-gradle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ 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); Nmae and age can be passed in via the command line
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'.
./gradlew Scheduling -q
Expand Down Expand Up @@ -94,11 +99,11 @@ sourceSets {

tasks.withType(JavaExec) {
standardInput = System.in
classpath = sourceSets.main.runtimeClasspath
}

task FizzBuzz (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.fizzbuzz.FizzBuzz'
classpath = sourceSets.main.runtimeClasspath
}

task FizzBuzzER (dependsOn: 'classes', type: JavaExec) {
Expand All @@ -107,31 +112,30 @@ task FizzBuzzER (dependsOn: 'classes', type: JavaExec) {
}
task Simple (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.simple.Launcher'
classpath = sourceSets.main.runtimeClasspath
}

task HelloWorld (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.helloworld.Launcher'
classpath = sourceSets.main.runtimeClasspath
}

task Fire (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.fire.Launcher'
}

task Scheduling (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.scheduling.Launcher'
classpath = sourceSets.main.runtimeClasspath
}

task Shop (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.shop.Launcher'
classpath = sourceSets.main.runtimeClasspath
args = [
findProperty('person') ?: 'Tom',
findProperty('age') ?: '14'
findProperty('age') ?: '17'
]
}

task Spring (dependsOn: 'classes', type: JavaExec) {
main = 'org.easyrules.samples.spring.Launcher'
classpath = sourceSets.main.runtimeClasspath
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.easyrules.samples.fire

import org.easyrules.samples.fire.rules.*
import org.easyrules.samples.fire.beans.*


import static org.easyrules.core.RulesEngineBuilder.aNewRulesEngine as EasyRules

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 the rooms for each name; Install a sprinkler system in each room; Add to the World
def rooms = [:]
def theWorld = new TheWorld()

names.each { name ->
rooms[name] = new Room(name)
theWorld.sprinklers << new Sprinkler(rooms[name])
}


// Create the rules engine
def rulesEngine = EasyRules()
.named("Fire Alarm Demo")
.build()

// Register all of the rules
rulesEngine.registerRule(new EverythingOKRule(theWorld:theWorld))
rulesEngine.registerRule(new RaiseAlarmRule(theWorld:theWorld))
rulesEngine.registerRule(new CancelAlarmRule(theWorld:theWorld))
rulesEngine.registerRule(new ThereIsAnAlarmRule(theWorld:theWorld))
rulesEngine.registerRule(new TurnSprinklerOnRule(theWorld:theWorld))
rulesEngine.registerRule(new TurnSprinklerOffRule(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()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.easyrules.samples.fire

@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
@groovy.transform.ToString(includePackage = false, includeNames = true)
class TheWorld {

def sprinklers = []
def alarm = null
def fires = []

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.easyrules.samples.fire.beans


@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
@groovy.transform.ToString(includePackage = false, includeNames = true)
class Alarm {
def address
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.easyrules.samples.fire.beans

@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
@groovy.transform.ToString(includePackage = false, includeNames = true)
class Fire {
def room;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.easyrules.samples.fire.beans

@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
@groovy.transform.ToString(includePackage = false, includeNames = true)
class Room {
def name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.easyrules.samples.fire.beans

@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
@groovy.transform.ToString(includePackage = false, includeNames = true)
class Sprinkler {
def room;
def on = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.easyrules.samples.fire.rules

import org.easyrules.annotation.Action
import org.easyrules.annotation.Condition
import org.easyrules.annotation.Rule
import org.easyrules.annotation.Priority

@Rule(description='All the fires are out, cancel the alarm')
class CancelAlarmRule {

def theWorld

@Condition
boolean when() {
theWorld.alarm && theWorld.fires.size() == 0
}

@Action
def then() {
println( "Cancel the Alarm");
theWorld.alarm = null
}

@Priority
int getPriority() { 1 }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.easyrules.samples.fire.rules

import org.easyrules.annotation.Action
import org.easyrules.annotation.Condition
import org.easyrules.annotation.Rule
import org.easyrules.annotation.Priority

@Rule(description='No alarm, nothing to see here; This need to be last rule considered')
class EverythingOKRule {

def theWorld

@Condition
boolean when() {
theWorld.alarm == null
}

@Action
def then() {
println 'At the Fire Station: Everything is OK'
}

@Priority
int getPriority() { 15 }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.easyrules.samples.fire.rules

import org.easyrules.samples.fire.beans.Alarm

import org.easyrules.annotation.Action
import org.easyrules.annotation.Condition
import org.easyrules.annotation.Rule
import org.easyrules.annotation.Priority

@Rule(description='A fire will raise an alarm')
class RaiseAlarmRule {

def theWorld

@Condition
boolean when() {
theWorld.fires.size() > 0
}

@Action
def then() {
theWorld.alarm = new Alarm('123 Main Street')
println( "Raise the Alarm");
}

@Priority
int getPriority() { 2 }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.easyrules.samples.fire.rules

import org.easyrules.annotation.Action
import org.easyrules.annotation.Condition
import org.easyrules.annotation.Rule
import org.easyrules.annotation.Priority

@Rule(description='The alarm is detected at the fire station')
class ThereIsAnAlarmRule {

def theWorld

@Condition
boolean when() {
theWorld.alarm != null
}

@Action
def then() {
println "At the Fire Station: There is an Alarm at ${theWorld.alarm.address}"
}

@Priority
int getPriority() { 5 }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.easyrules.samples.fire.rules

import org.easyrules.annotation.Action
import org.easyrules.annotation.Condition
import org.easyrules.annotation.Rule
import org.easyrules.annotation.Priority

@Rule(description='The fires are out, turn off all of the sprinklers')
class TurnSprinklerOffRule {

def theWorld

@Condition
boolean when() {
theWorld.fires.size() == 0
}

@Action
def then() {
theWorld.sprinklers.each { sprinkler ->
if(sprinkler.on) {
sprinkler.on = false
println "Turn sprinkler off in room: ${sprinkler.room.name}"
}
}
}

@Priority
int getPriority() { 0 }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.easyrules.samples.fire.rules

import org.easyrules.annotation.Action
import org.easyrules.annotation.Condition
import org.easyrules.annotation.Rule
import org.easyrules.annotation.Priority

@Rule(description='A fire has been detected in a room, turn on the sprinkler in the room; Highest priority rule')
class TurnSprinklerOnRule {

def theWorld

@Condition
boolean when() {
theWorld.fires.size() > 0
}

@Action
def then() {
theWorld.fires.each { fire ->

def sprinkler = theWorld.sprinklers.find { sprinkler ->
sprinkler.room.name == fire.room.name

}

if(sprinkler) {
sprinkler.on = true
println "Turn sprinkler on in room: ${sprinkler.room.name}"
}
}
}

@Priority
int getPriority() { 0 }

}

0 comments on commit 3439574

Please sign in to comment.