stopsoftwarepatents.eu petition banner

Grails countries plugin 0.2 released

August 7th, 2010 Stefan Armbruster 1 comment

Thanks to the contributions of other hackers I’m announcing the 0.2 release of the Grails countries plugin. The changes:

  • added languages for country and continent names:
  • country list is now maintained outside CountryBootstrap.groovy in seperate csv files
  • reworked properties file to consistently use ISO-3166 3-letter-code as key
Categories: Uncategorized Tags: , ,

new Grails plugin: Countries

August 4th, 2010 Stefan Armbruster 4 comments

A common requirement in many applications is to deal with countries and/or continents. The plugin’s goal is to apply the DRY principle to these requirements.

In short, the plugin offers:

  • populated domain classes for countries and continents
  • i18n for continent and country names (for now, only en and de locales). Currently there are 190 countries available.
  • tags for simple usage of
    • localized names for countries and continents
    • select boxes: for all countries, for all continents, for all countries of a continent or for a defined set of countries. The select box contents are automatically sorted by the the localized country/continent name.

resources:

For bug reports please use http://jira.codehaus.org, project “GrailsPlugins”, component “countries”.

Update: since the initial release requires the usage of Grails 1.3.4-SNAPSHOT a bugfix release 0.1.1 has been release shortly afterwards. 0.1.1 should work with Grails >= 1.0.

Categories: Uncategorized Tags: , ,

Grails Neo4j plugin 0.3 released

July 30th, 2010 Stefan Armbruster No comments

