grails properties - grails

I am having some big troubles using external properties with grails.
In config.groovy I have:
grails.config.locations = ["file:grails-app/conf/config.properties"]
this is my config.properties file:
test.prop.test=this is a test
and this is in my code:
println grailsApplication.config["test.prop.test"]
Has anyone any idea why this does not work?

If you want to access the config options using single string keys that include dots, as opposed to the multi-level grailsApplication.config.test.prop.test then you need to use flatConfig instead:
grailsApplication.flatConfig["test.prop.test"]

in external config
this.is.myname="My name is Hello!"
in your controller
import org.codehaus.groovy.grails.commons.ConfigurationHolder
String name= ConfigurationHolder.config.this.is.myname;
this is work for me...with using grails 2.1.1

Related

How to Modify Grails 5 Configuration by Adding Groovy Files

I have a large number of Grails 2.5 applications that I want to upgrade to Grails 5, but have been unable to get the configuration to work. In particular, I want my plugin to set up the data source and Spring Security configuration as it did in Grails 2.5.
In my Grails 2.5 applications, I was able to add files to the configuration by adding this code to the top of Config.groovy.
if (!grails.config.location || !(grails.config.location instanceof List)) {
grails.config.location = []
}
grails.config.location << ["classpath:jcc-server-config.properties"]
grails.config.location << ["classpath:SecurityConfig.groovy"]
But this doesn't work in Grails 5. I've tried adding an application.groovy file, but everything defined in the application.yml seems to be set in stone. Has anybody found a way to add a Groovy file to the Grails configuration that will override or add to the settings in application.yml? YAML will not do because I have logic embedded in the configuration to make it work correctly in different environments.
Thanks.
Did you remember to include the external-config dependency? i.e.
implementation 'dk.glasius:external-config:3.0.0'
Re' your question on accessing config values this way, there should be no difference, in my apps I get to the config either via grailsApplication.config, or if grailsApplication isn't immediately available(e.g. classes under src), then with Holders, i.e. Holders.grailsApplication.config.

Reading Grails configs from groovy

I just tried to read a grails config from groovy. The ConfigSlurper is easy to use, but since it executes the config, it needs all dependencies in place. In my case, it complains about a missing log4j class.
Even when I import this class into my ConfigSlurper script, the config itself runs into this problem.
Any Idea how I could make the log4j classes accessible to the config?
Update: now that I have a proper keyboard in front of me, I can elaborate on my problem:
I have grails configurations which configure log4j as described in the docs:
import org.apache.log4j.*
log4j = {
appenders {
appender new RollingFileAppender(
name: "myAppender",
maxFileSize: 1024,
file: "/tmp/logs/myApp.log"
)
}
}
Then I tried to parse them like this:
def file = new File(<config location>)
def config = new ConfigSlurper().parse(file.toURL())
and the Slurper threw an exception...
I've found two solutions:
First, the documents show a way how to configure a rollingFileAppender without instantiating one: http://grails.org/doc/2.3.7/guide/conf.html .
Second, I managed to fix my original problem with a
#Grab('log4j:log4j:')
in front of my script - not a good solution if you are behind a firewall...
As Jeff already stated, it should also be possible to put the right jar file in the classpath, but I have to say that I often struggle with the cp :-( and when I tried to put the log4j.jar in the .groovy folder, I didn't succeed - but I guess this was because of an inproper groovy installation.

Add logging to an external pluggable script

As described in Can't call one closure from another, I am using a pluggable script from within a Grails app.
Unfortunately, I've found that I can't use log4j from within these scripts. I am forced to use println.
I tried using
import org.apache.commons.logging.LogFactory
def Log log = LogFactory.getLog(getClass())
but I got no output. When I print out the result of the call to getClass(), I get something like
myscript$_run_closure5
So I'm thinking the issue is that there is no configuration in my Grails Config.groovy file for this class.
Is there a way for me to programmatically add these pluggable scripts to the log4j configuration? Keep in mind that I do not know in advance what the names of the scripts are, so this has to happen at runtime.
Consider the following code:
import org.apache.log4j.Logger
// ...
Logger log = Logger.getLogger('MyPlugin')
new File( grailsApplication.config.externalFiles ).eachFile { file ->
Binding binding = new Binding()
binding.variables.log = log
GroovyShell shell = new GroovyShell(binding)
shell.evaluate(file)
strategies.put( binding.variables.key, binding.variables )
}
Explanation:
It is not obligatory to pass class name to getLogger, it can be actually any string. You just need to make sure that this string is matched in log4j.properties of the main program.
You pass once created log to plugin scripts via binding variable "log". Then plugin scripts can access it simply as log.info('test123')
My personal recommendation would be to use logback instead of log4j. Both libraries were developed by the same guy and it is stated that logback supersedes log4j.

How to use an external service as a source for Grails app configuration?

Section 3.4 of Grails documentation says that Grails app can be configured from an external source:
grails.config.locations = [
"classpath:${appName}-config.properties",
"classpath:${appName}-config.groovy",
"file:${userHome}/.grails/${appName}-config.properties",
"file:${userHome}/.grails/${appName}-config.groovy" ]
Also, it is possible to load config by specifying a class that is a config script:
grails.config.locations = [com.my.app.MyConfig]
My questions are:
Could you please give an example of how MyConfig class implementation could look like? It is not quite clear from the documentation.
If I want to use some external JSON REST service as a source for my config data, how can this be implemented?
Answer for second question: you can do that in BootStrap.groovy init closure, because basically, it allows you to execute any code:
// Inject grails app
def grailsApplication
def init = { servletContext ->
def externalValue = getItUsingRest(someUrl)
grailsApplication.config.my.custom.var = externalValue
}
Depending on version of grails you are using, you might need to use
org.codehaus.groovy.grails.commons.ConfigurationHolde.config
to get to config instead.
Your application configuration can actually be a Groovy script. So any class which looks like your Config.groovy can act as a configuration class. In our projects we tend to keep the configuration outside the grails application so that the application can be configured without recompiling everything.
Maybe this post of mine will give you a hint on how to use and load external configuration files.

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