Archive for the ‘How-to’ Category

Playing with Grails application configuration

This small tutorial will show how to create a configuration file and how to manage configuration of your Grails application. It will show how to

  • Access configuration parameters
  • Create external configuration
  • Configure Spring for different environments
  • Create a new environment

Accessing configuration parameters

The configuration of Grails is stored in grails-app/conf directory. Parameters are stored in configuration files in “plain text way”

app.default.user = "tester"

or in “structured way”

app{
	default{
		user = "tester"
	}
}

In an application, one can access the parameters easily. Just import the correct class and ask it the correct question.

import org.codehaus.groovy.grails.commons.ConfigurationHolder
 
class TestController {
	def query = {
		render ConfigurationHolder.config.app.default.user
	}
}

The example above should render the string “tester”. Moreover, in the configuration files, one can easily define distinct config values for each of three different environments – production, development and test.

environments {
	production {
		grails.serverURL = "http://www.changeme.com"
	}
	development {
		grails.serverURL = "http://www.do-not-change.cz"
	}
	test {
		grails.serverURL = "http://www.just-for-test.de"
	}
}

External configuration

The configuration mechanism of Grails is nice, but there is a small trouble. The configuration files are compiled and packed into the deployment package (WAR) during project build phase. However, one usually does not want to rebuild the whole application just to change say a database password. So, how to do it?

The first step is to create an external configuration file. Let’s name it externalConfig.groovy. Its structure will be the same as the structure of the other configuration files – “flat text” or “structured”.

Now, how do you tell Grails to find and use it? Adding the following code to the beginning of your config.groovy will do the trick. It expects that there is an OS environment variable MY_GREAT_CONFIG that points to the configuration file.

if(System.getenv("MY_GREAT_CONFIG")) {
	println( "Including configuration file: " + System.getenv("MY_GREAT_CONFIG"));
	grails.config.locations << "file:" + System.getenv("MY_GREAT_CONFIG")
} else {
	println "No external configuration file defined."
}

Spring configuration

The grails-app/conf/spring/resources.groovy file gives the developer a convenient way to define beans. Distinguishing environments is slightly more complex than in other configuration files, but still elegant.

