Use ConfigSluper Instead Of Properites Files



>> Thursday, September 9, 2010

I often use Java property files as configuration for prototypes, proofs of concepts, utility applications, etc. Groovy has a more powerful way of doing this called a ConfigSlurper (JavaDoc).

A ConfigSlurper just uses a Groovy script as input instead of a .properties file. This lets you do better (in my opinion) configuration like having typed properties (instead of them all being Strings you have to convert) including lists and maps, tree-structures of properties, even deriving a property value based on some calculation or closure.

Here are some examples. All the code can be downloaded here (box.net)


//Config1.groovy
stringProperty="Some string"
numberProperty=42
booleanProperty=false
listProperty=["Monday", "Tuesday", "Wednesday"]

Here is a basic configuration file using some different types. Here is how to read and use it:

def config = new ConfigSlurper().parse(new File('src/Config1.groovy').toURL())

assert "Some string" == config.stringProperty
assert config.stringProperty.class == String

assert 42 == config.numberProperty
assert config.numberProperty.class == Integer

assert false == config.booleanProperty
assert config.booleanProperty.class == Boolean

assert ["Monday", "Tuesday", "Wednesday"] == config.listProperty
assert 3 == config.listProperty.size()
assert config.listProperty.class == ArrayList


Another powerful feature is being able to use trees of data like this:

//Config2.groovy
teams {
packers {
quarterback="Aaron Rodgers"
recievers=["Greg Jennings", "Donald Driver"]
}
vikings {
quarterback="Brett Favre"
}
}


And then reading them like this:

def config = new ConfigSlurper().parse(new File('src/Config2.groovy').toURL())

assert "Aaron Rodgers" == config.teams.packers.quarterback
assert ["Greg Jennings", "Donald Driver"] == config.teams.packers.recievers
assert "Brett Favre" == config.teams.vikings.quarterback


Along those lines, there is a special configuration called "environment." This allows you to use different configurations based on what "environment" you are in.

//Config3.groovy
website {
//default values
url = "http://default.mycompany.com"
port = 80
user = "test"
}

environments {
development {
website {
url = "http://dev.mycompany.com"
port = 8080
}
}
production {
website {
url = "http://www.mycompany.com"
user = "prodUser"
}
}
}

In this example, there are some default values for the website properties. Then, the different environments overwrite some of the defaults. Here is how you call the ConfigSlurper to use the different environments.


//defaults
def config = new ConfigSlurper().parse(new File('src/Config3.groovy').toURL())

assert config.website.url=="http://default.mycompany.com"
assert config.website.port==80
assert config.website.user=="test"

//development environment
config = new ConfigSlurper("development").parse(new File('src/Config3.groovy').toURL())

assert config.website.url=="http://dev.mycompany.com"
assert config.website.port==8080
assert config.website.user=="test"

//production environment
config = new ConfigSlurper("production").parse(new File('src/Config3.groovy').toURL())

assert config.website.url=="http://www.mycompany.com"
assert config.website.port==80
assert config.website.user=="prodUser"


Finally (for this article), here are a few fun things you can do with a ConfigSlurper including calculated values and merging configs.


//Config4.groovy

//set the value as some calculation
calculation = 2+2

//base the value off of some other property
calc2 = calculation * 2

//set the value using a closure
doubling = 1
5.times{ doubling = doubling * 2 }


And using those values:

def config = new ConfigSlurper().parse(new File('src/Config4.groovy').toURL())

assert 4 == config.calculation
assert 8 == config.calc2

assert 32 == config.doubling

//merge config files
def config1 = new ConfigSlurper().parse(new File('src/Config1.groovy').toURL())
def config2 = new ConfigSlurper().parse(new File('src/Config2.groovy').toURL())
config1 = config1.merge(config2)
assert 42 == config1.numberProperty
assert "Aaron Rodgers" == config1.teams.packers.quarterback


Leave a comment if you have any questions or suggestions!

4 comments:

Kalpesh Soni August 15, 2013 at 10:12 AM  

awesome awesome post!

note that calculations are not done lazy in case of environment

so if you are "calculating" url = host + port

you need to do that in each dev/test/prod etc

Anonymous,  March 5, 2014 at 6:05 AM  

fantastic....thank you so much Matt...i just got the ease of working on ConfigSlurper

Rares March 31, 2016 at 7:34 AM  
This comment has been removed by the author.
Rares March 31, 2016 at 7:43 AM  
This comment has been removed by the author.

Post a Comment

  © Blogger template Webnolia by Ourblogtemplates.com 2009

Back to TOP