Today I released an update of the Grails Neo4j plugin (http://www.grails.org/plugin/neo4j). The main changes are:

  • compatibility with Grails 1.3.x. Be aware, Grails 1.3 – 1.3.3 are suffering from http://jira.codehaus.org/browse/GRAILS-6427, so either use Grails 1.2.x, or be brave and use a recent git build of Grails 1.3.4.SNAPSHOT.
  • usage of Neo4j 1.1 (released today just a few hours ago, so get it while it’s hot).

All changes:

  • [GRAILSPLUGINS-2302] – “home” link broken in the org.codehaus.groovy.grails.plugins.neo4j.Neo4jController views
  • [GRAILSPLUGINS-2303] – Problems with annotation Neo4jEntity
  • [GRAILSPLUGINS-2345] – upgrade to Neo4j 1.1
  • [GRAILSPLUGINS-2346] – <domainclass>.get() throws exception if id is not invalid
  • [GRAILSPLUGINS-2347] – <domainClass>.findAllBy<Field>(value) fails
  • [GRAILSPLUGINS-2349] – provide compatibility for Grails 1.3.x
Categories: Uncategorized Tags: ,

getting a list of all i18n properties used in a Grails application

July 14th, 2010 Stefan Armbruster No comments

You might know this situation: in a project you start by hacking code that uses i18n properties instead of fixed strings in order to support multiple languages. The normal process in Grails is to use the g:message tag in controllers or gsp templates. Side by side you append the new introduced i18n property with some value in your messsages.properties file.

When support for a new language is requested, all you have to do is translating messages.properties. So far so good – this make i18n really easy.

But: when the project evolves, there’s a good chance that some of your i18n properties in messages.properties gets orphaned. Assume you remove a block of code from a gsp. It happens often that the i18n properties used in this block are not removed from messages*.properties because at some point you are not sure if it is referenced elsewhere. So what would be really useful here would be a list of all referenced i18n properties from your *.groovy/*.gsp files.

Doing so is pretty easy, just add a new gant script to your Grails application’s script folder, let’s name it i18nList.groovy. This script basically contains:

includeTargets << grailsScript("Init")
 
target(main: "create a list of all i18n properties used in groovy code and gsp templates") {
 
    def properties = []
 
    new File(".").eachFileRecurse {
        if (it.file) {
            switch (it) {
                case ~/.*\.groovy/:
                    def matcher = it.text =~ /code:\s*["'](.*?)["']/
                    matcher.each { properties << it[1] }
                    break
                case ~/.*\.gsp/:
                    def matcher = it.text =~ /code=["'](.*?)["']/
                    matcher.each { properties << it[1] }
                    break
            }
        }
    }
    println properties.sort().unique().join("\n")
 
}
 
setDefaultTarget(main)

(sorry the color coding seems to fail for some Groovy regexes) The script recursivly iterates over all *.groovy and *.gsp files in your project and extract the part after the ‘code’ attribute of the message tag using a regex. The regex result are collected into an array. This array is sorted, unique’d and printed to the console. That’s it.

One word of caution: this gant script ‘works for me’. So depending on your code, you might notice that the used regex are not sufficient or even fail. Feel free to modify them for your needs, even better send back your modifications.

Categories: Uncategorized Tags: , ,

Grails Webdav Plugin 0.3 released

May 30th, 2010 Stefan Armbruster 1 comment

Today I’ve released a minor update to the Grails Webdav plugin. Compared with the previous version a few bugs have been fixed.

Categories: Uncategorized Tags: ,

new Grails plugin released: modproxybalancer

Last week I attended the gr8conf, a really great conference. One of my favorite event was the Hackergarden. In the evening after the regular talks ~30+ people came together (should I call them nerds?), split up into small groups and did some hacking on Groovy & Grails related topics. I found myself together with Davide Rossi to do some coding on deploying a Grails application to multiple tomcat nodes and manage a loadbalancer in front of them. The original goal was to finish the task at end of evening. Unfortunately we set our goal too high, and did not manage to release some code at that evening. During the last weekend I took some time to finish this and did a release today.

This plugin’s goal is to simplify the deployment of a grails application to a cluster consisting of multiple tomcat instances and an Apache httpd mod_proxy_balancer.

It assumes you have an Apache mod_proxy_balancer running in front of multiple tomcat instances in order to provide a) high-availability and b) load-balancing to your Grails application. In such a scenario, upgrading the running application to a newer release is painful and error-prone when done manually. This plugin’s goal is to simplify that procedure by performing a “rolling upgrade”. Calling ‘grails tomcat redeploy’ performs these actions:

  1. take first node offline in loadbalancer
  2. undeploy app on first tomcat node
  3. deploy app on first tomcat node
  4. check if app responds on first tomcat node
  5. take first node online in loadbalancer
  6. proceed the same procedure with next node

To solve this, we’ve forked the 1.3.1 release of the tomcat plugin an added the following capabilities:

  1. deploying to multiple hosts and
  2. emitting lifecycle events: PreDeploy, PostDeploy, PreUndeploy, PostUndeploy
  3. provide support for ‘grails tomcat redeploy’

These changes have been included in a pull request to the upstream plugin, so I’m hoping they will find their way into Grails 1.3.2.

The rest of the work has been put into the modproxybalancer plugin, taking care of remote controlling the loadbalancer  by catching up these events. mod_proxy_balancer comes with a simple management frontend called balancer-manager. This consists of some simple HTML forms that can be easily triggered using htmlunit. When the forked tomcat plugin emits a “PreUndeploy” event, the loadbalancer disables the respective tomcat node, then a normal undeploy und deploy happens. After this, the freshly deployed tomcat is checked for availablity and taken back online in the loadbalancer.

The plugin is licensend under the WTFPL.

Side note: this is my first Grails plugin with it’s sources residing on github.com. Thanks to Peter Ledbrook’s excellent blog post, I was able to use GitHub pages for the documentation.

restrict a Grails controller to localhost access only

April 19th, 2010 Stefan Armbruster 2 comments

A common requirement for many web applications is that some parts (aka controllers) should only be accessible from specifc ip addresses. Typically controllers doing some administrative or maintenance work must be protected from non-authroized access. The most complete solution for this is using a full blown security framework like the Grails Acegi plugin. But there’s also a lean and quick solution for this in Grails: use a controller interceptor:

def beforeInterceptor = {
   if (!["127.0.0.1", "0:0:0:0:0:0:0:1"].contains(request.remoteAddr)) {
      render(status: 401, text: 'Access limited to localhost')
      return false
   }
}

Grails calls the beforeIntereceptor closure prior every action in a controller. Only if it returns true, the action is executed. In the code above if the client has a non-local IP address, a 401 error is returned with an error message. Note that localhost in IPv6 is 0:0:0:0:0:0:0:1, so it work both in IPv4 and IPv6 networks.

Categories: Uncategorized Tags: ,

Grails Neo4j plugin 0.2.1 released

April 2nd, 2010 Stefan Armbruster 4 comments

Today I released a minor update of the Grails Neo4j plugin. The changes are:

  • performance improvement by no longer calling map constructor in createInstanceForNode
  • fixed transaction handling by replacing interceptor with a “real” servlet filter
  • support for primitve arrays as properties in domain classes
  • bugfix: handling of bidirectional many-to-many relationships
  • bugfix: setProperties does no longer null out properties that have not been set
  • support for encodeAsXXXX methods from CodecsGrailsPlugin. In previous versions encoding did not work, since the ‘node’
    property of the domain classes could not be encoded (it’s a neo4j internal class!). Workaround: add getNode()==null method
    in AST transformation.

Everyone using the 0.2 release is recommended to upgrade.

Categories: Uncategorized Tags: ,

remove the passphrase from a pkcs12 certificate

March 23rd, 2010 Stefan Armbruster No comments

PKCS12 defines a file format that contains a private key an a associated certifcate. These files might be used to establish some encrypted data exchange. In the current use case, OpenVPN is used to connect to a remote network. The pkcs12 is being issued by a CA (certificat authority) tool. For security reasons, the private key contained in the pkcs12 is normally protected by a passphrase. This has the downside, that you need to manually type the passphrase whenever you need to establish the connection. But there’s a way to get around this. OpenSSL is a swiss-army-knife toolkit for managing simply everything in the field of keys and certificates. Since it’s a command line tool, you need to understand what you’re doing. So it took me a little to figure out how to remove a passphrase from a given pkcs12 file. Here’s what I’ve done:

openssl pkcs12 -in protected.p12.orig -nodes -out temp.pem
 
openssl pkcs12 -export -in temp.pem  -out unprotected.p12
 
rm temp.pem

The first command decrypts the original pkcs12 into a temporary pem file. pem is a base64 encoded format. The second command picks this up and constructs a new pkcs12 file. During this, the new passphrase is asked. By simply typing ‘return’ here, it set to nothing. When using unprotected.p12 in the OpenVPN connection, you’re no longer asked for a passphrase.

A word of warning: I do not recommend doing this generally. From my perspective it’s okay, if your unprotected pkcs12 file is protected by other means, e.g. harddisc encryption.

running Groovy on the Nokia N900

March 21st, 2010 Stefan Armbruster 3 comments

My favorite gadget for the last few months is definitely the Nokia N900. It’s a geeky device with a real Linux OS aboard. In opposite to it’s locked down competitors, the N900 runs Maemo, a platform consisting (mostly) of open source software. So I wonder if it’s possible to use Groovy on that. And yes, it is possible! Read more…

Categories: Uncategorized Tags: , ,