how to set hikari connection properties in datasource.groovy - grails

In springboot2.X i am able to set hikari connection pool config like maxLifeTime in application.ymal easily.
Similarly i want to to it in groovy. Is it inside dBProperties?
i am using groovy 2.5.4 and grails 2.4.4
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/my_database"
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = "username"
password = "password"
type = "com.zaxxer.hikari.HikariDataSource"
properties {
....
....
dbProperties {
maxLifeTime=200000
}
}
}

You can add it as bean in conf/spring/resources.groovy
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import grails.util.Holders
// Place your Spring DSL code here
beans = {
dataSource(HikariDataSource) { bean ->
def ds = Holders.config.dataSource
def hp = new Properties()
hp.username = ds.username
hp.password = ds.password
hp.jdbcUrl = ds.url
hp.driverClassName = ds.driverClassName
hp.connectionTimeout = ds.hikariConnectionTimeout
hp.maximumPoolSize = ds.hikariMaximumPoolSize
hp.maxLifetime = ds.hikariMaxLifetime
hp.idleTimeout = ds.hikariIdleTimeout
hp.minimumIdle = ds.hikariMinimumIdle
hp.connectionTestQuery = "SELECT 1"
HikariConfig hc = new HikariConfig(hp)
bean.constructorArgs = [hc]
}
}
With these added you can define your properties in your Datasoure.groovy like this
dataSource {
dbCreate = "update"
url = "jdbc:postgresql://localhost:5432/db"
username = "username"
password = "password"
hikariMinimumIdle = 5
hikariMaximumPoolSize = 30
hikariIdleTimeout = 600000
hikariConnectionTimeout = 30000
hikariMaxLifetime = 1800000
}

Related

How to replace Servlet Filters already defined (replacing legacy doWithWebDescriptor with doWithSpring)

I'm trying to upgrade a Grails plugin from version 2.3.4 to 4.0.11. It uses a syntax that is no longer supported to replace filters with names sitemesh and urlMapping with its own filters.
The code below uses a DSL for xml. It replaces xml nodes in the final generated web.xml.
def doWithWebDescriptor = { xml ->
def pageFilter = xml.filter.find { it.'filter-name'.text() == 'sitemesh' }
def urlMappingFilter = xml.filter.find { it.'filter-name'.text() == 'urlMapping' }
def grailsVersion = GrailsUtil.grailsVersion
// Grails 1.3.x & Grails 2.0.x
def pageFilterClass = "org.zkoss.zk.grails.web.ZKGrailsPageFilter"
def urlMappingFilterClass = "org.zkoss.zk.grails.web.ZULUrlMappingsFilter"
if(grailsVersion.startsWith("2")) {
pageFilter.'filter-class'.replaceNode {
'filter-class'(pageFilterClass)
}
urlMappingFilter.'filter-class'.replaceNode {
'filter-class'(urlMappingFilterClass)
}
//
// Require a legacy config for servlet version
//
if(application.metadata.getServletVersion() >= '3.0') {
pageFilter.'filter-class' + {
'async-supported'('true')
}
urlMappingFilter.'filter-class' + {
'async-supported'('true')
}
}
} else {
pageFilter.'filter-class'.replaceBody(pageFilterClass)
urlMappingFilter.'filter-class'.replaceBody(urlMappingFilterClass)
}
}
What I tried so far
The code below uses Grails plugin configuration to register filters with spring's FilterRegistrationBean. I'm following Grails official documentation.
Closure doWithSpring() { { ->
boolean supportsAsync = this.grailsApplication.metadata.getServletVersion() >= "3.0"
pageFilter(FilterRegistrationBean) {
name = "sitemesh"
filter = bean(org.zkoss.zk.grails.web.ZKGrailsPageFilter)
urlPatterns = ["/*"]
order = Ordered.HIGHEST_PRECEDENCE
asyncSupported = supportsAsync
}
urlMappingFilter(FilterRegistrationBean) {
name = "urlMapping"
filter = bean(org.zkoss.zk.grails.web.ZULUrlMappingsFilter)
urlPatterns = ["/*"]
order = Ordered.HIGHEST_PRECEDENCE
asyncSupported = supportsAsync
}
}}
How can I replicate the legacy code with RegistrationBeans?
Also, I don't know if any of these filters got deprecated by Grails. I would like to know if there are any other replacements, if possible.
Here's the project in case anyone wants more context.
Debugging the older version of the plugin I came up with the following:
pageFilter(FilterRegistrationBean) {
name = "sitemesh"
filter = bean(ZKGrailsPageFilter)
urlPatterns = ["/*"]
order = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER + 50
asyncSupported = supportsAsync
dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR)
}
urlMappingFilter(FilterRegistrationBean) {
name = "urlMapping"
filter = bean(ZULUrlMappingsFilter)
urlPatterns = ["/*"]
order = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER + 60
asyncSupported = supportsAsync
dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD)
}
Added the dispatcherTypes and changed the order assuming these would be the last filters where the 'pageFilter' should be placed before the 'urlMappingFilter' in the filter chain.

How do I configure Jasypt to use a ZeroSaltGenerator?

I'm using Grails 1.3.7 with Jasypt and I have the below in my Config.groovy:
jasypt {
algorithm = "PBEWithMD5AndTripleDES"
password = "password"
keyObtentionIterations = 1
saltSizeBytes = 0
}
How can I set the salt property to ZeroSaltGenerator?
In Config.groovy, change your config for jasypt to:
jasypt {
algorithm = "PBEWithMD5AndTripleDES"
password = "password"
keyObtentionIterations = 1
saltGenerator = new org.jasypt.salt.ZeroSaltGenerator()
}
If you want to use ZeroSaltGenerator then you have to make following changes:
Inside your config.groovy:
jasypt {
encryptorRegisteredName = "gormEncryptor"
}
And in your resources.groovy:
beans = {
hibernateStringEncryptor(HibernatePBEStringEncryptor) {
registeredName = "gormEncryptor"
algorithm = "PBEWithMD5AndTripleDES"
password = "password"
keyObtentionIterations = 1
saltGenerator = new org.jasypt.salt.ZeroSaltGenerator()
}
}
And it will generate the same encrypted values everytime.

