Tag Archives: configuration

Grails Starter kit

After years of working with Grails, I thought I would put down in one place a few things I tend to use frequently in my Grails projects. These are things I thought might help others getting started with Grails.

Templates

I often find that I need to extend the default session timeout(found in the src/templates). All that is needed is

> grails install-templates

You will then need to edit the web.xml contained in the following directory structure that was generated from the above command.

src -> templates -> war -> web.xml

you can now modify the timeout value

<session-config>
    <session-timeout>180</session-timeout>
 </session-config>

Custom Domain Classes

Update your domain class templates to reduce having to type in your company standards for every domain class. One of the environments I worked in had a database standard that required us to label Primary Key column name(PK_column_name) and use oracle’s generator for ids. I addressed this by creating a private company “db standards” Grails plugin.

First I updated the

templates-> artifacts ->DomainClass.groovy file

@artifact.package@class @artifact.name@ {
    Date lastUpdated
    Date dateCreated
    String createdBy
    String updatedBy

    static constraints = {

    }
    static mapping={
        id generator: 'sequence', params: [sequence: '@artifact.name.uppercase@_SEQ']
        columns { id column: 'PK_@artifact.name.uppercase@_ID' }//prod/test
    }
}

I then copied and modified a core grails script(see comments in code) that creates domain classes and renamed it create-my-domain(well it was better names then this… but you get the gist :D). See below.
Then I can run

>create-my-domain Book

The following concrete domain class is generated(notice the sequence,id, and generator are all there).

class Book{

  Date lastUpdated
  Date dateCreated
  String createdBy
  String updatedBy
  static mapping = {
    id generator: 'sequence', params: [sequence: 'BOOK_SEQ']
    columns { id column: 'PK_BOOK_ID' }
}

DataSource(s)

There are times when I need to query a database that I don’t need/want a Domain Class for.  I tend to create a datasource and inject it into a service that will be handling the connection/query with groovySql

Here is an example datasource in the DataSource.groovy file.

dataSource_salesInfo {
  driverClassName = "oracle.jdbc.driver.OracleDriver"
  url = ""//more on how to configure this later in this blog entry
  username = ""

  password = ""
  dialect = "org.hibernate.dialect.Oracle10gDialect"
  hibernate {
    cache {
      use_second_level_cache = false
      use_query_cache = false
    }
  }
}

Example service that uses the defined datasource entry.

class AwesomeService{

  def dataSource_salesInfo //Inject it

  def queryDB(){
  def sql = new Sql(dataSource_salesInfo)
  String myQuery ='..'
  sql.rows(myQuery).each { resultSet -> /*do something*/}
  }
}

Externalize Datasources

One way to externalize your jdbc connection url is to use an system environment variable. Another is to have your operations team generate a properties file based on the tnsnames.ora file and read it into your grails application. I will describe how the properties file based solution would work.
An Example tnsnames.properties entry might look like the following.

DATAWAREHOUSE=jdbc:oracle:thin:@xyaeyp49:1521:DATAWAREHOUSE

in datasource.groovy file, I add the following to the top of the file.

def props = new Properties()
new File('pathToTNS.properties').withInputStream { stream -> 
props.load(stream) }

then I reference the property in the URL entry for the datasource I am working with 

username='javazquez'
url = props.get("DATAWAREHOUSE")
...

 

Most of my day is spent with Oracle databases. The validation query that I use is

 

validationQuery = "SELECT sysdate from dual"

here is a complete example.

production {
  dataSource {
    url = props.get("DATAWAREHOUSE")
    username = ""
    password = ""
    properties {
      maxActive = -1
      minEvictableIdleTimeMillis = 1800000
      timeBetweenEvictionRunsMillis = 1800000
      numTestsPerEvictionRun = 3
      testOnBorrow = true
      testWhileIdle = true
      testOnReturn = true
      validationQuery = "SELECT sysdate from dual"
    }
  }
}

 

Here are the lines that actually allow you to externalize your config/datasources(Thanks to Burt Beckwith and his book )

 

production {
grails.config.locations = [
"file:path_2_external_config.properties" //NOTE: don’t leave spaces
]
}

I like to have the following in my path

grails.config.locations = [
 "file:path_${appName}/${appName}_${grails.util.Environment.current.name}_config.groovy",
]

This forces the file name to have development || production || test and the application name in the configuration file to prevent copy and paste errors(you would never do that right 😉 )

SQL Logging

There are a couple of ways to see what is going on under the hood when your application is querying the database.

The easiest is to add the logSql = true to your datasource

development {
  dataSource {
    url = props.get("DATAWAREHOUSE")
    logSql = true
    ...
    }
  }
}

