Archive

Posts Tagged ‘grails’

New Grails Book by Burt Beckwith

September 27th, 2012 No comments

My new position doesn’t offer me as much opportunity to use Grails as I would like, but jumped at this chance to learn more about it from one of the masters. Programming Grails is early release, but reviews are positive for the details about how grails uses spring and hibernate (and other persistence mechanisms). I just picked up a copy from O’Reilly. Used this discount code to get 50% off – AUTHD. I love retailmenot.com.

Now we’ll see if I ever get around to readying it.

Categories: grails Tags:

Grails 2 Unit Tests – Undocumented Properties

May 15th, 2012 No comments

GrailsUnitTestMixin (and its descendents DomainClassUnitTestMixin, ServiceUnitTestMixin, etc) give your test classes some static and instance variables that aren’t mentioned in the docs yet. You get applicationContext, grailsApplication, config, and messageSource. Previously, if you had code that needed a grailsApplication (such as the JSON configurations), you had to set it up yourself. Now you get it for free. The mixin also implements the shouldFail method from GroovyTestCase so you can keep that functionality even though your tests are now JUnit 4 based.

Categories: grails, Testing, unit test Tags: ,

No Fluff Just Stuff and CANI

May 2nd, 2012 No comments

I attended another great NFJS conference this weekend. This was the first year where I would say that mobile development was one of the leading topic areas. Surprisingly, there wasn’t a single Grails presentation, though Grails was mentioned by several presenters. It seems to have slipped into the area of “we’ll assume you are using Grails if you can since it makes your life much easier” category for now.

In any case, mobile dev was the focus of or was mentioned in 8 of the 11 sessions I attended. The design pattern of implementing REST APIs for your server apps and using a lightweight, MVC javascript library like Backbone or Spine for your front end tied into this. You can use the REST APIs as a service for native mobile apps along with the web apps, and the small size of the JS libraries works well for the limited memory and bandwidth of mobile browsers. Nathaniel Schutta’s JavaScript Libraries You Aren’t Using…Yet presentation is a great overview of some of the most popular libraries.

I must say that the body parts theme is getting a bit out of hand. Besides backbone and spine, there are the templating libraries mustache and handlebars. Walmart has developed backbone extensions called thorax and lumbar. Since CoffeScript is also a part of this mix, I thought I should take this whole clever name scheme to the next level -

I hereby announce the CANIjs library – Caffeinated Nerve Impulses ™. I don’t know what it’s going to do yet, but as soon as the jitters where off, I’ll think about it. Probably something to do with eventing (nerves, signals, events, etc). I do know that if you use it in the wrong way, everyone will say “That’s un-cani.”

Categories: grails, javascript, REST Tags: , ,

Grails Plugins Presentation

February 17th, 2012 No comments

I presented at the DC GUG meeting a couple of days ago, this time on Grails plugins. I wanted to go beyond the normal “these are the basics of Grails” intro to cover the main points of what you need to do to get a real project up and running and how to maintain it. I covered things like authentication, fixtures, tests and test data sets, audit logging, remote debugging, and monitoring. A bit too aggressive for an hour-long presentation (okay, so way too aggressive), but folks seemed to enjoy it. Hopefully I’ll have another opportunity to present it so I can tune it up a bit. For now, the slides are on slideshare and the basis for the sample project is on github. I’ll try to breakout the key points into individual posts soon.

Categories: grails, groovy Tags: , ,

Spring security: CAS + LDAP

December 21st, 2011 No comments

After getting straight LDAP authentication to work with the spring-security-ldap plugin, I moved on to the next requirement which was integrating with CAS. Like many projects before us, we need to do authentication through CAS and then follow up authorization (i.e. role checking) through LDAP. The authentication part was easy thanks to the spring-security-cas plugin. However, there are two mildly annoying issues with the plugin as a whole:

First, once it is installed, you can’t turn it off (at least, not in development mode). The value of the cas.active setting is ignored unless you deploy as a war. There is already a bug filed for this and someone has submitted a simple patch. You can either build the patched plugin, or just tweak the few lines directly in your project’s copy of the plugin.

The second issue relates to auto-creating user accounts. I posted about using an AuthenticationEvent listener to do this last week. Unfortunately, this will not work with the default configuration of the CAS plugin. The plugin does not override the userDetailsService so you get the default GormUserDetailsService. That class will throw a “user not found” exception if there is no local user domain object for the given user name. If you have no need for role information (authorities in spring-security speak), then you can simply plug in a simplistic userDetailsService like this one:

import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.User
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.springframework.security.core.authority.GrantedAuthorityImpl

