Skip to content

Commit

Permalink
Merge pull request #365 from gschueler/fix/job-xml-datatype-parsing
Browse files Browse the repository at this point in the history
Fix job xml datatype parsing fixes #353 and fixes #356
  • Loading branch information
gschueler committed Apr 23, 2013
2 parents 2697d19 + c1987e0 commit 9bd6f88
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 11 deletions.
Expand Up @@ -250,7 +250,7 @@ class ScheduledExecution extends ExecutionContext {
se.multipleExecutions=data.multipleExecutions?true:false
}
if(data.nodefilters){
se.nodeThreadcount = data.nodefilters.dispatch.threadcount ? data.nodefilters.dispatch.threadcount : 1
se.nodeThreadcount = data.nodefilters.dispatch.threadcount ?: 1
if(data.nodefilters.dispatch.containsKey('keepgoing')){
se.nodeKeepgoing = data.nodefilters.dispatch.keepgoing
}
Expand Down
34 changes: 31 additions & 3 deletions rundeckapp/grails-app/utils/rundeck/codecs/JobsXMLCodec.groovy
Expand Up @@ -99,7 +99,7 @@ class JobsXMLCodec {
*
*/
static convertToJobMap={ data->
final Object object = XmlParserUtil.toObject(data)
final Object object = XmlParserUtil.toObject(data,false)
if(!(object instanceof Map)){
throw new JobXMLException("Expected map data")
}
Expand Down Expand Up @@ -157,8 +157,11 @@ class JobsXMLCodec {
} else if (optm.values) {
optm.values = [optm.values.toString()]
}
if(null!=optm.enforcedvalues){
optm.enforced=optm.remove('enforcedvalues')
if(null!=optm.enforcedvalues) {
optm.enforced = Boolean.parseBoolean(optm.remove('enforcedvalues'))
}
if(null!=optm.required) {
optm.required = Boolean.parseBoolean(optm.remove('required'))
}
if(ndx>-1){
optm.sortIndex=ndx++;
Expand All @@ -175,6 +178,25 @@ class JobsXMLCodec {
if(null!=map.nodefilters.excludeprecedence){
map.nodefilters.dispatch['excludePrecedence']=map.nodefilters.remove('excludeprecedence')
}
if(null!=map.nodefilters.dispatch.threadcount && ""!= map.nodefilters.dispatch.threadcount){
//convert to integer
def value= map.nodefilters.dispatch.threadcount
try{
map.nodefilters.dispatch.threadcount=Integer.parseInt(value)
}catch (NumberFormatException e){
throw new JobXMLException("Not a valid threadcount: "+value)
}
}
if(null!=map.nodefilters.dispatch.keepgoing){
//convert to boolean
def value= map.nodefilters.dispatch.keepgoing
map.nodefilters.dispatch.keepgoing=Boolean.parseBoolean(value)
}
if(null!=map.nodefilters.dispatch.excludePrecedence){
//convert to boolean
def value= map.nodefilters.dispatch.excludePrecedence
map.nodefilters.dispatch.excludePrecedence=Boolean.parseBoolean(value)
}
}
if(map.schedule){
if(map.schedule.month?.day){
Expand Down Expand Up @@ -304,6 +326,9 @@ class JobsXMLCodec {
cmd.configuration = parsePluginConfig(plugin.configuration)
}
}
if(null!= cmd.keepgoingOnSuccess){
cmd.keepgoingOnSuccess=Boolean.parseBoolean(cmd.keepgoingOnSuccess)
}
}
data.commands.each(fixup)
data.commands.each {
Expand All @@ -312,6 +337,9 @@ class JobsXMLCodec {
}
}
}
if(null!=data.keepgoing && data.keepgoing instanceof String){
data.keepgoing = Boolean.parseBoolean(data.keepgoing)
}
}
/**
* Convert structure returned by job.toMap into correct structure for jobs xml
Expand Down
Expand Up @@ -48,7 +48,7 @@ public class XmlParserUtil {
/**
* Generate data object from the node, not including the node name
*/
static Object toObject(Node data) {
static Object toObject(Node data, boolean analyze=true) {
if (null == data) {
return null
}
Expand All @@ -57,23 +57,23 @@ public class XmlParserUtil {
def attrs = data.attributes()
def map = [:]
if (data.text()) {
map['<text>'] = XmlParserUtil.analyzeText(text)
map['<text>'] = analyze?XmlParserUtil.analyzeText(text):text
}
if (attrs) {
attrs.keySet().each{
map.put(it,analyzeText(attrs[it]))
map.put(it,analyze?analyzeText(attrs[it]):attrs[it])
}
}
if (null != childs && childs instanceof Collection) {
childs.each {gp ->
if (gp instanceof Node) {
if (null != map[gp.name()] && !(map[gp.name()] instanceof Collection)) {
def v = map[gp.name()]
map[gp.name()] = [v, toObject(gp)]
map[gp.name()] = [v, toObject(gp,analyze)]
} else if (map[gp.name()] instanceof Collection) {
map[gp.name()] << toObject(gp)
map[gp.name()] << toObject(gp, analyze)
} else {
map[gp.name()] = toObject(gp)
map[gp.name()] = toObject(gp, analyze)
}
}
}
Expand All @@ -93,4 +93,4 @@ public class XmlParserUtil {
}
return text
}
}
}
66 changes: 66 additions & 0 deletions rundeckapp/test/unit/JobsXMLCodecTests.groovy
Expand Up @@ -728,6 +728,72 @@ class JobsXMLCodecTests extends GroovyTestCase {
assertEquals "incorrect project","demo",jobs[0].project
}

void testDecodeStringsShouldNotBeBoolean() {
def example1 = """<joblist>
<job>
<id>1</id>
<name>false</name>
<description >false</description>
<loglevel>VERBOSE</loglevel>
<group>false</group>
<context>
<project>false</project>
<options>
<option name="false" enforcedvalues="false"/>
<option required="false" name="x" value="9000636026"/>
</options>
</context>
<sequence keepgoing="false">
<command>
<exec>false</exec>
<errorhandler keepgoingOnSuccess="false">
<script>false</script>
<scriptargs>false</scriptargs>
</errorhandler>
</command>
</sequence>
<nodefilters excludeprecedence="false">
<include>
<hostname>false</hostname>
<tags />
<os-name />
<os-family />
<os-arch />
<os-version />
<name />
</include>
</nodefilters>
<dispatch>
<threadcount>2</threadcount>
<keepgoing>false</keepgoing>
</dispatch>
</job>
</joblist>
"""
def jobs = JobsXMLCodec.decode(example1)
assertNotNull jobs
assertEquals "false",jobs[0].jobName
assertEquals "false",jobs[0].groupPath
assertEquals "false",jobs[0].description
assertEquals false, jobs[0].nodeExcludePrecedence
assertEquals false, jobs[0].nodeKeepgoing
assertEquals "false", jobs[0].nodeInclude
assertEquals "false",jobs[0].project
assertEquals 1, jobs[0].workflow.commands.size()
assertEquals "false", jobs[0].workflow.commands[0].adhocRemoteString
assertEquals "false", jobs[0].workflow.commands[0].errorHandler.adhocLocalString
assertEquals "false", jobs[0].workflow.commands[0].errorHandler.argString
assertEquals false, jobs[0].workflow.commands[0].errorHandler.keepgoingOnSuccess
assertEquals 2, jobs[0].nodeThreadcount
assertEquals false, jobs[0].workflow.keepgoing
assertEquals 2, jobs[0].options.size()
def opts=new ArrayList(jobs[0].options)
assertEquals 'false', opts[0].name
assertEquals false, opts[0].enforced
assertEquals 'x', opts[1].name
assertEquals false, opts[1].required
assertEquals '9000636026', opts[1].defaultValue
}
void testDecodeBackwardsCompatibility(){
/**
* Backwards compatibility test, using pre 3.5 format for input
Expand Down

0 comments on commit 9bd6f88

Please sign in to comment.