Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/grails 2.2.x upgrade #8

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
target/
out/
.idea/
*.iml
.classpath
.project
.settings/
.DS_Store
*/.DS_Store
web-app/WEB-INF
plugin.xml
*.zip
*.log
atlassian-ide-plugin.xml
web-app/css/errors.css
web-app/css/mobile.css
web-app/images/apple-touch-icon-retina.png
web-app/images/apple-touch-icon.png
web-app/images/favicon.ico
web-app/images/grails_logo.jpg
web-app/images/grails_logo.png
web-app/images/springsource.png
23 changes: 15 additions & 8 deletions README → README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
One Ring - Scripting Rules Engine Service
# One Ring - Scripting Rules Engine Service

One Ring isn't like other "Rules Engines", it's meant to be used as a web service for multiple applications
to gain access to scripted processing of arbitrary parameters.
Expand All @@ -12,7 +12,9 @@ One Ring - Scripting Rules Engine Service

It has not been optimised for speed, it's not fast but it's not exactly slow.

Features
See http://nerderg.com/One+Ring for doco and downloads of ready to go files.

## Features

* A friendly to quite a few humans DSL
* REST and SOAP interfaces
Expand All @@ -21,10 +23,15 @@ Features
* Script rules in simplified or not so simplified Groovy
* Keepin' it simple

Changes 15th May 2012
## Changes 28th April 2013

Added a "callRuleset" function to rules that lets you call another Ruleset from a rule like so:
Upgraded to Grails 2.1.1 and upgraded to use the latest rulesEngine.jar
Removed cruft.

## Changes 15th May 2012

Added a "callRuleset" function to rules that lets you call another Ruleset from a rule like so:
```groovy
ruleset("caller"){
require(['a', 'b'])
rule("call div"){
Expand All @@ -49,13 +56,13 @@ ruleset("divide"){
}
}
}

Changes 5th March 2012
```
## Changes 5th March 2012

We now scrub JSONObject.Null values from incoming facts and convert to a null because of all the problems JSONObject.Null
causes.

Changes 20th December 2011
## Changes 20th December 2011

