One Ring - Scripting Rules Engine Service
It centralises processing of common rules (or business rules) for multiple applications that need access to the same rules. Rules are defined using a simple language understandable by domain experts.
One Ring is aimed at continuous processing for multiple small applications, not batch processing of billions of
entities. It is very light weight and is deployed as a WAR inside a container like Tomcat. You can have multiple One Ring servers running in the same container pointing to different, or the same rule sets.
It has not been optimised for speed, but it's not exactly slow. The engine can process a 1000 simple 3 rule rule sets in around 200ms or ~0.2ms per rule set. That's serially called with fact set-up in each call.
Features
- A friendly to quite a few humans DSL
- REST and SOAP interfaces
- JSON and XML fact encoding
- Inbuilt rule testing in the rule set
- Script rules in simplified or not so simplified Groovy
- Simple directory of ruleset files which can be version controlled using any version control system like Git, Mercurial, Subversion etc.
- Live updating of rulesets without interruption
Still to come
- User management and security - at the moment it is assumed you run this server partitioned from external access, however the ability to update and access the servers REST or SOAP functionality could be secured to allow B2B scripted access.
- Pluggable DSLs - adding Domain Specific Language processing for specific domains should be a simple thing to do.
- Scriptable data access/lookup services - rules commonly have data tables, and including those tables in the rules directly is ugly and could be abstracted, it's simple enough to read a file in a One Ring rule script, but accessing other REST services and databases could be simpler.
Getting started
Getting One Ring going is pretty simple Download the rulesEngine-0.7.war and drop it into a web container like Tomcat and point your browser at http://localhost:8080/rulesEngine (change "localhost" to the host you're Tomcat instance is on).Check out more details here: One+Ring+install
Rule examples
The following is an example rule set using the simple DSL. This shows three different forms of rules, 1) when, then, otherwise; 2) evaluate; and 3) Plain old Groovy.A couple of things to note from this example:
- The rule set takes a Map of Facts
- The facts are dynamically typed
- The require phrase tells the rules engine that certain facts must exist or it will fail
- When, Then and Evaluate rules assume variables are from the map of facts. If you assign a value it will be returned in the map of facts to the caller. Outside of when, then, otherwise and evaluate you need to directly reference facts.
- "When" clauses must end in an value that will be judged true (then) or false (otherwise). This uses Groovy Truth, so a blank string evaluates to false.
- The test phrase takes input test facts, runs them against the rules, and checks the results.
Rule set variables
You can define a variable outside the rules that can be used inside a rule. e.g:require(["singer"])
rule("singer is Kelis"){
when { singer =~ /(?i)Kelis/ }
then { boys = 'In the yard' }
otherwise { boys = 'not in the yard' }
}
test(singer: 'Kelis') { boys 'In the yard' }
test(singer: 'kElis') { boys 'In the yard' }
test(singer: 'Snoop Dog') { boys 'not in the yard' }
}
require(['value'])
rule('quantity within range') {
when {
value < 1 || value > 10
}
then {
failed = true
message = ["invalid quantity"]
}
otherwise {
failed = false
message = []
}
}
test(value: 0) {
failed true
message (["invalid quantity"])
}
}