Share config between two grails apps that share a

2019-03-06 12:43发布

We will have two apps that both need to use the same services/utilities/code/configuration.

We are using grailsApplication.config.* to configure things like URLs to external services. These are different depending on whether the app is running in dev/test/qa/staging/prod, so we have used the environments section in Config.groovy. We'll need the same URLs/environments configured for both applications.

In order to avoid duplication, we are trying to build a plugin that will hold all the shared stuff. This works for services and such, but Grails plugins do not include Config.groovy, resources.groovy so all the URL configuration and such can't be put in Config.groovy in the plugin.

Is there a nice way to put that configuration in a single place and have it available for both apps?

Perhaps we could put it in some place in the plugin and "import" it into the Config.groovy of both apps?

2条回答
虎瘦雄心在
2楼-- · 2019-03-06 13:20

Given that you want to embed the configuration within the plugin you will need to make your plugin smart enough to read it's own configuration and merge that into the containing applications config. The following is based on Grails 1.3.7. The configuration holder may have changed since then (2.0 did a lot of house cleaning) but I am sure you can figure that part out. This example assumes that there is a configuration file called grails-app/conf/MyPluginConfig.groovy inside your plugin.

Inside your /MyPlugin.groovy you will add this merge of your configuration in the doWithSpring closure.

def doWithSpring = {
    // get the current application configuration
    def currentConfig = org.codehaus.groovy.grails.commons.ConfigurationHolder.config
    GroovyClassLoader classLoader = new GroovyClassLoader(getClass().classLoader)

    // get the plugin configuration
    def pluginConfig = new ConfigSlurper(grails.util.GrailsUtil.environment).parse(classLoader.loadClass('MyPluginConfig'))

    // merge the configurations
    pluginConfig.merge(currentConfig)

    // set the application configuration to the merged configuration
    org.codehaus.groovy.grails.commons.ConfigurationHolder.config = pluginConfig
}

That's it in a nutshell. Hope this helps.

Also, take note that you can still override the values in your containing application because of the way the merge is done. The application configuration is merged into the plugin configuration. If the containing application defines something it will override the plugins value.

查看更多
Viruses.
3楼-- · 2019-03-06 13:39

The grails.config.locations definition for external configuration files can include java.lang.Class objects to load configuration from pre-compiled Groovy scripts, as well as file: or classpath: URLs to parse Groovy or .properties files at runtime. So you should be able to create a configuration file in the plugin under src/groovy

{plugin}/src/groovy/com/example/CommonConfiguration.groovy

package com.example

environments {
  production {
    ...
  }
  development {
    ...
  }
}

and then in the applications' Config.groovy files include this class in grails.config.locations

grails.config.locations = [com.example.CommonConfiguration]

However this does mean that when the plugin's CommonConfiguration and the host app's Config.groovy both specify a value for the same property, the plugin would win. To redress the balance, you'd need to put a second external in grails.config.locations (which could be another Class or a URL)

grails.config.locations = [com.example.CommonConfiguration,
                           "file:app-config.groovy"]

and put app configuration in there (as later externals override earlier ones).

查看更多
登录 后发表回答