This is quite annoying. Fortunately Grails expose different way to solve this problem.
First of all have a look at the documentation: http://grails.org/doc/latest/guide/conf.html#configExternalized
There is only something that doesn't work for me: they say it is possible to perform change without restarting the app but that's not my case, i had always to restart the app.
So, let's have a look at the important code section:
grails.config.locations = [ "classpath:${appName}-config.properties", "classpath:${appName}-config.groovy", "file:${userHome}/.grails/${appName}-config.properties", "file:${userHome}/.grails/${appName}-config.groovy" ]Here you can specify two different ways to get an external configuration file which is via classpath or via file.
If you want to put a file directly under the app root folder, simply use this kind of syntax:
file:configfile.groovy
But what if you want to read the file using an environment variable which specify the location of the file, so that you can have different environment configuration files without the need to know where the file is, as often happens in real world systems where developers doesn't know what is the production config file which is usually managed by an application manager?
Here is the solution:
if (System.getenv("TEST_CONF_GROOVY")) { grails.config.locations << "file:" + System.getenv("TEST_CONF_GROOVY") }
Here you are simply saying to Grails to use, if defined, an environment variable which is the path to your configuration file.
At this point you are able to specify external configuration file but what if you want to update configuration at runtime?
Here it is: you can specify a code section (i placed it inside a controller) which refresh the external configuration:
import grails.util.Environment def grailsApplication; def refreshConfig() { def files = grailsApplication.config.grails.config.locations files.each { fileName -> File configFile = new File(fileName.replace("file:", "")).absoluteFile try { ConfigSlurper configSlurper = new ConfigSlurper(Environment.getCurrent().getName()) ConfigObject updatedConfig updatedConfig = configSlurper.parse(configFile.text) grailsApplication.config.merge(updatedConfig) } catch (Throwable e) { log.error("Failed parsing and merging config file ${configFile} changes", e) } } }
It is super simple and this code is specific to groovy configurations and not properties file. It simply parse again any external file and merge the new configurations with the current one.
So you don't need anymore to restart or reload the server!
how can tomcat know "classpath:${appName}-config.groovy" location?
RispondiEliminai am trying "classpath:external-config.groovy"..i am using server linux..
All these configs go in Config.groovy so you are within the Grails App (so ${appName} is known) so tomcat is not involved in this question.
RispondiEliminaRemember, i'm running a Grails <=2.4 version where you have appName specified. In Grails 3, default appName has been removed