Datasource avanced properties - grails

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{
.......
}
}
}

Related

how to set hikari connection properties in datasource.groovy

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
}

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.

Where's located the declaration of messageSource in Grails?

Background
We have some legacy internationalization for field labels that are stored in the database, so I tried to make a "merged" messageSource. If the code exists in database, return, if not, use PluginAwareResourceBundleMessageSource to look in the i18n.
Problem
For some reason the cachedMergedPluginProperties is caching the wrong file for the locale. For example, if I search for en_US, I receive pt_BR messages (the key of the Map is en_US, but the properties are pt_BR).
I declared my messageSource as follows:
messageSource(DatabaseMessageSource) {
messageBundleMessageSource = { org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource m ->
basenames = "WEB-INF/grails-app/i18n/messages"
}
}
The inner bean is beacause of Grails won't let me have two beans of type MessageSource.
Am I declaring PluginAwareResourceBundleMessageSource different from the default of Grails? In which file of Grails I can see this bean declaration?
I found the declaration inside I18nGrailsPlugin, and it's a bit more detailed then mine:
String baseDir = "grails-app/i18n"
String version = GrailsUtil.getGrailsVersion()
String watchedResources = "file:./${baseDir}/**/*.properties".toString()
...
Set baseNames = []
def messageResources
if (application.warDeployed) {
messageResources = parentCtx?.getResources("**/WEB-INF/${baseDir}/**/*.properties")?.toList()
}
else {
messageResources = plugin.watchedResources
}
if (messageResources) {
for (resource in messageResources) {
// Extract the file path of the file's parent directory
// that comes after "grails-app/i18n".
String path
if (resource instanceof ContextResource) {
path = StringUtils.substringAfter(resource.pathWithinContext, baseDir)
}
else {
path = StringUtils.substringAfter(resource.path, baseDir)
}
// look for an underscore in the file name (not the full path)
String fileName = resource.filename
int firstUnderscore = fileName.indexOf('_')
if (firstUnderscore > 0) {
// grab everyting up to but not including
// the first underscore in the file name
int numberOfCharsToRemove = fileName.length() - firstUnderscore
int lastCharacterToRetain = -1 * (numberOfCharsToRemove + 1)
path = path[0..lastCharacterToRetain]
}
else {
// Lop off the extension - the "basenames" property in the
// message source cannot have entries with an extension.
path -= ".properties"
}
baseNames << "WEB-INF/" + baseDir + path
}
}
LOG.debug "Creating messageSource with basenames: $baseNames"
messageSource(PluginAwareResourceBundleMessageSource) {
basenames = baseNames.toArray()
fallbackToSystemLocale = false
pluginManager = manager
if (Environment.current.isReloadEnabled() || GrailsConfigUtils.isConfigTrue(application, GroovyPagesTemplateEngine.CONFIG_PROPERTY_GSP_ENABLE_RELOAD)) {
def cacheSecondsSetting = application?.flatConfig?.get('grails.i18n.cache.seconds')
if (cacheSecondsSetting != null) {
cacheSeconds = cacheSecondsSetting as Integer
} else {
cacheSeconds = 5
}
}
}
Since Grails don't let you have two beans of type MessageSource I had to copy this code and adapt to mine "merged" messageSource.

JdbcSQLException for a grails app with h2 database?

I'm getting a JdbcSQLException whenever I try to deploy my app to a server, though running locally works fine. I have no idea what this error is and can't seem to find the answer on google.
Code throwing the error:
class ResultService {
def recentStoryRuns() {
StoryRun.list(sort: "batch.dateCreated", order: "desc")
}
}
Full stacktrace:
org.h2.jdbc.JdbcSQLException: Table "STORY_RUN" not found; SQL statement:
select this_.id as id3_1_, this_.version as version3_1_, this_.batch_id as batch3_3_1_, this_.batch_iteration as batch4_3_1_, this_.browser_string as browser5_3_1_, this_.easybresult_id as easybres6_3_1_, this_.failed_scenarios as failed7_3_1_, this_.last_parse_error as last8_3_1_, this_.passed_scenarios as passed9_3_1_, this_.result_parsed_story_status as result10_3_1_, this_.status as status3_1_, this_.story as story3_1_, this_.total_scenarios as total13_3_1_, this_.xml as xml3_1_, storyrunba1_.id as id2_0_, storyrunba1_.version as version2_0_, storyrunba1_.batch_id as batch3_2_0_, storyrunba1_.browsers_string as browsers4_2_0_, storyrunba1_.date_created as date5_2_0_, storyrunba1_.iterations as iterations2_0_, storyrunba1_.site_profile as site7_2_0_, storyrunba1_.stories_string as stories8_2_0_ from story_run this_ inner join story_run_batch storyrunba1_ on this_.batch_id=storyrunba1_.id order by storyrunba1_.date_created desc [42102-164]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.command.Parser.readTableOrView(Parser.java:4753)
at org.h2.command.Parser.readTableFilter(Parser.java:1080)
at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1686)
at org.h2.command.Parser.parseSelectSimple(Parser.java:1793)
at org.h2.command.Parser.parseSelectSub(Parser.java:1680)
at org.h2.command.Parser.parseSelectUnion(Parser.java:1523)
at org.h2.command.Parser.parseSelect(Parser.java:1511)
at org.h2.command.Parser.parsePrepared(Parser.java:405)
at org.h2.command.Parser.parse(Parser.java:279)
at org.h2.command.Parser.parse(Parser.java:251)
at org.h2.command.Parser.prepareCommand(Parser.java:217)
at org.h2.engine.Session.prepareLocal(Session.java:415)
at org.h2.engine.Session.prepareCommand(Session.java:364)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1121)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:267)
at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:281)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
at kindlingtests.ResultService.recentStoryRuns(ResultService.groovy:6)
at kindlingtests.HomeService.results(HomeService.groovy:19)
at kindlingtests.ModelFields$_closure1.doCall(ModelFields.groovy:13)
at kindlingtests.ModelFields.<init>(ModelFields.groovy:12)
at kindlingtests.HomeService.setControllerModelFields(HomeService.groovy:9)
at kindlingtests.HomeService.setControllerModelFields(HomeService.groovy:8)
at kindlingtests.HomeController.index(HomeController.groovy:14)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
[edit]
As requested, my DataSource.groovy:
dataSource {
pooled = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:mem:devDb;MVCC=TRUE"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:prodDb;MVCC=TRUE"
pooled = true
properties {
maxActive = -1
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
}
}

Resources