/**
 * Dumb service which just returns a UserDetails object with the username set.
 * @author esword
 */
class EmptyUserDetailsService implements GrailsUserDetailsService {

    /**
     * Taken from GormUserDetailsService: Some Spring Security classes expect at least one 
     * role, so we give a user with no granted roles this one which gets past that restriction
     * but doesn't grant anything.
     */
    static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]

    UserDetails loadUserByUsername(String username, boolean loadRoles) {
        return loadUserByUsername(username)
    }

    UserDetails loadUserByUsername(String username) {
        new User(username, '', true, true, true, true, NO_ROLES)
    }
}

You could extend InMemoryUserDetailsManager if you didn’t want to re-create the UserDetails all the time, or wrap a GormUserDetailsService to first check if you have a local account and return info from that if so. I just threw together this class so that I could verify that the rest of the authentication process with CAS worked.

LDAP Integration

If you do need role information from LDAP, you will need to add a few more beans to your resources.groovy file. Someone posted a thread on the grails-dev mailing list about a year ago with the core information for this configuration. However, the example they give hard-codes the LDAP connection settings in the bean definitions themselves. Since our app is deployed with the LDAP plugin (it is turned off if CAS is turned on), I wanted to use the same property settings so that we could easily toggle back and forth between plain LDAP and CAS. Here is the revised bean configuration within resources.groovy:

    // If CAS is active and if ldap is configured, do UserDetails lookup from ldap to get the roles.
    // All of these setting names and how they are used come from reading the SpringSecurityLdapGrailsPlugin.groovy
    if (application.config.grails.plugins.springsecurity.cas.active) {
        def config = SpringSecurityUtils.securityConfig
        if (config.ldap.context.server) {
            SpringSecurityUtils.loadSecondaryConfig 'DefaultLdapSecurityConfig'
            config = SpringSecurityUtils.securityConfig

            initialDirContextFactory(org.springframework.security.ldap.DefaultSpringSecurityContextSource,
               config.ldap.context.server){
                userDn = config.ldap.context.managerDn
                password = config.ldap.context.managerPassword
            }

            ldapUserSearch(org.springframework.security.ldap.search.FilterBasedLdapUserSearch,
               config.ldap.search.base,
               config.ldap.search.filter,
                initialDirContextFactory){
            }

            ldapAuthoritiesPopulator(org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator,
                initialDirContextFactory,
               config.ldap.authorities.groupSearchBase){
                  groupRoleAttribute = config.ldap.authorities.groupRoleAttribute
                  groupSearchFilter = config.ldap.authorities.groupSearchFilter
                  searchSubtree = config.ldap.authorities.searchSubtree
                  rolePrefix = "ROLE_"
                  convertToUpperCase = config.ldap.mapper.convertToUpperCase
                  ignorePartialResultException = config.ldap.authorities.ignorePartialResultException
            }

            userDetailsService(org.springframework.security.ldap.userdetails.LdapUserDetailsService,
                ldapUserSearch,
                ldapAuthoritiesPopulator){
            }
        }
        else {
            //Dummy service if LDAP isn't set up
            userDetailsService(EmptyUserDetailsService)
        }
    }

Ideally, I would like to be able to keep the LDAP plugin turned on in an “authorization only” mode so that I could use the userDetailsService configuration directly from it. That is not yet possible with the plugin, so this is the next best thing. You still avoid having to write any new code in your application and at least get the benefit of being able to fall back on the default property settings for the LDAP plugin.

Auto-create User Domain Object with Spring Security

December 12th, 2011 No comments

For those who skip straight to the last page of a book to see how it ends – See Chap 7. Events of the spring-security-core plugin documentation.

For those who like a little more detail…

I just moved our grails app from using the shiro plugin to using the spring-security plugin(s). I like shiro’s filter-based config, but all the pre-built extension modules that Burt Beckwith has put together for spring-security (LDAP, CAS, etc.) makes it much easier for us to support the range of environments in which we have to deploy.

The one feature which took me a little while to figure out was how to have our app auto-create a user domain object when it is using an external authentication source. For example, say an instance of our app is configured to authentication against an LDAP server. The app has a MyUser class that holds local settings for users like preferences, documents, etc. When a user signs in for the first time and makes it past the authentication step, we need to automatically create a MyUser instance and associate it with the LDAP username. With the shiro-based authentication, we did this in the controller method which handled the authentication itself. Spring security works a little differently and there isn’t a central, post-authentication landing point.

