Externalize and reload grails configuration dynamically

15 / Oct / 2010 by Bhagwat Kumar 9 comments

Configuration file plays great role in grails. You can store application specific configuration at one place. One of the grails goodies is that you can externalize configuration file i.e. store them at a location so that it is not packed with the war file.

Here is the part of Config.groovy that describes how to specify external configuration file :

// configuration files can either be Java properties files or ConfigSlurper scripts.
//Note that the file whose path is specified below is not included in war file.

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

Externalizing the configuration helps us to change the configuration without re-creating the war file. But the problem I faced was changes to this external configuration file was not reloaded by grails automatically. I found the code to reload the configuration in Grails Quartz plug-in source code. Here is the code snippet.

        def config = ConfigurationHolder.config
        GroovyClassLoader classLoader = new GroovyClassLoader(getClass().classLoader)

        // merging default Quartz config into main application config
        config.merge(new ConfigSlurper(GrailsUtil.environment).parse(classLoader.loadClass('DefaultQuartzConfig')))

However the code is reloading configuration from a groovy class(it should be in the class-path) that I could not use in my use case.

Doing some googling and thanks to Himanshu for useful code snippets, I found the constructor that accepts String . I used the following code to merge the changed external configuration file with the configuration of running application :

def config = ConfigurationHolder.config
def locations = config.grails.config.locations

locations.each {
	String configFileName = it.split("file:")[1]
	config.merge(new ConfigSlurper().parse(new File(configFileName).text))
}
//above code iterates over all the external config files and 
//merges them with the running application configuration

I wrote the above code inside a controller-action. Now whenever I change the external configuration file I simply hit the URL of the controller-action and the changes take effect that point onward. You can also use Grails Console plug-in that lets you execute groovy code from the running application or use Grails Quartz Job to periodically reload the external configuration.


Hope this helps you !


Bhagwat Kumar
bhagwat(at)intelligrape(dot)com

FOUND THIS USEFUL? SHARE IT

comments (9)

  1. Prateek

    Hi Everyone,
    I am following above code but I stuck in a problem. Here it is –
    In case of nested map config, If I need to delete some keys from config map, It just merge the old map with new map. New deleted keys are not deleted. Please help.

    Reply
  2. boutfounast

    Hello Mr Bhagwat Kumar,
    thanks for the useful post, i am asking if is it possible to reload hibernate configuration, i have externalized the datasource arguments to a text file, i can read them, and edit them at runtime, but i gave to restart the container to connect to new configured database … can i do this without restarting the app ??

    thanks.

    Reply
  3. Bhagwat Kumar

    Hi Parag,
    Here is a sample method which can update the configuration :

    private void setConfigValue(String pathString, def newValue) {
    def config = grailsApplication.config /* hope you have injected grailsApplication bean */
    List paths = pathString.tokenize(“.”)
    String lastVar = paths.last()
    paths = paths – lastVar
    paths.each {path ->
    config = config.”${path}”
    }
    config.”$lastVar” = newValue
    }

    You can call this like :

    setConfigValue(“grails.mail.host”, “test2.smtp.com”)

    You can use Bootstrap.groovy to read configuration from table and update Configuration using above method.

    There is a grails plugin “Dynamic Config” for this purpose making your life easier.

    Here is the link : http://www.grails.org/plugin/dynamic-config

    Hope it helps you. :)

    Reply
  4. Parag

    Hello Bhagwat Sir,
    If My configuration stored in table in database . How can apply this configuration dynamically to config file (i.e. Application)

    Suppose , in Config file , i have grails.mail.host=”test.smtp.com” and in table i have text “test2.smtp.com”. Then how can i overrite table property in config file. Please Guide me..!!!

    Thanking You…

    Reply
  5. Igor E. Poteryaev

    Hello. Try this one-liner:

    ConfigurationHelper.initConfig(grailsApplication.config)

    (You can override classloader if needed)

    Reply
  6. Lucas Teixeira

    Hello, great post!

    I was looking into this kind of stuff in a past months, and found the reload-confit grails plugin. It is a great one, and even give us auto reloading of configuration files when they changed – automatically.

    Keep up the good work on intelligrape!

    Reply

Leave a comment -