Anatomy of a successful project

Starting a new project is always an exciting time. People are discussing the “NEW BIG THING”, putting together their two cents to fully utilize the budget, dreaming…

Stakeholder says: “It has to rock! It must create us a competitive advantage!”

Project sponsor: “Sure, but it has to be cheap.”

Analyst shouts: “We should not underestimate the requirements!”

Architect whispers to developer: “Architecture is important!”

Developer whispers back: “There is a great new framework there. It does not suffer of… you know, the thing that almost killed us last time.”

All of these are valid inputs, but to start a successful project, it is important to know its phases. So, let’s describe it on a simple project that should solve business trips to Paris.

  • Customer describes the most important use cases: “I travel to Paris a lot. It would be great to fly there.”
  • Analyst remarks requirement: “Customer wants an airplane.”
  • Analyst creates a vision and presents it to the stakeholder. User gets Powerpoint presentation. Both are excited!
  • Company puts together a tender committee to select the airplane.
  • Tender committee describes the airplane… It requires at least 50 seats… to be sure, it covers future requirements.
  • Vendors create proposals to deliver the airplane.
  • Tender committee selects two of them for price negotiations.
  • Vendors are pushed to cut down price. Tender committee sacrifices the 50 seats and few other non-important features.
  • Vendors describe a bicycle for price of a car, calling it “Low elevation flyer™”.
  • Tender committee and architects accept it as a temporary solution.
  • Negotiations were too long, so there is no time to implement. Vendor buys a bicycle, colors it red, stick a pair of bird wings on it and delivers.
  • Rollout and success! Celebration needed.
  • End users start to whisper, that it does not fly and it is extremely slow.
  • Vendor provides a bunch of performance tuning and usability experts and forms a task force.
  • The task force adds a textile wings, propeller, powerful 2000 RP1 engine and a name “TURBO low elevation flyer™”
  • Even greater success! Celebration needed, press release absolutely necessary.
  • End users start to use train.

Now it is obvious: “It is not important what you do, but how you present it”

Happy All Fools’ Day!

1. 2000 RP – 2000 ratpowers. It is like horsepower, but it looks better to see 2000 RP than 2 HP.

Nested set plugin for Grails

We are happy to announce that our NestedSet plugin for the Grails framework has been released. The plugin creates a hierarchical structure on top of plain database records. A description of the “nested set” data structure can be found in Wikipedia.

The NestedSet Grails plugin is

  • non-intrusive – it does not change your data model, just adds one table
  • easy to use – just add “static nestedSet = true” to the domain class
  • versatile – it supports multiple hierarchies

Installation instructions and usage details can be found at the NestedSet plugin homepage.

If you find it useful, tell your friends. If there is a problem, please register at grails.cz and create a new issue.

SoapUI in IntelliJ IDEA 8.1.3

The latest and greatest IntelliJ IDEA 8.1.3, a cute Java IDE, has soapUI integrated as a plugin. That’s a handy open-source helper for developing and testing SOAP-based web services.

However, after installing the plugin and starting it from Tools – SoapUI – Start SoapUI, you can only see the soapUI Navigator tool window, showing the project structure. You can not see or invoke the famous two-pane SoapUI ModelItem Editor displaying SOAP request-response pairs (at least in MS Windows).

A brief check of the soapUI Log – error log discovers that a class named RSyntaxTextArea cannot be found:

java.lang.NoClassDefFoundError: org/fife/ui/rsyntaxtextarea/RSyntaxTextArea

That’s easily helped: just download RSyntaxTextArea from the SourceForge and copy

rsyntaxtextarea.jar

to

%USERPROFILE%\.IntelliJIdea80\config\plugins\intellij-soapui-plugin\lib

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

Configuration and usage of Gldapo in a Grails project

Configuration and usage of Gldapo in a Grails project

Gldapo is a groovy library for object oriented LDAP access. “The Gldapo is to LDAP what GORM is to SQL”.

Gldapo is packaged in Grails LDAP plugin, its installation is easy. In the root of your Grails project run command:

grails install-plugin ldap

Configuration

The Gldapo is configured in the Config.groovy file. Here follows an example.

ldap {
    directories {
        user { 
            url = "ldap://ldap.zmok.net"
            base = "OU=Users,DC=zmok,DC=net"
            userDn = "CN=usernameToLogToLdap,OU=Users,DC=zmok,DC=net"
            password = "passwordToLogToLdap" 
            searchControls { 
                countLimit = 40 
                timeLimit = 600 
                searchScope = "subtree" 
            }
        }
        group { 
            url = "ldap://ldap.zmok.net"
            base = "OU=Groups,DC=zmok,DC=net"
            userDn = "CN=usernameToLogToLdap,OU=Users,DC=zmok,DC=net"
            password = "passwordToLogToLdap"
            searchControls { 
                countLimit = 40 
                timeLimit = 600 
                searchScope = "subtree" 
            }
        }
    }
 
    schemas = [ 
        net.zmok.ldap.User,
        net.zmok.ldap.Group
    ]
 
}

The configuration is self-explaining, except of the schemas part. This is where the magic starts. The classes are object representation of the LDAP entities. So, let’s look how the classes are defined.

package net.zmok.ldap
import gldapo.schema.annotation.GldapoNamingAttribute
 
class User{
	@GldapoNamingAttribute
	String cn
	String title
	String displayName
	Set memberOf
}
package net.zmok.ldap
import gldapo.schema.annotation.GldapoNamingAttribute
 
class Group{
	@GldapoNamingAttribute
	String cn
	Set members
	@GldapoSynonymFor("mgr")
	String manager
}

Here, @GldapoNamingAttribute is mandatory and defines the key of the entity. The @GldapoSynonymFor redefines the LDAP names to human-readable format. In our case mgr will be translated to manager.

Manipulation

Usually, one needs to find a few records in an LDAP directory and do something with them. Lets say we need to find members of groups named like “Groovy*” (means GroovyProgrammers, GroovyFans, GroovyHaters) and their managers.
The Gldapo offers findAll method similar to GORM. So, here is the code to list them:

Group.findAll( directory: "group", filter: "(cn=Groovy*)" ).each{ group ->
	def groupName = group.cn
	group.members.each{ member ->
		def user = User.find( directory:"user", filter:"(cn=${member})")
		println "User ${user.displayName} managed by ${group.manager} is member of ${groupName}."
	}
}

Pretty easy, isn’t it? The User and Group classes are similar to GORM classes, so one can create, update, move, replace, delete… and much more. For details see http://http://gldapo.codehaus.org/schemaclasses/entries.html.