Truly externalizing the Grails DateSource configuration

Why externalize?

During development of a Grails application, I’ve also developed some independent POJ applications to work alongside the Grails application; because these independent applications worked on the same data as the Grails, they naturally had to use the same data source.
Wouldn’t it be great if all these applications could use the same data source configuration files?

Grails’ default configuration (datasources.groovy) clearly couldn’t stay because there is no way to share it while it’s still in the ‘grails-app/conf’ directory.
After doing a tad of research, It seemed that externalization was possible… well, sort of.

Why do I say “sort of”? Because if Grails is going to share a data source configuration, it’s going to do so on its own terms.

Issues with the existing methods

Allow me to explain.
The current options for externalization are good, but they are limited:

#1 Data source configuration from an external data source

This solution presents us with the “chicken and egg problem” and stays the same; We remain with a data source which we need to share. So, scratch this.

#2 Data source configuration from an external properties file

This is a pretty good option, right? Store the properties file in an external jar file and share it as a dependency between all the applications that need it.
But that’s still not good enough!
Because the properties are eventually loaded directly to Grails’ configuration object, the property names within the file must use Grails’ naming conventions, otherwise they won’t be recognized!
We want to share this properties file between different (not-necessarily-Grails) applications, so why should other applications have to use Grails’ naming conventions?
Also, what if we would like to use a different format other than properties? YAML, JSON, GConfig, etc.?
Scratch this one off, too.

So what can we do?

There are a number of keys to the solution.
First we must understand the order in which Grails loads its data sources.
Grails and data source settings are eventually stored in the same configuration object, and during bootstrap the data source settings are first read from the Config.groovy file (whether directly, from a different data source or from an external properties file), and finally read from the datasources.groovy (if it exists).

Another thing we should remember is that the Config.groovy is… Groovy; this means we can do whatever the hell we want within it.

GIT-R-DONE

So let’s place the data source configuration file in an external shared project, say “common-settings” and add it as a dependency to our Grails project to ensure that it’s loaded on bootstrap.

Now, let’s add a new method “getDataSourcesConfig” to our project’s Config.groovy file.
The method will locate the external properties resource and read it via Groovy’s config slurper.

private ConfigObject getDataSourcesConfig() {
    Properties dataSourcesProps = new Properties()
    InputStream resourceStream
    try {
      resourceStream = new PathMatchingResourcePatternResolver().getResource('datasources/source.properties').inputStream
      dataSourcesProps.load(resourceStream)
    } finally {
        IOUtils.closeQuietly(resourceStream)
    }
    new ConfigSlurper().parse(dataSourcesProps)

Now we can call this method from anywhere within the body of our Config.groovy file, and map our properties to Grails' data source properties.

ConfigObject dataSourcesConfig = getDataSourcesConfig()
grails.mongo.username = dataSourcesConfig.get 'custom.datasource.username'
//etc

And there we have it.

About these ads

One thought on “Truly externalizing the Grails DateSource configuration

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s