If your app is always deployed with the same type of authentication (e.g. always with LDAP), you could put the persistence code into a custom UserDetailsService. There are several posts on the web that discuss creating a custom UserDetails object and a corresponding service for it, so this was the first approach I looked at. Chapter 11 of the spring-security-core plugin’s user guide has info on it as well. The primary shortcoming is that you can’t chain together UserDetailsServices. You have to implement one for each form of authentication with which you want to work.

If your app must work with a variety of authentication methods, it is easier to register a listener with Spring Security. Chapter 7 of the plugin guide discusses the two ways to do this. I found that handling the AuthenticationSuccessEvent was all I needed. Since we already had a Grail’s service that handles various user-related tasks, the listener object was dirt simple:

import org.springframework.beans.factory.InitializingBean
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.context.ApplicationListener
import org.springframework.security.authentication.event.AuthenticationSuccessEvent

class MyAuthenticationEventListener implements ApplicationListener<AuthenticationSuccessEvent>, InitializingBean, ApplicationContextAware {
    ApplicationContext applicationContext
    def userService

    void afterPropertiesSet() {
        userService = applicationContext.getBean('userService')
    }

    void onApplicationEvent(AuthenticationSuccessEvent e) {
        //the principal field of the source object is a UserDetails object of some form.  
        //The spring-security API contract guarantees that at least the username field will be populated. 
        userService.createUser(e.source.principal)
    }
}

Since the whole class really just has one line of “functional” code, I could have used the closure-based approach described in section 7.3 of the user guide. I just prefer to keep true code out of the Config.groovy file.

Then, within the UserService.createUser method, the key lines look something like this:

    def user = MyUser.findByUsername(userDetails.username)
    if (!user)
    {
        MyUser.withTransaction {status ->
            user = new MyUser(username:userDetails.username /*, set any other props you want to store locally*/)
            user.save(flush: true, failOnError:true)
        }
    }
    return user

One note of interest – without the withTransaction statement, you may get an exception stating that no hibernate session exists and one cannot be opened. The withTransaction closure wraps this up nicely for you.

Running latest Groovy from Maven

April 5th, 2011 2 comments

Say you have a groovy-project that you build with maven.  You use the org.codehaus.gmaven:gmaven-plugin to compile your groovy code and run groovy tests without a problem.  Then you add some features or tests that need groovy 1.7.  You add the proper dependency and version to the <dependencies> section of your pom, run your test… and watch it blow up because the gmaven-plugin defaults to using groovy 1.6.  So you dig around on the web and find references for how to use the <providerSelection> tag of the gmaven-plugin to get your code compiled with 1.7 and to use 1.7 when running tests.  Things seem good.  Until…

You add a feature that requires some version of groovy greater than 1.7.4 (the version included with the latest gmaven-plugin, 1.3).  In my case, I used the @Delegate annotation with some inheritance in a test configuration and hit a bug that was fixed in groovy 1.7.6.  No matter what version I used in my dependencies section, my tests were executed under groovy 1.7.4.  I finally came up with the configuration below which let me run with a different groovy.  Note that it made no difference what I included in the dependencies section.  The gmaven-plugin configuration appears to be completely independent of that.

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.3</version>
    <configuration>
        <providerSelection>1.7</providerSelection>
        <!-- This is only used if you want to run a groovy script from the command line using maven -->
        <source>${groovy.script}</source>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>testCompile</goal>
            </goals>
        </execution>
    </executions>
    <!-- This block is required in order to make the gmaven plugins use a groovy other than 1.7.4.
     This is independent of the groovy entry in the dependencies section.  This does not affect the class path.

     What is interesting is that there must be both the gmaven.runtime entry with the explicit excludes
     and the additional dependency on whatever version we do want to use.  If you exclude the former,
     it will throw an exception. -->
    <dependencies>
        <dependency>
            <groupId>org.codehaus.gmaven.runtime</groupId>
            <artifactId>gmaven-runtime-1.7</artifactId>
            <version>1.3</version>
            <exclusions>
                 <exclusion>
                     <groupId>org.codehaus.groovy</groupId>
                     <artifactId>groovy-all</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>1.7.6</version>
        </dependency>
    </dependencies>
</plugin>

Validation differences between Grails 1.1 and 1.2

June 9th, 2010 No comments

…or My Penance For Ignoring Validation Errors…

We recently updated our app from Grails 1.1.1 to 1.2.2. (We wanted to move all the way to 1.3.1 but since we build with maven, we finally decided to wait until a new grails-maven plugin is released. See GRAILS-6327.) During the upgrade, we hit two particularly annoying issues related to persistence and setting up associations.

The first involved a belongsTo relation like this:

class AppUser {
    UserPrefs prefs = new UserPrefs()
}

