I'd like to store properties in a database tables and have defaults for those properties set in Config.groovy. For example, I want to put a default email address into Config.groovy:
app.send.report.to = 'me#example.com'
and then be able to override this in a database table (key, value columns...).
Is there a plugin (or functionality inside grails) to do this?
There is Dynamic Config Plugin.
It stores config property in ConfigProperty domain and merges properties from Config.groovy and from database using:
grailsApplication.config.merge(configObject)
You may want to look at the plugin source code. If plugin does not work for you, you can implement something similar to this.
This approach is useful when you have UI for editing config properties.
Grails does not have functionality that I'm aware of to override configuration values from a database, but it shouldn't be that difficult to do. In your Config.groovy you could put the defaults, and then as part of your bootstrap process, you could generate a temporary config file that has the values from the database (a simple query and iteration over the results could be used to generate that temp file). Include that temp file as one of your grails config locations, and it will override any values that are in the Config.groovy
If your goal is to have a shared configuration file that is used by multiple grails apps, you might also look into using something like Zookeeper to manage the shared configuration, but that may be a bit overkill for a single config file.
Not quite what you're asking for, but depending on what you want to achieve the External Configuration Reload plugin might be of use. It helps you to override default properties (in runtime), but not by using the DB.
Related
There are some properties that I have in the default generated application.yml file in Grails 3. Take for example this property
test:
network:
path: '/home/cool/testing_data'
Now, the part that I want to do is change this property when I invoke the build script, so that it is different for the various OS that it might be executed on. I.e: On windows, that path should be 'E:/shared/testing_data', and on solaris, something different.
Using this post here, I can conclude that I can identify which OS I am currently on, so that I can potentially make some changes. Ex:
import org.apache.tools.ant.taskdefs.condition.Os
task checkWin() << {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// it is windows, lets change the path to not be linux like
}
}
So my question is, using gradle or any other means as necessary, can I change the properties in application.yml file to accommodate the different OS systems that the application might be deployed on? I am considering reading the application.yml file line by line and doing a string replacement, but I will resort to this only if there are no cleaner solutions.
Maybe am I using the wrong tool to solve this problem as is, so a good question to ask is, is there an easier way that I am missing here, possibly a similar approach to different "environments" like :test, dev, prod, for operating systems, already built into the core functionality of grails that I can re-use?
Just create application.groovy file in the same folder as application.yml is. In groovy file you can use any script to set value of properties.
For example add this line to application.groovy file (also remove option from yml):
test.network.path = Os.isFamily(Os.FAMILY_WINDOWS) ? 'd:\something' : '/home/something'
We are using DropWizard v0.8.1 and we're wondering if we can have a YAML files with default values that will then get overridden by the specific environment file (such as dev.xml).
Spring boot works this way, where the application.yml file act as a template for default values and then application-dev.yml will override duplicate properties.
We don't want to duplicate all the repetitive properties and only want to update in one file the defaults.
You can write your own ConfigurationProvider that combines 2 InputStreams and use yaml merge directives
You can use a configuration management tool, such as Ansible, to manage your configurations files.
Set up a template .yml file, and substitute the variables per environment as needed.
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?
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).
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.
I'm wiring grails plugin. During _Install I would like to append the part of my plugin'sConfig.groovy. The block I'd like to cut and append starts with
// **** PLUGINSTART
and ends with
// **** PLUGINEND
Curently I'm using ant.copy and completely replace the Config.groovy with my plugin's Config.groovy. How to append only this part?
Have a look at Externalized Configuration, particularly the line:
"This can be useful in situations where the config is either coming from a plugin or some other part of your application. A typical use
for this is re-using configuration provided by plugins across multiple
applications."
How do I set the batch size for Nhibernate? I'd like to do this in the web.config. The examples I see, don't make a lot of sense to me.
In this example they are using code to set the batch size. I don't wnat to do that. I want it configurable in the web.config.
I understand how to add the config section, I just have read articles that differ on how to set this batch size. Most of them show batch size being set in code, and the ones that show it in the config use different names, or an appsettings key. Confusing.
When I add the config section into my web.config do I need to do anything special when creating the session or will nhibernate pick up the settings automatically?
in case anyone is wondering, I ended up just resorting to setting it up in my fluentnhibernate session factory.
Fluently.Configure().Database(
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
.ConnectionString(c => c.FromConnectionStringWithKey("MyDatabase"))
.AdoNetBatchSize(20)
)
I also had to resort to using code to configure, though I only override the batch size parameter and otherwise use the Web.config settings as-is:
Configuration configuration = new Configuration();
configuration.SetProperty(Environment.BatchSize, "0");