Reputation: 1231
I am building a library for myself and using ConfigSlurper
to parse a config.groovy
file, and other config sources into an aggregated ConfigObject
that I am using Micronaught compile time IOC to inject
@Bean
@Named('config')
ConfigObject config () {
Map envMap = [:]
def sysProps = System.getenv()
if (System.getProperty("env") ) {
envMap = System.getenv().findResult { it.key?.toLowerCase().contains "env" }.collect { [(it.key?.toLowerCase().substring(0, 2)): it.value.toLowerCase()] }
} else
envMap.get ('env', "development")
def env = envMap.get('env')
def resourcePath = "src${File.separatorChar}${env =="test" ?: "main"}${File.separatorChar}resources${File.separatorChar}"
ConfigObject config = new ConfigSlurper().parse(new File("${resourcePath}ApplicationConfig.groovy").text /*.toURI().toURL()*/)
config.put('systemProperties', sysProps)
config.putAll(envMap)
config.put('projectPath', System.getProperty("user.dir"))
config.put('resourcesPath', resourcePath.toString())
File resourceDirectory = new File ("${System.getProperty("user.dir")}$File.separatorChar$resourcePath")
FilenameFilter filter = {file, name -> name.matches(~/^.*properties$/) }
List propsFiles = resourceDirectory.listFiles (filter)
filter = {file, name -> name.matches(~/^.*yaml$/) }
List yamlFiles = resourceDirectory.listFiles (filter)
propsFiles.each {file ->
Properties prop = new Properties()
prop.load(new FileInputStream (file) )
Map propsMap = [:]
for (key in prop.stringPropertyNames()) {
propsMap.put(key, prop.getProperty(key))
}
config.putAll(propsMap)
}
yamlFiles.each {file ->
def yamlConfig = new YamlSlurper().parseText(file.text)
config.putAll(yamlConfig)
}
config
}
the resources/applicationConfig.groovy
file looks like this
framework {
environments {
development {
server = "local" // choice of {local|clustered}
vertxOptions {
}
}
test {
server = "local" // choice of {local|clustered}
vertxOptions {
}
}
production {
server = "clustered" // choice of {local|clustered}
vertxOptions {
}
}
}
}
The code parses the groovy file but when I look at what in the configObject
, its created the tope level framework map entry - but the lower levels are not there.
calling configObject.framework
in code returns the object but it is of size() == 0!
I don't understand why the rest of the structure is not getting built.
Can any one advise why the internal structure is not being parsed and built.
Can anyone suggest what I have done wrong ?
I have just done a stripped back version like this
def configText = """
framework {
environments {
development {
server = "local" // choice of {local|clustered}
vertxOptions {
}
}
test {
server = "local" // choice of {local|clustered}
vertxOptions {
}
}
production {
server = "clustered" // choice of {local|clustered}
vertxOptions {
}
}
}
}
"""
ConfigObject conf = new ConfigSlurper().parse(configText)
assert conf.framework?.environments?.size() == 3
where the error shows this
Caught: Assertion failed:
assert conf.framework?.environments?.size() == 3
| | | | |
| | [:] 0 false
| ['environments':[:]]
['framework':['environments':[:]]]
Assertion failed:
assert conf.framework?.environments?.size() == 3
| | | | |
| | [:] 0 false
| ['environments':[:]]
['framework':['environments':[:]]]
at scripts.configSlurperTest.run(configSlurperTest.groovy:33)
at
Upvotes: 1
Views: 120
Reputation: 171124
The environments
section when parsed by configslurper is conditional to the environment you pass to the constructor of ConfigSlurper itself.
Lets say you want the development config to be the default, but then you want to override this when run in test
or production
, you would do the following:
def configText = """
framework {
// defaults
mode = 'development'
server = "local" // choice of {local|clustered}
vertxOptions {
}
environments {
// test settings
test {
mode = 'testing'
server = "local" // choice of {local|clustered}
vertxOptions {
}
}
// production settings
production {
mode = 'live!'
server = "clustered" // choice of {local|clustered}
vertxOptions {
}
}
}
}
"""
// Default values
assert new ConfigSlurper().parse(configText).framework.mode == 'development'
// Test values
assert new ConfigSlurper('test').parse(configText).framework.mode == 'testing'
// Production values
assert new ConfigSlurper('production').parse(configText).framework.mode == 'live!'
Upvotes: 2