Grails external configuration (datasource) with multiple environments - grails

In my Config.groovy i put line:
grails.config.locations = [ "classpath:app-config.properties"]
where I set definition for datasource. File looks like:
dataSource.url=jdbc:mysql://host/instance
dataSource.username=u
dataSource.password=p
and it properly replace properties from DataSource.groovy.
Problem is that it replace configuration for every environment, but i need separate config for dev, test and production. Trying to put into file different entries like:
environments.development.dataSource.url=jdbc:mysql://host/dev
...
environments.production.dataSource.url=jdbc:mysql://host/prod
...
ends with default data sources properties defined in DataSource.groovy. How to make one property file to work with different environments?

There are several possible approaches. Here are a couple:
Embed the current environment name in your external config file name:
grails.config.locations = [
"classpath:app-${grails.util.Environment.current.name}-config.properties"]
This will cause app-development-config.properties to be loaded in dev mode, app-test-config.properties in test, etc.
Use the .groovy config format instead of .properties. With a .groovy config file, you can use the environment { ... } block.

Related

Bazel - How to Read a String from An Environment File?

I have several k8s_object rules in my project and I supply each of them with the same cluster name like this:
k8s_object(
name = "k8s_service",
kind = "service",
cluster = "gke_cents-ideas_europe-west3-b_cents-ideas",
template = ":gateway.service.yaml",
)
So whenever I want to change the cluster name, I have to change it in many different places.
Goal
I would prefer to set the cluster name in a .env file like this:
KUBERNETES_CLUSTER=my-cluster-name
and let Bazel automatically pick up this value.
https://docs.bazel.build/versions/2.0.0/skylark/tutorial-sharing-variables.html
Create a .bzl file in which you can declare a variable. Import this bzl file in all BUILD files referencing the variable.

In DropWizard, can we have a default YAML configuration file?

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.

Share config between two grails apps that share a common plugin

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.

Getting values from a config file or environment variable in meteor

This would be very useful for storing API keys or other sensitive information. From what I understand, you can use config files locally but they won't work on meteor.com, but I heard a rumor that environment variables were soon to be supported, or are already as of a recent release, but I can't find any examples.
Can someone provide an example of how to retrieve a value from an environment variable or some other safe location?
You can actually access the process object to retrieve environment variables in Meteor. In essence, just do the same as in this solution
After some thought, storing them all in a .js file inside an object literal, adding that file to the .gitignore, and checking in a corresponding .js.sample file with dummy or blank values would do the trick.
There's a much better way to handle environment variables. If you come from Ruby on Rails you're used to setting your environment variables in your .ENV file or in your config/application.yml file.
Meteor handles environment variables in a similar way.
Create settings.json file
Inside your server folder in your project, create a file and name it settings.json. Add this file to your gitignore file.
Inside this JSON file, you can save any environment variables you need.
{
"facebookAppId": "6666667527666666",
"facebookAppSecret": "00004b20dd845637777321cd3c750000",
"amazonS3Bucket": "bucket-name"
}
Loading the environment variables
To use these values inside your app during runtime, start Meteor with a --settings option flag.
$ meteor run --settings server/settings.json
Use the values
To use the values, just call the Meteor.settings object.
ServiceConfiguration.configurations.upsert(
{ service: "facebook" },
{
$set: {
appId: Meteor.settings.facebookAppId,
secret: Meteor.settings.facebookAppSecret
}
}
);
That's all there is to it! Keep your settings safe, and do not commit your keys.

Converting Java -> Grails ... How do I load these properties?

I'm converting a Java web app to Grails (1.2.1). In my Java app, I have a singleton that loads properties from a ".properties" file. I've seen I can put that loading into the "Config.groovy" conf file. If my properties are loaded in Config.groovy, how do I load them in my Java file? Here is how I'm doing it when the Config was loaded in java ...
Long interval = ConfigSingleton.getInstance().getGlobalCacheRefreshInterval();
Thanks, - Dave
Adapted from the Grails User Guide:
You can add your own configuration in grails-app/conf/Config.groovy, for example:
globalCacheRefreshInterval = 120
Then later in your application you can access these settings in one of two ways. The most common is via the GrailsApplication object, which is available as a variable in controllers and tag libraries:
Long interval = grailsApplication.config.globalCacheRefreshInterval
The other way involves getting a reference to the ConfigurationHolder class that holds a reference to the configuration object:
def config = org.codehaus.groovy.grails.commons.ConfigurationHolder.config
Long interval = config.globalCacheRefreshInterval
If you want to acess this configuration from a Java class, you can use:
import org.codehaus.groovy.grails.commons.ConfigurationHolder;
...
Map config = ConfigurationHolder.getFlatConfig();
Long interval = (Long) config.get("globalCacheRefreshInterval");
Attention for the correct type in your Config.groovy. In the case above, your configuration property must be defined as a Long:
globalCacheRefreshInterval = 120L
You should also checkout the ConfigSlurper class (this is what grails uses to load its config file).
Dave if what you need is to load the properties file as it is without having to move them to the Config.groovy manually, you can the following inside the Config.groovy file:
grails.config.locations = [
"file:" + "/pathWhereFileLives/fileName.properties"
]
This will load all the properties you have in the file in the Grails configuration class. Something to be aware of is that if you have a property in the Config.groovy and the properties file with the same name, the one from the properties file will override the value of the one from Config.groovy
You can find more information about the Grails external configurations here.

Resources