Categories
Uncategorized

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.

Categories
Uncategorized

restrict a Grails controller to localhost access only

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

Grails Neo4j plugin 0.2.1 released

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

Grails Neo4j plugin 0.2 released

Today an important update of the Grails Neo4j plugin has been released. Neo4j is a graph database, it’s main concepts are described in brevity in a previous post.  The plugin provides a convenient way to use Neo4j as a persistence layer for Grails domain classes.

The key features / changes of this release are:

  • domain classes managed by Neo4j can now co-existing with traditional domain classes (aka mapped by Hibernate)
  • Upgrade to Neo4j 1.0
  • usage of Grails dependency resolution instead of embedding the jars in /lib directory
  • added a seperate controller to inspect the Neo4j node space
  • major refactoring using AST transformation, just like in the couchdb plugin
  • support for the Neo4j indexer
  • support for non-declared properties
  • support for traversers
Categories
Uncategorized

Customizing Grails data binding with a “groovy” PropertyEditor

When Grails binds data e.g. when the controller’s bindData method is called, it instantiates a GrailsDataBinder to take the action. GrailsDataBinder configures itself with  some basic ProperyEditors. The neat thing is you can extend that behaviour by adding an arbitrary named PropertyEditorRegistrar implementation to the application context. The PropertyEditorRegistrar registers one or multiple PropertyEditors.

A recent use case was the ability to look up some domain instance by a given key and use this for data binding. Coding a seperate PropertyEditor for each domain class would not really be DRY, so I decided to go the groovy way: a DomainClassLookupPropertyEditor:

public class DomainClassLookupPropertyEditor extends PropertyEditorSupport {

    Class domainClass
    String property
    boolean doAssert = true

    String getAsText() {
        value."$property"
    }

    void setAsText(String text) {
        value = domainClass."findBy${StringUtils.capitalize(property)}"(text)
        assert doAssert && value, "no $domainClass found for $property '$text'"
    }

}

The PropertyEditor calls the domain class’ findBy<Property> method to look up the desired instance. The PropertyRegistrar looks like this:

public class MyPropertyEditorRegistrar implements PropertyEditorRegistrar {
    public void registerCustomEditors(PropertyEditorRegistry propertyEditorRegistry) {
        propertyEditorRegistry.registerCustomEditor(Author, new DomainClassLookupPropertyEditor(domainClass: Author, property: "name"))
        propertyEditorRegistry.registerCustomEditor(Book, new DomainClassLookupPropertyEditor(domainClass: Book, property: "isbn"))
    }
}

Last, we need to configure that in resources.groovy:

beans = {
    myEditorRegistrar(MyPropertyEditorRegistrar)
}
Categories
Uncategorized

Solved a little trouble with Hudson and Grails

A few months ago I started to use Hudson for continuous  integration. Installing and running Hudson is very simple and well documented. There’s a plugin for Grails available.

In most of my Grails projects, I’m using the Acegi Plugin. By default, this plugin utilizes EhCache for caching user data. In principal this is a good idea but it comes to trouble when using multiple Grails apps in Hudson. The default configuration uses /tmp/userCache.data for this cache. Since multiple apps use the same cache directory, it’s obvious that we get in trouble.

The most simple solution here is to completely disable the user cache. This can be easily done in grails-app/conf/SecurityConfig.groovy by adding

cacheUsers = false

Another (and probably better) option would be using a more sophisticated cache configuration e.g. by including the application’s name in the cache store dir. Or, even better, disable the cache in development and testing environment and configure it with a unique path name for production.

As mostly always: use the simplest solution that could probably work.

Over and out.

Categories
Uncategorized

Example for using Neo4j with Grails

In reply to my today’s annoncement of the Neo4j Grails plugin, @StigLau asked me to provide an example for using the Neo4j Grails plugin. So here we go:

  1. Create your sample application:
    grails create-app neo4jtest; cd neo4jtest
  2. Add the Neo4j plugin:
    grails install-plugin neo4j
  3. create some sample domain classes:
    grails create-domain-class Author
    grails create-domain-class Book
  4. create a controller for the domain class
    grails create-controller Author
    grails create-controller Book
  5. modify the domain classes:
    import grails.plugins.neo4j.Neo4jEntity
    @Neo4jEntity
    class Author {
        String name
        Date dob
    
        static hasMany = [ books: Book ]
    }

    and

    import grails.plugins.neo4j.Neo4jEntity
    @Neo4jEntity
    class Book {
        String title
        static belongsTo = [author:Author]
    }
  6. modify the controller to use dynamic scaffolding:
    class AuthorController {
        def scaffold = true
    }
    class BookController {
        def scaffold = true
    }
  7. start up the application:
    grails run-app
  8. use it, love it: go to http://localhost:8080/neo4jtest, add some authors and books.
  9. to explore the Neo4j node space created with your grails app, check out Neoclipse.

UPDATE: Use Grails 1.2.1

Categories
Uncategorized

Neo4j Grails Plugin

Today I released the first version of the  Neo4j Grails plugin. The plugin’s goal is to provide an alternative approach for storing Grails domain classes: in the Neo4j database.

Neo4j is a relative new and very interesting approach for persitence in a non-SQLish way. Neo4j is a graph database and uses the concept of

Nodes

A node is the basic building block. It normally represents a “something”, a entity.

Relationships

Relationsships are associations between nodes. Each relationship connects exactly two nodes. Relationsships have a direction: incoming, outgoing or both.

Properties

Each node or relationship might contain a set of properties. A property has a name (String) and a value (primitive datatype). Complex value are not allowed for properties.

This is completely different from the SQL approach. There are no tables, columns, indexes, and other stuff we’ve dealt with for years. Somewhat crucial is the way how to organize the node space. Neo4j gives some advice here.

Neo4j itself uses the AGPL license, the plugin is licensed the WTFPL.

How the plugin works

Using Groovy’s metaprogramming capabilities, the basic CRUD-methods list, save, get and delete are added transparently to each domain class. In addition, each domain instance gets a ‘node’ property referencing the associated Neo4j Node.

For each domain class a subreference node is created related to the reference aka root node. Each domain instance holds a relation to it’s subreference node. For non-primitive properties, either relations to other domain nodes are used or they are converted to strings using the Spring’s PropertyEditor approach.

Aside from this, the plugin starts up and closes the Neo4j database. The database’s path is configured using the grails.neo4j.storeDir property in Config.groovy.

Howto use the plugin

The plugin can be used transparently in a Grails application. The only thing you have to do is to remove the hibernate plugin and install the neo4j plugin:

grails uninstall-plugin hibernate
grails install-plugin neo4j

Add some domain classes and controllers with scaffolding – they should work.

What currently works

  • basic CRUD operations on domain classes
  • one-to-one, one-to-many, many-to-one and many-to-many relations of domain classes
  • the current implementation supports scaffolding
  • Together with the acegi plugin, you can store your user, role and requestmap information in neo4j. Since the default UserDetailsService relies on Hibernate’s SessionFactory you have to use a custom UserDetailsService to get this working.

What’s still missing (and hopefully will be added in upcoming releases)

  • currently all constraints are ignored
  • only a subset of the domain methods are implemented
  • dynamic finders have only a very basic support: just DomainClass.findBy[Property](value) works so far

New planned features

  • SVG controller/views to display the complete object graph, just like Neoclipse does.
  • Gant scripts for automatically snapshotting and restoring the database
  • Criteria queries implemented using Neo4j traversers

Any feedback is appreciated.