If you need more information,  Burt Beckwith has the following Logging Hibernate SQL post that you should read. He shows how adding the following lines to your log4j closure will help with understanding what is happening under the hood.

log4j = {
   ...
   debug 'org.hibernate.SQL'
   trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}

Misc

A log pattern that works with tomcat(YMMV)

appenders {
console name: 'stdout', threshold: org.apache.log4j.Level.INFO
rollingFile name: 'MyLogs', file: 'logs/MyLog.log', maxSize: 104576, threshold: org.apache.log4j.Level.INFO ,
layout:pattern(conversionPattern: "%d{yyyy-MM-dd HH:mm:ss} [%t] %p %c - %m%n")

}

Have your war tell you what environment you are deploying to

grails.project.war.file = "target/${appName}-${appVersion}-${System.getProperty('grails.env')[0..3]}.war"

Websites and links to check out

 

Many of the things I have learned have come from the above links and people. A big Thank You to the gr8 community for all the help over the years.

 

-Juan

Grails ldap integration with Active Directory via spring-security-ldap

The spring-security-ldap has great documentation. I put together a working example (at least in my environment) to complement the docs. When I was tasked with integrating our grails apps with Active Directory I remember there being a scarcity of examples.. so I hope this code will save you some time in getting ldap working with Active Directory in your grails environment.

Important files

grails-app/conf/Config.groovy
src/groovy/com/javazquez/ldapexample/MyUserDetailsContextMapper.groovy
src/groovy/com/javazquez/ldapexample/MyUserDetails.groovy
grails-app/conf/spring/resources.groovy

once you have your Active Directory configurations entered (grails-app/conf/Config.groovy), fire up your app and
test it out by logging in via the login controller.

Notes

  • You may have to update MyUserDetailsContextMapper.groovy as my Active Directory environment may differ from yours.
  • You may also want to update MyUserDetails.groovy to hold more or less info than my config.

-JV

Groovy Invoke Dynamic Support

The release of Groovy 2.1 comes with full Invoke Dynamic Support. Initially I had issues with trying to get a working example up and running as seen by the following message.

>groovy –indy mergesort.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during class generation: Cannot use invokedynamic, indy module was excluded from this build.

I checked the groovy version to make sure that I had Java 7 loaded as seen here
groovy -version
Groovy Version: 2.1.0 JVM: 1.7.0_11 Vendor: Oracle Corporation OS: Mac OS X

In order to get things working, I read that I needed to get the “indy” jar on my classpath. I added the following to my .bash_profile and restarted my terminal and the error cleared up

export CLASSPATH=$HOME/.gvm/groovy/current/indy/groovy-2.1.0-indy.jar

Hope this helps and a huge thanks to the Groovy Core Team for this latest update!

-Juan

Simple Groovy project using Gradle

Hello fellow Groovyists 🙂

I have been kicking the tires on using Gradle for my Groovy projects. I had a few stumbles along the way and wanted to share what I came up with for getting a very simple example working.

build.gradle

apply plugin: 'groovy'
version = "1.0-${new Date().format('yyyyMMdd')}"

manifest.mainAttributes("Main-Class" : "com.javazquez.HelloThere")

