Defining an alternate connection pool in Grails 2.3.6 - grails

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!

Related

Dynamic Quartz Configuration in Grails 3

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
}

How to configure tempusage in activemq grails app

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.

No suitable driver found for jdbc:jtds:sqlserver in grails 2.4.3 + groovy 2.3 project

I am facing weird issue in my grail project and after trying a lot i am posting this question here.I have tried all the URL related combination form http://jtds.sourceforge.net/faq.html#noSuitableDriver and other stack over flow answers like Help me create a jTDS connection string.
I am working on grails 2.4.3 project with groovy 2.3 and trying to connect with SQL Server database using jtds 1.3.1 but always getting "No suitable driver found for jdbc:jtds:sqlserver:" But to test this scenario i have written stand alone program as given below for same data base using same jar jtds 1.3.1 and its working fine.
try{
Class.forName("net.sourceforge.jtds.jdbc.Driver");
String url = "jdbc:jtds:sqlserver://<hostname>:<port>/<database>";
Connection con = DriverManager.getConnection(url,"user","password");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);}
Below I have provided the grails project code snippet for connection class
class SQLServerConnection implements DBConnection {
#Override
public Connection getConnection(String serverName, String databaseName) {
// TODO Auto-generated method stub
Class.forName("net.sourceforge.jtds.jdbc.Driver");
String url = "jdbc:jtds:sqlserver://<host>:<port>/<database>";
Connection con = DriverManager.getConnection(url,"user","password");
return con
}
Action form where i am calling this method
def dataFaucetColumn (){
def currentApp = RawDataApp.get(params.int('id'))
String query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='"+currentApp?.tableName +"'"
Connection con = new SQLServerConnection().getConnection(currentApp?.servers,currentApp?.databaseName)
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query); }
waiting for your answers.
Here's how you can use SQL Server with Grails, while taking advantage of Hibernate:
Open grails-app/conf/BuildConfig.groovy
In the dependencies section add the JTDS dependency. Then save the file.
Example:
dependencies {
runtime 'net.sourceforge.jtds:jtds:1.3.1'
}
Open grails-app/conf/DataSource.groovy
In the environments section, set up the data source and save the file. In the following example I'll set up SQL Server for the production environment
Example:
environments {
production {
dataSource {
dbCreate = "update"
url = "jdbc:jtds:sqlserver://<hostname>:<port>/<database>"
username = "X"
password = "X"
driverClassName = "net.sourceforge.jtds.jdbc.Driver"
dialect = org.hibernate.dialect.SQLServerDialect
properties {
maxActive = 8
minEvictableIdleTimeMillis = 1800000
timeBetweenEvictionRunsMillis = 1800000
numTestsPerEvictionRun = 3
testOnBorrow = true
testWhileIdle = true
testOnReturn = true
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
jdbcInterceptors = "ConnectionState"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
}
}
}
That's it. Now you can use GORM to query the database. Plus, Hibernate will manage the database connection(s) :)

Grails Hibernate - how to keep data in hibernate cache still my grails application restarted

I created a new simple project.
I created a Book domain and mentioned cache=true in mapping.
I am setting some data by BootStrap.groovy configuration.
I added some print statements in BootStrap.groovy to check the data is added or not.
I put Hibernate second level cache is true.
I run application, it printed in console that "added this many records".
But the date not showing in my grid.
I tried with postgresSQL, with same data. My grid showing records. Just change in DataSource.groovy only.
Please help me, what I am missing
My Default hibernate configuration in DataSource.groovy
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
}
In other words, how to keep data in hibernate cache still my grails application restarted.
**
**

Jasypt plugin with encryption / decryption in grails

By the reference of the question Is it possible to use the Grails Jasypt plugin outside the GORM layer for simple String encryption and decryption?
i tried to implement it for my password encryption / decryption .
But every-time its giving different encrypted value for the same password . so how can i use the following code and the jasypt configuration ?
def authenticate(){
def jasyptConfig = grailsApplication.config.jasypt
org.jasypt.encryption.pbe.StandardPBEStringEncryptor stringEncryptor =
new org.jasypt.encryption.pbe.StandardPBEStringEncryptor(jasyptConfig)
def encrypted = stringEncryptor.encrypt(params.password)
}
jasypt {
algorithm = "PBEWITHSHA256AND256BITAES-CBC-BC"
providerName = "BC"
password = "test"
keyObtentionIterations = 1000
}
The salt!
If you don't care, just set a ZeroSaltGenerator instance to your Encryptor. By default, it is RandomSaltGenerator, so the outputs are different.
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 = "PBEWITHSHA256AND256BITAES-CBC-BC"
providerName = "BC"
password = "test"
keyObtentionIterations = 1
saltGenerator = new org.jasypt.salt.ZeroSaltGenerator()
}
}
And it will generate the same encrypted values everytime.

Resources