class UserPrefs {
    static belongsTo = [user: AppUser]
}

This worked under Grails 1.1, but under Grails 1.2 the prefs object was not getting persisted when the user was saved. Other belongsTo relations, both one-to-many and one-to-one worked as expected. We finally discovered that using the short form of the relation notation did work:

static belongsTo = AppUser

This post provided a clue as to where the problem may be. The user property of the Prefs object is not automatically set because the relationship is one-to-one. (At least, it is not automatically set all the time. If we load an AppUser object with Hibernate, it appears that the user property is set in the UserPrefs object. Go figure.) Under Grails 1.1, having a null user was apparently fine. My guess (based on the second error we hit, below) is that any validation errors caused by the child object were not stopping the save of the parent object. Grails 1.2, on the other hand, does care about the child object validation, though I could never get it to report anything in the errors property of either the parent or child object.

In order to work around the issue, I loosened the constraints on UserPrefs a little:

class UserPrefs {
    static constraints = {
        user(nullable: true)
    }
    static belongsTo = [user: AppUser]
}

With this change, cascading persistence works. Given, it’s not an ideal solution, but it does let us have access to the user property if needed.

What made this extra confusing is that we have a similar relationship in another set of classes that worked without a problem. The only difference there is that the child class is not automatically created with a static initializer as is done in for the prefs property in AppUser. It is always explicitly set into the owning object. I’ve run out of time to pursue this one further, so I don’t have a final answer. Anyone else out there have more insight into this?

The second persistence issue related to this section of code in the update method of one of our controllers:

def update = {
    def hubMap = HubMap.get(params.id);
    hubMap.properties = params;
    if (hubMap.save()) {
        ...add success message to response...
    } else {
        ...add failure message to response...
    }
    ...
}

Again, the code worked fine under Grails 1.1.1, but the save call failed under 1.2.2. Unfortunately, there was a hole in both our unit and integration tests for this method, so we didn’t catch it until much later in the release cycle.

Was the JSON conversion in the controller’s get method that generated the original data for the browser different? Nope.
Had the behaviour of the properties meta-method changed? Nope.

The difference is in how Grails handles any existing validation errors on a domain object when you call save(). In our case, the JSON that was being sent to the controller (via a Prototype AJAX call) contained two properties that were references to other objects. The javascript object conversion in the browser was not setting these properties in a meaningful way for the AJAX call; they were both coming across with the string value [object Object]. Since these fields are never updated in this particular workflow, we had never checked what was happening to them. Grails obviously could not convert from the string values to the proper objects, it ignored the values and set two errors on the domain object to record them. However, we didn’t check for errors after the properties call. We went straight to the save call. Under Grails 1.1, deep within the saving sequence in a random class called AbstractDynamicPersistentMethod, you come across this bit of code:

doInvokeInternal(...) {
    ...
    Errors errors = new BeanPropertyBindingResult(target, target.getClass().getName());
    mc.setProperty(target, ERRORS_PROPERTY, errors);
    ...
}

Any existing errors are replaced with a fresh, clean BeanPropertyBindingResult object, wiping out the error information. We never spotted it because we never expected the properties with errors to change anyway. That hole has been closed in Grails 1.2:

doInvokeInternal(...) {
    ...
    Errors errors = setupErrorsProperty(target);
    ...
}

The new setupErrorsProperty call will copy out existing errors. We put in a few adjustments to not attempt to update those properties and all is well.

So there you have it. A couple of gotchas in the upgrade path for grails. Hope this saves some folks from banging their head against the wall.

Grails, Maven, packaging, and skipTests fun

April 22nd, 2010 No comments

The grails maven plugin honors the maven.test.skip option (which turns off compiling and executing tests), but not the skipTests option (which only turns off executing tests). This means that you cannot easily create a package with test classes in it without running all of the tests. I finally come up with a close work around:

mvn clean grails:exec install -Dcommand=test-app -Dargs="-unit DoesNotExist" -Dmaven.test.skip=true

By explicitly listing the test-app command but specifying a test that does not exist, I was able to get the unit tests to be compiled. Since I only needed some common testing files in my package, this works for me. If someone wanted to package both the unit and integration tests, I don’t think this would work. I filed a new issue in the Grails Jira to try to get a real resolution.

Grails+Maven+GeoTools+PdfBox = PITA

March 20th, 2010 No comments

Here’s a bit of maven-voodoo for you. If you have a Grails (1.1.1) app that is built with Maven (2.1) and you try to link in GeoTools (specifically the gt-xsd-core module) and you try to bring in PdfBox as well, you will get really fascinating class loading and linking problems revolving around various XML pieces. I finally found two different ways to get rid of the errors. For those who like to cut to the chase, I’ll list the solutions first and then explain a bit more what errors I was seeing.