repositories {
mavenCentral()
mavenRepo urls: "http://groovypp.artifactoryonline.com/groovypp/libs-releases-local"
}
dependencies {
groovy group: 'org.codehaus.groovy', name: 'groovy-all', version: '1.8.4'
groovy group: 'org.mongodb', name: 'mongo-java-driver', version: '2.6.5'
groovy group: 'com.gmongo', name: 'gmongo', version: '0.9.1'
testCompile "org.spockframework:spock-core:0.5-groovy-1.8"
}

jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

below is the the HelloThere.groovy file located src/main/groovy/com/javazquez/HelloThere

package com.javazquez
public class HelloThere {

public static void main(String []args) {
println "Hello coders!"

}

}

after running gradle build, I can navigate to the build/libs directory and run java -jar HelloThere-1.0-20111115.jar and get the following ouptut

Hello coders!

Gradle is a fantastic tool and I hope this article helps show the ease of getting a project set up.

Login with Basic Authentication using Groovy

Hey there fellow Groovyists! I was recently in need of performing Basic Authentication on Apache using Groovy for a proof of concept. Below is what I was able to quickly put together.

//Here is a quick groovy 1.7.4 Basic Auth Example
@Grab(group=’org.codehaus.groovy.modules.http-builder’, module=’http-builder’, version=’0.5.0′ )

def authSite = new groovyx.net.http.HTTPBuilder( ‘http://10.110.201.115/~juanvazquez/basicAuth/’ )
authSite.auth.basic ‘user’, ‘pwd’
println authSite.get( path:’testAuth.html’ )

Proxy/ReverseProxy and Apache2

I recently configured Apache2 to be a ReverseProxy/Proxy and thought I would share my experiences while it was still fresh. Having never configured any kind of proxy, I found this webpage very informative. The scenario I would like to use for my example is that I have three internal web servers called

Site Local IP Remote IP Port
www.reallycoolsite.com 192.168.1.102 10.15.22.1 80
www.justcoolsite.com 192.168.1.102 10.15.22.2 80
www.reallylamesite.com 192.168.1.44 10.15.22.3 80

Alright…pretty straight forward right? If you are in a situation that I was when I started, you haven’t done much more than install apache from source and added a few modules here and there occasionally. The way I solved the problem was to create name-based virtual host for each of the servers.
our example would look like


#you can listen on specific ports for requests if you like
#(ex->Listen 192.168.1.102:80)
#I use the below statement to listen on 80 for all requests
Listen *:80
#Because we have multiple names mapped to same ip
NameVirtualHost 192.168.1.102:80

<VirtualHost 192.168.1.102:80 >
ServerName www.reallycoolsite.com
ProxyRequests Off
ProxyPass / http://10.15.22.1/
ProxyReverse / http://www.reallycoolsite.com/
ProxyPreserveHost On
ErrorLog reallycoolsite_error_log
CustomLog reallycoolsite_access_logs
</VirtualHost >

<VirtualHost 192.168.1.102:80 >
ServerName www.justcoolsite.com
ProxyRequests Off
ProxyPass / http://10.15.22.2/
ProxyReverse / http://www.justcoolsite.com/
ProxyPreserveHost On
ErrorLog justcoolsite_error_log
CustomLog justcoolsite_access_logs
</VirtualHost >

<VirtualHost 192.168.1.44:80 >
ServerName www.reallylamesite.com
ProxyRequests Off
ProxyPass / http://10.15.22.3/
ProxyReverse / http://www.reallylamesite.com/
ProxyPreserveHost On
ErrorLog reallylamesite_error_log
CustomLog reallylamesite_access_logs
</VirtualHost >

If you receive errors during the communication of your proxy and your server, it may be a good idea to investigate if you have an http protocol error discussed at the bottom of this page
The following two lines are pulled from the reference and fixed a problem I had with one of my IIS servers using SSL(for more info about the issue, go here

SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1

My apache configuration file(httpd.conf) was the file I used to edit my settings.. Your file may be different depending on how new your apache version is. I found that some implementations called the configuration file apache.conf…. I hope this blog entry is helpful you, Happy Configuring!