switch(GrailsUtil.environment) {
	case "production":
		myBean(package.BeanClass, 1, "prod")
		break
	case "test":
		myBean(package.BeanClass, 1, "test")
		break
	case "development":
		myBean(package.BeanClass, 1, "dev")
		break

Configuration parameters can be used here the same way as in the controller example above.

myBean(package.BeanClass, 1, ConfigurationHolder.config.app.default.user)

Adding more environments

It might seem that the development, test and production environments are just enough. Yes, that is true for most basic scenarios. However, if you develop for a large company with sophisticated deployment procedures, there are typically several production-level application server environments (one for user acceptance testing, one for system patch analysis and performance testing, one for production etc.), all of them corresponding to the Grails “production” environment.

How to address this scenario? Easily. Just introduce another environment into your configuration

environments {
	production {
		grails.serverURL = "http://www.changeme.com"
	}
	development {
		grails.serverURL = "http://www.do-not-change.cz"
	}
	test {
		grails.serverURL = "http://www.just-for-test.cz"
	}
	uat {
		grails.serverURL = "http://www.uat-testing-environment.cz"
	}
}

and run the application or create a war file with an extra parameter

	grails -Dgrails.env=uat war
	or
	grails -Dgrails.env=uat run-app

Grails: internationalization in the service

Today I spent some time by creation of localized messages in a service. Here is a small tutorial.

1. Create your service

grails create-service Local

2. Add a messageSource variable to your new service

class LocalService {
  def messageSource
}

3. Use it in a service method

// Initialize parameters
Object[] testArgs = {}
def msg = messageSource.resolveCode("message.code.to.translate", new java.util.Locale("EN")).format(testArgs)

4. Finally edit the grails-app/i18n/messages.properties

message.code.to.translate=It works!!!

Monitoring number of SQL queries in MySQL

I have created a new application in Grails and surprisingly, in production environment it was slower than on my laptop. Production administrator found that my application generate too many SQL queries. The delay was caused by network latency. So, I had to find a way how to monitor number of SQL queries on MySQL server.

For monitoring of the current session, there is a handy command:

SHOW STATUS WHERE variable_name='Com_select'

For monitoring of all the sessions, there is a switch:

SHOW global STATUS WHERE variable_name='Com_select'

All variables could be listed by

SHOW STATUS

Custom iterative tag in Grails with named variable

I will show you how to create an iterative Grails tag that can contain another tag. The inner tag will use variable of the iterative tag. So, we are going to implement a tag that creates n links ’/show/1’, ’/show/2’, etc. with description ‘Article number 1’, ‘Article number 2’ etc.:

First of all, there is a nice and handy example for a simple iterative tag on the Grails site.

Definition:

def repeat = { attrs, body ->
  def i = Integer.valueOf( attrs["times"] )
  def current = 0
  i.times {
    // pass the current iteration as the groovy default arg "it"
    // then pass the result to "out" to send it to the view
    out << body( ++current )
  }
}

Usage:

<g:repeat times="3">
  <p>Repeat this 3 times! Current repeat = ${it}</p>
</g:repeat>

Slight modification of the tag does not lead to the requested functionality:

<g:repeat times="3"> 
  <g:link action="show" id="${it}">Hello number  ${it}</g:link> 
</g:repeat>

It just generates the “Article number” string three times, because the it variable is not known here.
Thus it is necessary to change the tag definition. Lets add another parameter vars as a symbolic name of the current member of the collection.

def repeat = { attrs, body -> 
  def pars = [:]
 
  attrs.times?.toInteger().times { n -> 
    pars[attrs.var] = n
    out << body(pars) 
  } 
}

And now it is possible to use g:link inside the custom tag:

<g:repeat times="3" var="num"> 
  <g:link action="show" id="${num}">Hello number  ${num}</g:link> 
</g:repeat>

I am not sure if it is supported, but it is definitely working.

From Mysql to Oracle: Grails application migration

Today I have finished migration of our Grails prototype. Originally we did develop it for MySQL, but the final system have to work with Oracle. This post summarize troubles and differences I was facing.

User creation

Since I am not Oracle administrator, it took me some time to put together script that creates user and appropriate rights for the Grails application. Use the script for development only.

CREATE user grails IDENTIFIED BY grassword;
GRANT connect  TO habilion;
GRANT CREATE TABLE TO habilion;
GRANT CREATE sequence TO habilion;
GRANT unlimited tablespace TO habilion;

Identifier length limitation

I usually do not use identifiers that are 30 characters long. But, there is a trick.

Imagine two classes: Author and Content. Author having multiple Contents.

Now, imagine there is several types of Content – Book, Newspaper, ElectronicNewspaper, ScientificArticle…
So, we can model the situation using following classes:

Class Content{
  static belongsTo = [ contentAuthor:Author ]
}
 
Class Book extends Content {}
Class Newspaper extends Content {}
Class ElectronicNewspaper extends Content {}
Class ScientificArticle extends Content {}
 
Class Author{
  static hasMany = [ contents: Content ]
}

And now comes the trick. The ‘content’ table in the database contains long columns:

content_author_id
newspaper_content_author_id
electronic_newspaper_content_author_id
book_content_authot_id
scientific_article_author_id

As you can see, it is easy to hit the 30 characters limit. If you look deeper, you will see the solution. The column names are composed of class name of the Content descendants and variable name pointing to the master entity.
So, I renamed the contentAuthor to ca, created getter and setter for contentAuthor and checked all “new Book…” snippets. God bless MVC!

Column size

The second major issue was a String column. I had a string column of 10000 characters.

Class Content {
  String abstract
  static constraints = { abstract(maxSize:10000) }
}

It was translated to Long data type. Unfortunately there is a bug in Oracle JDBC driver that causes nasty stack traces when processing Long data type. There is a workaround on the Internet, but it is working only for some versions of Oracle. Moreover, there is just one Long column allowed per table. So, changed the size to 4000 characters and the column was created as VARCHAR2.

And thats it!

Update: Empty strings

One thing to mention is a fact that Oracle does not distinguish between null and an empty string. So, if you try to store an empty string to Oracle DB, it actually stores it as a null value.

The problem arises, if you have not null column and you try to store empty string ‘’. For Grails it is a not null value, so it does not apply defaults. For Oracle it is null and thus constraint violation…