How to properly remove H2 from Grails

I am trying to minimalize my Grails (2.4.2) app and cull out a lot of stuff that create-app generates that I'm just not going to use.
One of these things is H2. I'm just not going to use it, and besides, if I needed an embedded DB, I'd prefer to use HSQLDB.
So I made the following changes to my BuildConfig:
...
// Remove the DB console for all environments, not just dev.
grails.dbconsole.enabled = false
...
grails.project.dependency.resolution = {
inherits("global") {
excludes 'h2'
}
...
}
Now, when I do a run-app, I get the following error:
... <huge stacktrace omitted for brevity>
Caused by: org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: org.h2.Driver
... 4 more
Caused by: java.sql.SQLException: org.h2.Driver
... 4 more
Caused by: java.lang.ClassNotFoundException: org.h2.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.Class.forName(Class.java:270)
... 4 more
Error |
Forked Grails VM exited with error
What's going on and how do I fix this error while properly removing H2 and any of its configs/references?
Update, my DataSources.groovy file
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = false
// cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
singleSession = true // configure OSIV singleSession mode
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
properties {
// See http://grails.org/doc/latest/guide/conf.html#dataSource for documentation
jmxEnabled = true
initialSize = 5
maxActive = 50
minIdle = 5
maxIdle = 25
maxWait = 10000
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
testOnBorrow = true
testWhileIdle = true
testOnReturn = false
jdbcInterceptors = "ConnectionState"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
}
}
}
In your grails-app/conf/DataSources.groovy you probably have some references to the h2 Driver, e.g.
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
Remove the dataSource configuration completely if you're not using any DB. If you're using a different DB, replace the h2 driver class name with the class name of the driver for your DB.

How do you use environment variables inside of Config.groovy

Inside of Config.groovy i have setup a few environment variables:
def appName = grails.util.Metadata.current.getApplicationName()
def casUrl = "https://login.cas.server/cas"
environments {
development {
grails.logging.jul.usebridge = true
host.address = "12.34.56.78"
host.port = "8080"
}
test {
grails.logging.jul.usebridge = true
host.address = "http://staging.server.somewhere.com/"
host.port = ""
}
production {
grails.logging.jul.usebridge = false
host.address = "http://www.production.com"
host.port = ""
}
}
I'm trying to use those values inside the same configuration file (Config.groovy) like so:
grails.plugin.springsecurity.cas.loginUri = '/login'
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.cas.serverUrlPrefix = '${casUrl}'
grails.plugin.springsecurity.cas.proxyCallbackUrl = "/secure/receptor"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
However, the only thing that is getting resolved is the appName variable, everything else is null. Is this something that can be done? It looks like it was used in this post here Grails: Spring Security CAS Working in 2.2.3 but I cant seem to get them to resolve.
If I do something like
def appName = grails.util.Metadata.current.getApplicationName()
def casUrl = "https://login.umt.edu/cas"
host.address = "MyAddress"
environments {
...
The configSlurper resolves that host.address inside the CAS config, why can't I access the enviornment variables?
See the answer here under Basic Configuration.
However, you can't nest after using the dot notation. In other words, this won't work
// Won't work!
foo.bar {
hello = "world"
good = "bye"
}
So try to use nesting like this
foo {
bar {
hello = "world"
good = "bye"
}
}
Move the properties that depend on host.address and host.port inside each environment block:
environments {
development {
grails.logging.jul.usebridge = true
host.address = "12.34.56.78"
host.port = "8080"
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
}
test {
grails.logging.jul.usebridge = true
host.address = "http://staging.server.somewhere.com/"
host.port = ""
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
}
production {
grails.logging.jul.usebridge = false
host.address = "http://www.production.com"
host.port = ""
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
}
}
You can get rid of the host.address and host.port variables altogether:
environments {
development {
grails.logging.jul.usebridge = true
grails.plugin.springsecurity.cas.serviceUrl = "http://12.34.56.78:8080/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=http://12.34.56.78:8080/${appName}/"
}
test {
grails.logging.jul.usebridge = true
grails.plugin.springsecurity.cas.serviceUrl = "http://staging.server.somewhere.com/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=http://staging.server.somewhere.com/${appName}/"
}
production {
grails.logging.jul.usebridge = false
grails.plugin.springsecurity.cas.serviceUrl = "http://www.production.com/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=http://www.production.com/${appName}/"
}
}

Datasource avanced properties

I just wondering is this is a valid DataSource configuration:
development {
properties {
maxActive = 50
maxIdle = 25
minIdle = 5
initialSize = 8
minEvictableIdleTimeMillis = 1000 * 15 * 60
timeBetweenEvictionRunsMillis = 1000 * 15 * 60
maxWait = 10000
validationQuery = "/* ping */"
}
dataSource {
username = "test"
password = "test"
dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:mysql://params"
}
}
If i have this, do the dataSource use the properties listed above?
If you want to centralize your properties, you can define the datasource without an enviornment first:
dataSource {
properties {
}
}
development {
dataSource {
}
}
properties is part of the datasource bean (of type BasicDataSource). Using DSL makes it easier not to use the accessor methods explicitly to set/get the members.
So I think you have to stick to
development{
dataSource{
......
properties{
.......
}
}
}

Resources