Made JSONObject.NULL fail a groovy truth test so that tests like if(blah) work as expected
References to maps within maps will now work so you can test S1.names.firstName == "Peter"
Expand All @@ -67,7 +74,7 @@ test(name: [firstName:'Peter', secondName: 'McNeil') {
assert fact.name.firstName == 'peter'
}

Changes 20th October 2011
## Changes 20th October 2011

One Ring has undergone quite a change. I have ripped out the online editing of rules, instead ruleSet files are
added to a directory (default ~/.OneRing/rules) which are read and parsed on startup and cached in memory (hashmap).
Expand Down
12 changes: 3 additions & 9 deletions application.properties
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#Grails Metadata file
#Fri Jul 20 09:56:54 EST 2012
app.grails.version=1.3.7
#Sat Aug 03 12:05:33 EST 2013
app.grails.version=2.2.4
app.name=rulesEngine
app.servlet.version=2.4
app.version=0.9.2
plugins.codenarc=0.8.1
plugins.cxf=0.7.0
plugins.hibernate=1.3.7
plugins.jquery=1.5.2
plugins.jquery-ui=1.8.11
plugins.tomcat=1.3.7
app.version=1.0.1
14 changes: 4 additions & 10 deletions grails-app/conf/BuildConfig.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,13 @@ grails.project.dependency.resolution = {
grailsPlugins()
grailsHome()
grailsCentral()

// uncomment the below to enable remote dependency resolution
// from public Maven repositories
//mavenLocal()
//mavenCentral()
//mavenRepo "http://snapshots.repository.codehaus.org"
//mavenRepo "http://repository.codehaus.org"
//mavenRepo "http://download.java.net/maven/2/"
//mavenRepo "http://repository.jboss.com/maven2/"
}
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

// runtime 'mysql:mysql-connector-java:5.1.5'
}
plugins {
compile ":cxf:1.1.1"
build ":tomcat:$grailsVersion"
}
}
4 changes: 2 additions & 2 deletions grails-app/conf/Config.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ log4j = {
}
environments {
production {
grails.serverURL = "http://127.0.0.1"
grails.serverURL = ""
oneRing.rules.directory = "${userHome}/.OneRing/rules"
log4j = {
info 'stdout, file',
debug 'stdout, file',
'grails.app'
}
}
Expand Down
9 changes: 0 additions & 9 deletions grails-app/conf/DataSource.groovy
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
dataSource {
pooled = true
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RulesEngineController {
response.status = 400
return render("Error: No rule set supplied")
}
def facts = params.facts
String facts = params.facts
if (!facts) {
log.error "No facts supplied"
response.status = 400
Expand Down Expand Up @@ -84,7 +84,7 @@ class RulesEngineController {
log.debug "render json $results"
return results
} catch (e) {
int lineNumber = e.stackTrace.find {
Integer lineNumber = e.stackTrace.find {
it.fileName == 'Script1.groovy'
}?.lineNumber
log.error "Error processing rule $ruleSet -> $e line $lineNumber"
Expand All @@ -105,14 +105,14 @@ class RulesEngineController {
if (it.value.equals(null)) {
it.value = null
} else if (it.value instanceof Map) {
it.value = cleanUpJSONNullMap(it.value)
it.value = cleanUpJSONNullMap(it.value as Map)
} else if (it.value instanceof Collection) {
it.value = cleanUpJSONNullCollection(it.value)
it.value = cleanUpJSONNullCollection(it.value as Collection)
}
}
}

private Collection cleanUpJSONNullCollection(Collection c) {
protected Collection cleanUpJSONNullCollection(Collection c) {
//create a new collection sans JSONObject.Null objects
List collect = []
c.each { v ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class RuleSetService {
}
}
log.debug "read files in " + (System.currentTimeMillis() - startProcess) + "ms"
File tmpOut = new File("/tmp/rules.groovy")
File tmpOut = File.createTempFile("rules", ".groovy")
tmpOut.write(ruleSetStrings.toString())
startProcess = System.currentTimeMillis()
List<RulesetDelegate> ruleSetDelegates = RulesEngine.processRules(ruleSetStrings.toString())
Expand Down
8 changes: 2 additions & 6 deletions grails-app/views/layouts/main.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
<head>
<title><g:layoutTitle default="Grails"/></title>
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}"/>
<link rel="shortcut icon" href="${resource(dir: 'images', file: 'icon32.png')}" type="image/png"/>
<link rel="shortcut icon" href="${resource(dir: 'images', file: 'logo-32.png')}" type="image/png"/>
<g:layoutHead/>
<g:javascript plugin="jquery" library="jquery"/>
<g:javascript library="ace/ace"/>
<g:javascript library="ace/theme-twilight"/>
<g:javascript library="ace/mode-groovy"/>
<g:javascript library="application"/>
</head>

<body>
<div id="spinner" class="spinner" style="display:none;">
<img src="${resource(dir: 'images', file: 'spinner.gif')}"
alt="${message(code: 'spinner.alt', default: 'Loading...')}"/>
alt="..."/>
</div>

<div id="head"><a href="${createLink(uri: '/')}"><img class="logo"
Expand Down
2 changes: 1 addition & 1 deletion grails-app/views/ruleSet/list.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<body>
<div class="nav">
<span class="menuButton"><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
<span class="menuButton"><a class="home" href="${createLink(controller: 'ruleSet', action: 'update')}">Update</a></span>
<span class="menuButton"><a class="update" href="${createLink(controller: 'ruleSet', action: 'update')}">Update</a></span>
</div>
<div class="body">
<h1><g:message code="default.list.label" args="[entityName]"/></h1>
Expand Down
Binary file modified lib/engine.jar
Binary file not shown.
11 changes: 11 additions & 0 deletions src/groovy/com/nerderg/rules/RulesetNotFoundException.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,18 @@ package com.nerderg.rules
*/
class RulesetNotFoundException extends Exception {

RulesetNotFoundException() {
}

RulesetNotFoundException(String s) {
super(s)
}

RulesetNotFoundException(String s, Throwable throwable) {
super(s, throwable)
}

RulesetNotFoundException(Throwable throwable) {
super(throwable)
}
}
20 changes: 19 additions & 1 deletion test/unit/com/nerderg/rules/RulesEngineControllerTests.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,28 @@ class RulesEngineControllerTests extends ControllerUnitTestCase {
void testNullCollectionHandling() {

def facts = "[{id: 1, income: 23heaps, expenses: 501},{id: 2, income: 2000, expenses: 600}, null]"
def list = controller.cleanUpJSONNullCollection(JSON.parse(facts))
def list = controller.cleanUpJSONNullCollection(JSON.parse(facts) as Collection)
assert list.size() == 3
assert list[2] == null

}

void testFireJsonNotFound() {
mockLogging(RulesEngineService, true)
mockLogging(RulesEngine, true)

def rssControl = mockFor(RuleSetService)
rssControl.demand.getRuleSet(1..1) { String name ->
return null
}
controller.rulesEngineService = new RulesEngineService()
controller.rulesEngineService.ruleSetService = rssControl.createMock()
controller.params.ruleSet = "Means Toast"
controller.params.facts = "[{id: 1, income: 900, expenses: 501},{id: 2, income: 2000, expenses: 600}]"
controller.fire()
println controller.response.contentAsString
def expected = '[{"error":"Ruleset \'Means Toast\' not found"}]'
assert controller.response.contentAsString == expected
}

}
4 changes: 2 additions & 2 deletions test/unit/com/nerderg/rules/RulesEngineTests.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ ruleset("divide"){
}
}
"""
Map<String, RulesetDelegate> ruleSets = RulesEngine.processRules(dslScript).groupBy { it.name }
Map<String, List<RulesetDelegate>> ruleSets = RulesEngine.processRules(dslScript).groupBy { it.name }
assert ruleSets
assert ruleSets.size() == 2
RulesEngineService rulesEngineService = new RulesEngineService(ruleSetService: [getRuleSet: {name -> ruleSets[name].first()}])
Expand Down Expand Up @@ -314,7 +314,7 @@ ruleset("divide"){

List<String> fails = RulesEngine.testRuleset(ruleSet)
assert !fails.empty
assert fails[0].startsWith("Test 1\nassert fact[name]")
assert fails[0].startsWith("\n-----\nTest 1 failed")

ruleDsl = """ruleset("Means Test") {
require(['income', 'expenses'])
Expand Down
54 changes: 22 additions & 32 deletions web-app/WEB-INF/applicationContext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,30 @@
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
<description>Grails application factory bean</description>
<property name="grailsDescriptor" value="/WEB-INF/grails.xml"/>
<property name="grailsResourceLoader" ref="grailsResourceLoader"/>
</bean>
<bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
<description>Grails application factory bean</description>
<property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
<property name="grailsResourceLoader" ref="grailsResourceLoader" />
</bean>

<bean id="pluginManager" class="org.codehaus.groovy.grails.plugins.GrailsPluginManagerFactoryBean">
<description>A bean that manages Grails plugins</description>
<property name="grailsDescriptor" value="/WEB-INF/grails.xml"/>
<property name="application" ref="grailsApplication"/>
</bean>
<bean id="pluginManager" class="org.codehaus.groovy.grails.plugins.GrailsPluginManagerFactoryBean">
<description>A bean that manages Grails plugins</description>
<property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
<property name="application" ref="grailsApplication" />
</bean>

<bean id="grailsConfigurator" class="org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator">
<constructor-arg>
<ref bean="grailsApplication"/>
</constructor-arg>
<property name="pluginManager" ref="pluginManager"/>
</bean>
<bean id="grailsConfigurator" class="org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator">
<constructor-arg>
<ref bean="grailsApplication" />
</constructor-arg>
<property name="pluginManager" ref="pluginManager" />
</bean>

<bean id="grailsResourceLoader" class="org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean">
<property name="grailsResourceHolder" ref="grailsResourceHolder"/>
</bean>
<bean id="grailsResourceLoader" class="org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean" />

<bean id="grailsResourceHolder" scope="prototype"
class="org.codehaus.groovy.grails.commons.spring.GrailsResourceHolder">
<property name="resources">
<value>classpath*:**/grails-app/**/*.groovy</value>
</property>
</bean>

<bean id="characterEncodingFilter"
class="org.springframework.web.filter.CharacterEncodingFilter">
<property name="encoding">
<value>utf-8</value>
</property>
</bean>
<bean id="characterEncodingFilter" class="org.springframework.web.filter.CharacterEncodingFilter">
<property name="encoding">
<value>utf-8</value>
</property>
</bean>
</beans>
8 changes: 4 additions & 4 deletions web-app/WEB-INF/sitemesh.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<sitemesh>
<page-parsers>
<parser content-type="text/html"
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser"/>
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
<parser content-type="text/html;charset=ISO-8859-1"
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser"/>
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
<parser content-type="text/html;charset=UTF-8"
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser"/>
class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
</page-parsers>

<decorator-mappers>
<mapper class="org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutDecoratorMapper"/>
<mapper class="org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutDecoratorMapper" />
</decorator-mappers>
</sitemesh>
Loading