Externalizing Configurations per Grails Application

You may have multiple grails applications and each is using different datasource, mail, etc configurations. It may be benefit to externalize those configurations for maintainability as well as portability reasons. In this post, i demonstrate one way to accomplish it.

Make Grails Externalize

In order to externalize configurations, you have to add following line in the conf/Config.groovy:


grails.config.locations = ["file:${userHome}/.grails/apps-config/${appName}/${appName}-config.groovy"]

This way you specify the path as well as the name of the configuration file. We choose to keep our configuration in Groovy file, however, it works as well if .properties file:


grails.config.locations = ["file:${userHome}/.grails/apps-config/${appName}/${appName}-config.properties"]

However, its preferable in .groovy file because that way you are able to script. Please see section ‘.Groovy vs .Properties’ below

Naming Application

In the above, you can see we using variable – appName. This variable is set by Grails at the startup. It is defined in the ‘application.properties’ file in root directory of the application. Here is example:


#Grails Metadata file
#Sat Oct 06 09:17:17 CDT 2012
app.grails.version=2.1.1
app.name=minnehaha
app.servlet.version=2.5

Grails reads the value of ‘app.name’ and initializes variable ‘appName’ that you can use in any of Grails configuration file. In our case, we use to set proper directory as well as the externalized configurations file name

External Configuration File

Once externalized in ‘conf/Config.groovy’ and application name set as described above, at last, create groovy script with externalized configurations and place it in directory specified above. Here is an example of mail server configuration externalized:

grails{
    mail{
        host="smtp.gmail.com"
        port=465
        username="website@ms.com"
...
    }

}

This will configure mail server with the email account for the specific application

.Groovy vs .Properties file

Externalizing in .groovy file,  does not necessary mean you are unable to accomplish the same with .properties file. For the fact it is doable, however, let me demonstrate how, so its clear, going with .groovy file, is the preferred way.

For example, to externalize in .groovy configuration file something per different environment such as datasource is as easy as adding:

environments {
    test {
       dataSource {
          driverClassName = "com.mysql.jdbc.Driver"
         ...
         }
    }
    development {
       dataSource {
          driverClassName = "com.mysql.jdbc.Driver"
         ...
         }
    }
}

It doesn’t necessary mean you are unable to accomplish the same with .properties file. For the fact it is doable, however, let me demonstrate how, so its clear, going with .groovy file, is the preferred way.

To accomplish the same – different datasource per environment, its necessary to update the externalization variable ‘grails.config.locations’ in the .conf/Config.groovy:

grails.config.locations = ["file:${userHome}/.grails/${appName}-config-${grails.util.Environment.current.name}.properties"]

From the code snippet you can see, we append the environment to the .properties file name. So, that different .properties file is read for each environment that way different configurations applied:

dataSource.dbCreate =
dataSource.driverClassName = com.mysql.jdbc.Driver
dataSource.url = jdbc:mysql://localhost/minnehaha_test
dataSource.username = root
dataSource.password = mysql

Above is an example for test environment .properties file to use appropriate database, however. There needs to be .properties file per environment:

 >/home/me/.grails/myapp/myapp-config-development.properties
  >/home/me/.grails/myapp/myapp-config-test.properties
  >/home/me/.grails/myapp/myapp-config-production.properties

In short, it required many more .properties files to accomplish the same in one .groovy due to scripting capabilities

NOTE: For .properties config files, make sure quotes are removed,otherwise, errors like such ‘ Cannot load JDBC driver class ‘”com.mysql.jdbc.Driver”‘ is received

Its important to note that externalized configurations supersede the configurations in any of the Grails configuration files(BuildConfig.groovy, Config.groovy, DataSource.groovy,etc.)

Issues

1. If the externalized .groovy script file has syntax errors then none of the configurations are read as well as Grails continues the startup without any error notification.

Leave a Reply

Your email address will not be published. Required fields are marked *