In Grails 2, we had the following block of code in our Config.groovy file. The ConfigurationManagement class did a runtime lookup in a Configuration Management Database to determine if the quartz.autoStartup parameter should be true or false. We also used similar configuration to load additional Quartz properties.
quartz {
def autoStartupOnTheseServers = ConfigurationManagement.getValue("myApp.quartz.autoStartupOnTheseServers", "").split(",")
if ( autoStartupOnTheseServers.any { it.trim().toUpperCase() == hostName.toUpperCase() } ) {
autoStartup = true
}
else {
autoStartup = false
}
// Default for clustering (jdbcStore) has to be "false" so the app will run locally.
// Clustering (jdbcStore) will be true for DEV, TEST, QA, and PROD (set by Configuartion Management).
jdbcStore = ConfigurationManagement.getValue("myApp.quartz.jdbcStore", "false").toBoolean()
// don't set the props if not enabling quartz clustering...causes an exception.
if(jdbcStore == true) { props(quartzProps) }
}
In Grails 3, similar code used in application.groovy doesn't work and there isn't any facility for conditionals that I can find for application.yml. Is there any way in Grails 3 to do a similar dynamic configuration?
In Grails 3, it seems that you can't set these values directly, but you can declare a local variable and use that to set the property. So, for my example above, the following works:
def extServerList = ConfigurationManagement.getValue("myApp.quartz.autoStartupOnTheseServers", "").split(",")
def extAutoStartup = extServerList.any { it.trim().toUpperCase() == hostName.toUpperCase() }
def extJdbcStore = ConfigurationManagement.getValue("myApp.quartz.jdbcStore", "false").toBoolean()
quartz {
autoStartupOnTheseServers = extServerList
autoStartup = extAutoStartup
jdbcStore = extJdbcStore
}
Related
I have some keys that i want to keep in the config file. I have two different keys, one for use in development setting and another for use when the environment is set to production. Now, in grails we extract these property values from config file using
grailsApplication.config.[name of the property in config file]
is it possible to have conditional setting on config file that will return the right key depending on whether the environment is set to production or development? I appreciate any help! Thanks!
We use the approach of separate external config files for different environments and then include them in "config.groovy" depending on the environments like below
environments {
test {
grails.logging.jul.usebridge = true
grails.config.locations = ["file:${userHome}/.grails/${appName}-config-TEST.groovy"]
}
development {
grails.logging.jul.usebridge = true
grails.config.locations = ["file:${userHome}/.grails/${appName}-config-DEV.groovy"]
}
production {
grails.logging.jul.usebridge = false
grails.config.locations = ["file:${userHome}/.grails/${appName}-config-PROD.groovy"]
}
}
But if you want common file for all the environments then you can use the "Environment" available in "grails.util" package like below
package asia.grails.myexample
import grails.util.Environment
class SomeController {
def someAction() {
if (Environment.current == Environment.DEVELOPMENT) {
// insert Development environment specific key here
} else
if (Environment.current == Environment.TEST) {
// insert Test environment specific key here
} else
if (Environment.current == Environment.PRODUCTION) {
// insert Production environment specific key here
}
render "Environment is ${Environment.current}"
}
}
I am using jms to send messages between two apps, here is the code for receiver app
xmlns amq:"http://activemq.apache.org/schema/core"
amq.'broker'(
useJmx: '${grails.jms.useJmx}',
persistent:'${grails.jms.persistent}',
dataDirectory: '${grails.jms.dataDirectory}'){
amq.'transportConnectors'{
amq.'transportConnector'(uri:'${grails.jms.transportConnector}')
}
}
amqConnectionFactory(ActiveMQConnectionFactory) {
brokerURL = '${grails.jms.brokerUrl}'
}
jmsConnectionFactory(SingleConnectionFactory) { bean ->
targetConnectionFactory = ref(amqConnectionFactory)
}
I am able to run the app but getting error like
"Store limit is 102400 mb, whilst the data directory: /my-activemq-data/localhost/KahaDB only has 7438 mb of usable space" in console. I just want to configure the temp memory usage, can anyone help me on this. thanks
Are you using the https://grails.org/plugin/activemq plugin?
If so, I added precisely that functionality to the plugin.
The plugin allows the following configuration options (just put them in your Config.groovy):
grails.activemq.active = (true|false) default to true
grails.activemq.useJms = (true|false) default to false
grails.activemq.startBroker = (true|false) default to true
grails.activemq.brokerId = (string) default to "brokerId"
grails.activemq.brokerName = (string) default to "localhost"
grails.activemq.persistent = (true|false) default to false
grails.activemq.port = (int) default to 61616
grails.activemq.tempUsageLimit = (size in bytes) defaults to 64Mb
grails.activemq.storeUsageLimit = (size in bytes) defaults to 64Mb
If you aren't using the plugin maybe you should :)
For reference, this is the resources.groovy file I use for most projects (which rely on an application server jndi based JMS service for test and production and use activemq for development):
import grails.util.Environment
import org.apache.activemq.ActiveMQConnectionFactory
import org.springframework.jms.connection.SingleConnectionFactory
import org.springframework.jndi.JndiObjectFactoryBean
beans = {
switch(Environment.current) {
case Environment.PRODUCTION:
case Environment.TEST:
jmsConnectionFactory(JndiObjectFactoryBean) {
jndiName = "java:/ConnectionFactory"
}
break
case Environment.DEVELOPMENT:
jmsConnectionFactory(SingleConnectionFactory) {
targetConnectionFactory = { ActiveMQConnectionFactory cf ->
brokerURL = 'vm://localhost'
}
}
break
}
}
I had the same problem as you while using ActiveMQ with the activemq plugin, so I made a pull request adding those configuration options and setting them to a more reasonable default (for development) of 64Mb.
If you use the plugin you just need to add it to your BuildConfig plugins section, and it should work ok without further configuration, just the resources.groovy inside config/spring.
Anyway, the options I described should go into Config.groovy if you need any of them.
Finally, I got solution to my problem. here is the updated resource.groovy
activeMQTempUsage(TempUsage) {
activeMQTempUsage.limit = 1024 * 1024 * 1024
}
activeMQStoreUsage(StoreUsage) {
activeMQStoreUsage.limit = 1024 * 1024 * 1024
}
activeMQSystemUsage(SystemUsage){
activeMQSystemUsage.tempUsage = ref('activeMQTempUsage')
activeMQSystemUsage.storeUsage = ref('activeMQStoreUsage')
}
tcpConnector(TransportConnector,uri:'tcp://localhost:61616') {
}
connectors(ArrayList,[ref('tcpConnector')]){
}
myBrokerService(XBeanBrokerService){bean->
myBrokerService.useJmx = false
myBrokerService.persistent = true
myBrokerService.dataDirectory = 'my-activemq-data'
myBrokerService.systemUsage = ref('activeMQSystemUsage')
myBrokerService.transportConnectors = ref('connectors')
}
amqConnectionFactory(ActiveMQConnectionFactory) {
brokerURL = 'vm://localhost'
}
jmsConnectionFactory(SingleConnectionFactory) { bean ->
targetConnectionFactory = ref(amqConnectionFactory)
}
Using XbeanBrokerService properties we can achieve this, if you we want add more configuration we can add by using properties of XbeanBrokerService as like above.
I know that, at some point between Grails 1.X and Grails 2.X, the default connection pooling library changed from commons-dbcp to tomcat-dbcp.
Now, I'm trying to configure either BoneCP or HikariCP as the connection pooling library for my Grails application.
However, I see that this answer offers a solution which might only apply to Grails 1.X.
I also found this Gist, but again, I don't know which Grails version it applies to.
So, is it possible to define a custom connection pool inside a Grails 2.3.6 application? Thanks!
UPDATE: OK so you actually need to tell Grails not to pool the datasources, since HikariCP is now taking care of this.
I saw connection weirdness in my apps if I left that switch on. So instead say:
pooled = false
OK yeah, #Joshua Moore is right.
I tried doing it with updated Grails methods and this is the relevant section of my resources.groovy file. As far as I can understand, the configuration values in Datasource.groovy are pulled into resources.groovy at runtime, after the target runtime environment has been identified (development, test or production).
def config = Holders.config
def dataSources = config.findAll {
it.key.toString().contains("dataSource_")
}
dataSources.each { key, value ->
def ds = value
"${key}"(HikariDataSource, { bean ->
def hp = new Properties()
hp.username = ds.username
hp.password = ds.password
hp.connectionTimeout = 6000
hp.maximumPoolSize = 60
hp.jdbcUrl = ds.url
hp.driverClassName = ds.driverClassName
HikariConfig hc = new HikariConfig(hp)
bean.constructorArgs = [hc]
})
}
And this is the relevant section of my DataSource.groovy configuration:
// environment specific settings
environments {
development {
dataSource_myapp1 {
pooled = false
username = "CONFIGURE_ME_EXTERNALLY"
password = "CONFIGURE_ME_EXTERNALLY"
driverClassName = 'oracle.jdbc.OracleDriver'
dialect = 'org.hibernate.dialect.Oracle10gDialect'
url = 'jdbc:oracle:thin:#MYDBHOST1:1521/MYSERVICEID1'
}
dataSource_myApp2 {
pooled = false
username = "CONFIGURE_ME_EXTERNALLY"
password = "CONFIGURE_ME_EXTERNALLY"
driverClassName = 'oracle.jdbc.OracleDriver'
dialect = 'org.hibernate.dialect.Oracle10gDialect'
url = 'jdbc:oracle:thin:#MYDBHOST2:1521/MYSERVICEID2'
}
}
}
In my case, it's pretty much the same for test and production environments. Thanks!
I have a situation. I want to set one value to some parameter in Config.groovy in my Grails project. This parameter should have different value for each environment, i.e. for dev environment it is like abc = "devValue", for test environment like abc="testValue" and for production environment like abc="prodValue". and then I want to set that value as a hidden field value on gsp page according to running environment.
There's already an example of this in the Config.groovy that's generated for you:
environments {
development {
grails.logging.jul.usebridge = true
}
production {
grails.logging.jul.usebridge = false
}
}
so you can just add your setting there:
environments {
development {
grails.logging.jul.usebridge = true
abc = "devValue"
}
test {
abc = "testValue"
}
production {
grails.logging.jul.usebridge = false
abc = "prodValue"
}
}
Thanks Igor Artamonov,
I found the solution below.
I added code below in Config.groovy
environments {
development {
abc="devValue"
}
test {
abc="testValue"
}
production {
abc="prodValue"
}
}
And then in gsp i set the hidden field as below.
<input id="oid" type="hidden" name="oid" value="${grailsApplication.config.abc}">
Thank you.
Using the Grails OAuth plugin requires that an absolute callback URL be provided in Config.groovy. However I have different serverURLs for each environment.
Is there a way to get the current environment from inside Config.groovy, here's an example of what I want to do:
def devServerUrl = 'http://dev.example.com'
def prodServerUrl = 'http://prod.example.com'
def currentServerUrl = grailsApplication.metadata.environment == 'development' ? devServerUrl : prodServerUrl;
environments {
development {
grails {
serverURL = devServerUrl
}
}
production {
grails {
serverURL = prodServerUrl
}
}
}
oauth {
providers {
runkeeper {
api = RunKeeperApi
key = 'key'
secret = 'secret'
callback = currentServerUrl + '/oauth/runkeeper/callback'
}
}
}
Any ideas? Thanks!
Try this:
def currentServerUrl = Environment.current.name == 'development' ? devServerUrl : prodServerUrl;
I think it is cleaner to set different grails.serverURL for each environment and then do:
callback = "${grails.serverURL}/oauth/runkeeper/callback"