Solution #1: Exclude, exclude, exclude

If you don’t need commons-jxpath, you can add these three exclusions to the gt-xsd-core dependency declaration.

    <dependency>
        <groupId>org.geotools.xsd</groupId>
        <artifactId>gt-xsd-core</artifactId>
        <version>${gt.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-jxpath</groupId>
                <artifactId>commons-jxpath</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis-xerces</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

This at least works for me given the subset of geotools functionality I am using (primarily encoding and parsing OGC Filter objects to and from XML so I can persist them with Hibernate). It is still pulling in xercesImpl and that appears to be enough, at least to get my unit and integration tests working.

Solution #2: Using Dependency Management

If you need the commons-jxpath functionality in gt-xsd-core, add this to your dependencyManagement section of your POM:

    <dependencyManagement>
        <dependencies>
            <!-- The gt-xsd-core tries to bring commons-jxpath 1.2 in.  That messes up the maven junitreport plugin for
            some reason (like links to a version of xalan or xml-apis or something.  The 1.3 version doesn't have that
            issue. -->
            <dependency>
                <groupId>commons-jxpath</groupId>
                <artifactId>commons-jxpath</artifactId>
                <version>1.3</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

and then keep the exclusions for the xml-api artifacts as above:

    <dependency>
        <groupId>org.geotools.xsd</groupId>
        <artifactId>gt-xsd-core</artifactId>
        <version>${gt.version}</version>
        <exclusions>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis-xerces</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

This is what I have setup in my POM right now because I think I might need jxpath soon. I also tried adding a node in dependency management to use the 1.3.03 version of xml-apis rather than 1.0b2 (which is what was pulled in by default), but that doesn’t appear to make any difference. I still had to have the 2 exclusions under gt-xsd-core for things to work.

So what was the problem?

Now, a little more about the problems I had. I had two types of errors:

Maven junitreport conflict – When I added the dependency for gt-xsd-core and then ran my unit tests using the maven grails plugin (mvn grails:exec -Dcommand=test-app -Dargs="-unit"), my tests would run fine (except for one which I’ll detail below), but then I would get this error when the junitreport plugin tried to run its XSL transform:

Embedded error: java.lang.reflect.InvocationTargetException
Provider org.apache.xalan.processor.TransformerFactoryImpl not found

Normally I would suspect that the geotools dependencies brought in some new version of the xalan library and it didn’t have an old class that the junitreport plugin required. To check this, I compared the output from both maven dependency:classpath and dependency:tree between my trunk branch and the branch where I had added the geotools dependencies. The comparision showed that only one one dependency had changed between the branches; a newer version of commons-pool was used. All other classpath mods were new libraries that were not previously included at all. In fact, xerces and xalan was not included by the trunk branch at all. I am sure that someone with more recent experiences with xml-apis, xerces, and xalan knows exactly what was happening. My guess is that by including the xml-apis-xerces dependency, some piece of the junitreport plugin thought that it could use xalan as opposed to some other XSL lib that it would use when xerces was not present. This is supported by the fact that if I added xalan as a dependency, the error went away. If I have time, I’ll look at the docs for junitreport one of these days and see if that sheds some light on the issue.

PDFImageWriter/NodeList conflict – One of the unit tests exercised our use of PDFBox. If I did not have the above exclusions and I include xalan, this error appeared during the PDFImageWriter constructor:

java.lang.LinkageError: loader constraint violation: loader (instance
of <bootloader>) previously initiated loading for a different type with
name "org/w3c/dom/NodeList"

I haven’t tracked down exactly why this linkage conflict occurred. The bizare thing is that I inserted some link-loading debugging that I used in the past to try to see where NodeList was coming from in both my trunk and geotools-enabled branches:

def clazz = org.w3c.dom.NodeList.class
def codeSource = clazz.getProtectionDomain().getCodeSource();
println ("Source Location: " + codeSource);

In trunk (i.e. no geotools and working fine), it came back as null; NodeList wasn’t loaded at all. In the geotools-enabled branch, it would load (from xerces, I think), but then had that conflict.

At this point, I have a solution (two, actually) and have spend pretty much a whole day researching various paths, so I need to wrap it up and move on. If anyone has a better solution or thoughts as to why exactly there were problems, feel free to comment.

One last note in case there is any confusion from me mentioning xalan so much – I did not end up adding a dependency for xalan to my POM. Just using the exclusion statements listed above solved the issue.