Showing posts with label grails. Show all posts
Showing posts with label grails. Show all posts

Tuesday, 13 May 2014

Executing SQL queries with GORM

Yesterday at work somebody asked me how to execute a SQL query through GORM. I didn't remember at the moment how exactly how to do it, but I remembered that Hibernate's Session class had a method called executeSQLQuery.

This is a silly example to show how we have done it. Lets say you have a domain class 'MyDomainClass' and inside a service (MyService) you need to execute a given SQL query. It could be like this:

  class MyDomainClass {
      String name
      Integer age
  }

  class MyService {
      Integer getAgeByExecutingSQL() {
         return MyDomainClass.withSession { session ->
            session.executeSQLQuery("select age from my_domain_class").get()
         }
      }
  }

Accessing Hibernate session through withSession method we can access the method I was mentioning above. Then is just a matter of creating a valid SQL and of course keep in mind that the query doesn't return domain class instances but arrays of data.


Sunday, 27 April 2014

Searchable plugin: Search by a domain relationship

I don't remember last time I used Searchable Plugin, there must be like a year or so. Anyway I was trying to map a Product/I18nProductDescription domain classes to be able to search by the product description and then return the product id in order to build the link to the product detail.
I was using the default configuration and doing the queries through searchable controller to test my mappings. These were the initial mappings:
class Product {

    static hasMany = [descriptions: I18NDescription]   

}

class I18nDescription {

   static belongsTo = [product: Product]
   static searchable = true

   Locale locale
   String title
   String description

}

The problem was that if you map as "searchable" only I18nDescription, the index doesn't store the relationship, then you won't be able to do "productDescription.product.id" and you'll get a NPE (I guess this is caused because instances are not taken from the hibernate session but from lucene index).

I read the documentation and I found the "component" term.

class Product {

   static hasMany = [descriptions: I18NDescription]   
   static searchable = {
      descriptions component: true
   }

}

class I18nDescription {

   static belongsTo = [product: Product]
   static searchable = {
      product component: true
   }

   Locale locale
   String title
   String description

}


So I mapped my to domain classes as components of each other. But if I stopped there I would get double of results, because both domain classes are pointing to each other right? So I need to "disable" for searching one of them. To do so, one of them should have an option to tell it's not going to have it's one index but is going to be part of another search index.

class Product {

   static hasMany = [descriptions: I18NDescription]   
   static searchable = {
      descriptions component: true
      mapping {
        root false
      }
   }

}

class I18nDescription {

   static belongsTo = [product: Product]
   static searchable = {
      product component: true
      mapping {
        root true
      }
   }

   Locale locale
   String title
   String description

}

That way you can search by title or description and be able to get the reference of the product without having to do anything else.

References

Thursday, 28 November 2013

Testing a command object without a controller

Sometimes you just want to test a command object in a Spock specification without having to use @TestFor with an existing controller class passed as an argument.

Back in time (last week or so XD ) I used to do it this way

import spock.lang.Specification
import grails.test.mixin.TestFor

@TestFor(SomeControllerClass)
class MyCommandObjectSpec extends Specification {
   // ... your stuff
}

But the thing is that Grails wraps all its mocking functionality in "mixins"  and the way you can apply those mixins is through the @TestMixin annotation.

Normally you don't notice this behavior because the annotation @TestFor does that under the hood, but if you had to apply controller mocking behavior in your specification you should be using the @TestMixin annotation with the ControllerUnitTestMixin directly:

import spock.lang.Specification
import grails.test.mixin.TestMixin
import grails.test.mixin.web.ControllerUnitTestMixin

@TestMixin(ControllerUnitTestMixin)
class MyCommandObjectSpec extends Specification {
  //... your stuff
}

Happy testing :)

Friday, 8 November 2013

Exposing Grails URLMappings as JSON

I'm currently working in a REST API. The endpoints are increasing really fast and we haven't decided how to document it yet. Until that happens I was wondering it would be nice to know how to access URLMappings data at runtime.

We've created a controller where the URLMappings structure is exposed. Only thing we have to do is to access to "grailsApplication" and "grailsUrlMappingsHolder" beans.

import grails.converters.JSON

class RootController extends BaseApiController {
   
      def grailsApplication
      def grailsUrlMappingsHolder
  
      def listApiUrls() {
  
          def urlMappings = grailsUrlMappingsHolder.urlMappings.collect { [
  
                  name: it.mappingName?:'',
                  url: it.urlData.logicalUrls.first(),
                  methods: it.parameterValues,
                  parameters: it.constraints.propertyName
 
          ] }
  
  
          def root = [
  
              metadata: grailsApplication.metadata,
              urlMappings: urlMappings
  
          ]
  
          render root as JSON
  
      }
  
  }    

We put all the information in a map and convert it to JSON and....

{
  "metadata": {
    "app.version": "0.1",
    "app.grails.version": "2.2.4",
    "app.name": "yump-api"
  },
  "urlMappings": 
  [
    {
      "name": "",
      "url": "500",
      "methods": {
        "action": "handleValidationException",
        "controller": "exception"
      },
      "parameters": 
      [
      ]
    },
    {
      "name": "",
      "url": "500",
      "methods": {
        "action": "handleApiException",
        "controller": "exception"
      },
      "parameters": 
      [
      ]
    }...


Here we have a basic version of a API documentation with a few lines :)

Tuesday, 20 August 2013

Grails pitfalls: Don't do flush:true when you actually want a transaction (and II)

Today somebody at work ask me about some statements I made in the previous entry "Grails pitfalls: Don't do flush:true when you actually want a transaction".

He thought that when doing

company.save(flush:true)

It didn't matter it was within or outside a transaction, the transaction will eventually commit the transaction event tough there were an exception on the way.

I didn't know that either until I worked in a project where I needed to return the number of persisted items just after persisting a new one but just before doing some critical calculation that could raise an exception and eventually rollback the entire transaction.

Think about it, if the domain wasn't persisted and "committed" (notice the quotes) I couldn't count the right number of persisted entities, but What if the subsequent calculation failed? I had already saved the domain class even tough it was incorrect to do so. It was a dead alley until I had a conversation with a senior engineer. More or less it was like the following:

Mario: Ciaran I can't save the instance and see it in the following line
Ciaran: Then flush:true the save statement
Mario: What? But save(flush:true) commits the statement.
Ciaran: Nop, it makes the instructions visible for the rest of the transaction
Mario: Ummm, I don't quite follow you but let's test it anyway.

That was the most difficult task, How to test that assertion?

Let's say we have the following service method:

    def saveAndFail(Company company) {
      company.user = springSecurityService.currentUser
      company.save(flush:true)
      throw new IllegalArgumentException("Ahhhh")
    }

I did the following test:
   package whatever

   import static org.junit.Assert.assertThat
   import static org.hamcrest.CoreMatchers.notNullValue
   import static org.hamcrest.CoreMatchers.is
     
   import grails.plugin.spock.IntegrationSpec
   import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
         
  class CompanyServiceFlushIntegrationSpec extends IntegrationSpec{
       
    def companyService
         
    def "Test flush:true"(){ 
      setup: "Building a valid company instance"
        def user = validUser.save(failOnError:true,flush:true)
        def company = new Company(
          user: user,
          name: "name",
          companyCode : "companyCode"
        )
      when:"Saving a valid company instance"
          def savedCompany = SpringSecurityUtils.doWithAuth("username"){
              companyService.saveAndFail(company)
          }
      then: "The result should be the saved company"
        thrown(Exception)
        assertThat(Company.count(),is(0))
    }
        
    def getValidUser(){
      def validUser = new ApplicationUser(
        name: "name",
        username: "username",
        password: "password",
        locale: Locale.getDefault()
      ) 
    }       
        
 }


But it didn't work. I got:

Failure:  Test flush:true(whatever.CompanyServiceFlushIntegrationSpec)
|  java.lang.AssertionError: 
Expected: is <0>
     got: <1>

Let's analyze how the test worked. First, we should know that by default integration tests are transactional by default. That means that at the end of every test method if there is any transaction it will be rolled back....AT THE END. In our method we threw an exception "catched" by our thrown(Exception) statement. So there was no rollback there, so it makes sense that at line number 28 the assertion fails because the exception has not been propagated outside the test method, so that the count statement is aware of the persisted company because of the flush:true statement.

But I want to prove that the transaction actually does a rollback because of the exception we put on purpose. We can only do that establishing our own transaction scope. To do this is neccesary to declare the test as "not transactional", and then to wrap the service's invocation as it will happen at runtime.

   package whatever

   import static org.junit.Assert.assertThat
   import static org.hamcrest.CoreMatchers.notNullValue
   import static org.hamcrest.CoreMatchers.is
     
   import grails.plugin.spock.IntegrationSpec
   import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
         
  class CompanyServiceFlushIntegrationSpec extends IntegrationSpec{
       
    static transactional = false

    def companyService
         
    def "Test flush:true"(){ 
      setup: "Building a valid company instance"
        def user = validUser.save(failOnError:true,flush:true)
        def company = new Company(
          user: user,
          name: "name",
          companyCode : "companyCode"
        )
      when:"Saving a valid company instance"
          Company.withTransaction{
            def savedCompany = SpringSecurityUtils.doWithAuth("username"){
              companyService.saveAndFail(company)
            }
          }
      then: "The result should be the saved company"
        thrown(Exception)
        assertThat(Company.count(),is(0))
    }
        
    def getValidUser(){
      def validUser = new ApplicationUser(
        name: "name",
        username: "username",
        password: "password",
        locale: Locale.getDefault()
      ) 
    }       
        
 }


And voila!

| Tests PASSED - view reports in...

I had no companies saved even though I used flush:true.

Thursday, 8 August 2013

Grails pitfalls: Controllers and how to reuse code


There're a lot of common repetitive tasks that arises when coding controllers, services...etc. I've seen many times repeating code that has to do with pagination.

def list() {
    params.max = params.max ?: grailsApplication.config.list.default.maxElements
  
    def result = GeographicArea.findAll(params)        
    render view: 'list', model: [list:result]
}

It's really painful to repeat the code to establish default maximum or minimum number of results every time we have to deal with some pagination. It's easier to create a method maybe in some parent class, to be able to call it from those classes inheriting that class. We can use inheritance, mixins, AST...etc.

The pros of using inheritance is you have the behavior because of compilation (AST would be the same here) while doing Mixins would have a performance penalty.

Many times my favorite choice is to inherit a BaseController where I include most of the boilerplate code.
class BaseController{
  
 def configurationService

    def getPaginationParams(){
      if (!params.max){
        params.max = configurationService.defaulMaximumListElements()
        //params.min...etc
      }
      params
    }
  
  }

And then I make the child class to extend the BaseController class
class GeographicAreaController extends BaseController{  
    def list() {    
       def result = GeographicArea.findAll(paginationParams)        
       render view: 'list', model: [list:result]
      }   
}

Wednesday, 7 August 2013

Grails pitfalls: Inheriting a parent class doesn't mean a new table


Sometimes we need to audit our domain classes. And sometimes you open a couple of classes and realize auditing fields have been copied in every class:

  class Product{
     Date dateCreated
     Date lastUpdated
  }

  class Category{
     Date dateCreated
     Date lastUpdated
  }

As you may imagine, this could improve a lot. But most of newbies don't want to create a new class and make the previous classes inherit from it because they think they will be creating a new table.

But... Did you know you can inherit from a class without creating a new table?

The solution is really simple, the parent class should be in src/groovy and it should be an abstract class. Then you can extend that class. The child class will have all the parent's fields but without the penalty of having a new table.

  // src/main/groovy/myapp/BaseEntity.groovy
  abstract class BaseEntity{
     Date dateCreated
     Date lastUpdated
  }

  // grails-app/domain/myapp/Product.groovy
  class Product extends BaseEntity { }

  // grails-app/domain/myapp/Category.groovy
  class Category extends BaseEntity{ }

Grails pitfalls: Don't do flush:true when you actually want a transaction


Putting persistence code in controllers leads to poor maintenance, reduces the chance of reusing code, and makes controllers extremely hard to test.

One of the first problems a junior programmer experience is to realize the domain class hasn't been saved when he/she expected.

After explaining to them the best way of approaching this type of situations is to put the persistence code in the service layer, they ignore you because they find they can force the commit doing:
  product.save(flush:true)
For what else would be this parameter for? (Sarcasm ;)) If you were only saving a given instance without any relationship...still I wouldn't do that. At least forget about the use of flush:true in that context and use withTransaction:
  Product.withTransaction{
    product.save()
  }
I can see a transaction going on here. Let's say we have two given transactions trying to do something at once.
  Product.withTransaction{
    product.status = ACTIVE
    product.save(flush:true) // without this line the total number will be all of them but this one
    Product.countByByStatus(ACTIVE)
  }
In the previous code without forcing flush:true we would have been omitting the product we were saving in our transaction. First time you see this code you could be thinking, OMG they are committing before the end of the transaction.

Sort answer would be: we ARE NOT committing anything yet, we are sending to the database all instructions until this point (flushing) allowing other transactions in their way to see the our transaction status. If something goes wrong before the transaction ends then changes won't persist.

The problem is that when there's no transaction boundaries the default behavior of flush:true is to commit changes. But if you do establish the boundaries, we would expect the commit/rollback to happen once we exit the transaction's scope.

UPDATE: Somebody at work asked me how to prove this statement. I've created an entry to explain this a little bit more.

Using flush:true the way people normally use it is not right, but is even funnier when they realize they can't do

product.delete(flush:true)

All these could have been avoided if people were used to put their persistence code in services. There are a couple of benefits when using services:

  • You no longer have to worry about opening and closing a transaction. Convention over configuration.

A simplistic view of transactions in Grail's services would be that by default the code within a service's method is executed within a transaction. If the method throws an exception then that code will be rolled back. If everything went ok then all changes will be commited. Although you could but now you don't have to declare explicitly the boundaries of the transaction.
class ProductService{
   def addProductToCart(Product p, Cart c){ // transaction starts here

      //... code within a transaction

   } // transaction ends here (if everything went ok ;) )

}

EXPLANATORY UPDATE:

To be accurate the transaction begins not at the beginning of the method but at the service's invocation time. What does it means? It means that when you're invoking a service's method let's say from the controller, a Spring interceptor, intercepts the call and wraps that call inside a given transaction scope.

One more thing to keep in mind is that the default propagation of transactions is REQUIRED, that means that if we're calling a transactional service's method from another transactional method the latter uses the former transaction scope, or in cause there were none it creates a new one. That explains why we can call some other service methods from our service method without committing previous statements, because there were a pre-existent transaction.

You can always change the default propagation policy using the @Transactional annotation from Spring in your service methods, or using Spring AOP advices to configure transactional scopes.

Anyway if you want to dive into this topic please read "Spring Declarative Transaction Management".
  • It keeps separated your view logic (controllers) from your persistence code (services)

It's clear that less code is always easier to review. Hence if you could keep separated view logic from business logic everything starts looking clearer.  Let's see an example:

If you have the following code:

class ContractController{

  def saveContract(Contract contract,Address address){

    if(contract.validate()){       

       contract.deliveryAddress = address.save(flush:true)   
       contract.save(flush:true,failOnError:true)  

       render(view:'ok')    

    } else {

       render(view:'ko')

    }

  }

}

If you had to unit test this code you should have to mock every domain class behavior (Contract and Address), and sometimes that's really a pain in the ass. Besides the fact that the address could have been saved without succeeding on doing the same with the contract instance. That type of inconsistencies are really dangerous.

Wouldn't be better to split the code like this:

class ContractController{

  def contractService 

  def saveContract(Contract contract,Address address){

    if(c.validate()){   

       contractService.saveContract(contract,address)
       render(view:'ok')    

    } else {

       render(view:'ko')

    }

  }

}

class ContractService{

   def saveContract(Contract c,Address address){

       c.deliveryAddress = address.save()
       c.save(failOnError:true) 

   }

}

Now is easier to mock the service's method, and you only have to focus on testing the view logic.

Friday, 2 August 2013

Grails Tip: Different URL depending on user's role

"We need to redirect users depending on their roles". OMG how I was supposed to do this? Well after doing some search on the usual site, I found this:

http://omarello.com/2011/09/grails-custom-target-urls-after-login/

My solution is based on the previous blog entry. The only thing I've added is using Config.groovy to register different ROLE/URL cases. I thought it worthed sharing it.

Let's say we want to redirect users with role ROLE_MANAGER  to /users/search and users with role ROLE_PROVIDER to /invoices/search. So I came up with the following lines in my Config.groovy

authenticationurl{
 mappings{
  ROLE_MANAGER.controller='users'
  ROLE_MANAGER.action='search'
  ROLE_PROVIDER.controller='invoices'
  ROLE_PROVIDER.action='search'
 }
}


The nice thing about configuration files in Grails is that you can build maps just sharing the same root, in other words, I can ask which controller and action should be used for a manager accessing to the key ROLE_MANAGER:

def map = authenticationurl.mappings.ROLE_MANAGER
def controller = map.controller // 'users'
def action = map.action // 'search'


Taking into account that premise, I built my own AuthenticationHandler. This handler takes the authenticated user's role and use it as key to look for its correspondent controller/action:

import org.codehaus.groovy.grails.plugins.springsecurity.AjaxAwareAuthenticationSuccessHandler
import org.springframework.security.core.Authentication

import org.apache.commons.logging.LogFactory

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

import static org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils.ifAllGranted


class AuthenticationHandler extends AjaxAwareAuthenticationSuccessHandler {

 static log = LogFactory.getLog(AuthenticationHandler)

 def grailsLinkGenerator 
 def configurationService
 def springSecurityService

 @Override
 protected String determineTargetUrl(HttpServletRequest request,HttpServletResponse response) {
  /* Taking configuration mappings */ 
  def authMappings = configurationService.authenticationHandlerUrlMappings
  def defaultUrl = super.determineTargetUrl(request, response)
  if(log.isDebugEnabled()){
   log.debug("Default URL: $defaultUrl")
  }
  /* Taking the first match or the targetUrl  */
  return authMappings.findResult{k,v->
   if(ifAllGranted(k)){
    /* Here's better to get it absolute */
    grailsLinkGenerator.link(v << [absolute:true])
   }
  } ?: defaultUrl 
 }

}


The line with the authMapping variable assignment is doing grailsApplication.config. authenticationurl.mappings underneath. The value is itself a map of maps.

The method determineTargetUrl loops through the map looking for the first result matching the user's role. If there's an entry the user will be redirected to the configured URL otherwise the default URL will be used (normally it is the same URL where the user was when he tried to authenticate himself).

Notice that I'm using the service grailsLinkGenerator to generate the proper link passing the controller and action arguments to it. This works the same as if we were using the tag in any gsp. This service is available by default in Grails.

Ah of course don't forget to register your authentication handler in the resources.groovy file

authenticationSuccessHandler(AuthenticationHandler) {
        /* Reusing the security configuration */
        def conf = SpringSecurityUtils.securityConfig
        /* Configuring the bean */
        requestCache = ref('requestCache')
        redirectStrategy = ref('redirectStrategy')
        springSecurityService = ref('springSecurityService')
  grailsLinkGenerator = ref('grailsLinkGenerator')
  configurationService = ref('configurationService')
        defaultTargetUrl = conf.successHandler.defaultTargetUrl
        alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault
        targetUrlParameter = conf.successHandler.targetUrlParameter
        ajaxSuccessUrl = conf.successHandler.ajaxSuccessUrl
        useReferer = conf.successHandler.useReferer
    }

Monday, 19 November 2012

Groovy + Javascript == Grooscript 0.1

Last weekend Grooscript 0.1 was released. Grooscript is a library that compiles Groovy to Javascript using the AST tree as the source for the conversion.

There's been a while since I was waiting something like this landing in the Groovy scene. Why couldn't we  have a Javascript "compiler" to use it in the views as well?

Although Grooscript still needs time to be mature it's really promising. I have played with it a little bit and it's really funny the things  you can do in Groovy. The most important feature in version 0.1 is that you can call native javascript inside your methods. The syntax to do it is the following:

      @org.grooscript.GsNative def myMethod(parameter){/*
         //Javascript Code Here
      */}

This syntax has been chosen among others mainly because the lack of native method support in Groovy. We couldn't have used the word 'native' as GWT does when invoking javascript native methods.

By the time I'm writing this entry I have found one issue in the native support in Grooscript, and it seems that the workaround is pretty easy, you only need to add a dummy method at the end of your script to make the native support works.
      
      @org.grooscript.GsNative def myMethod(parameter){/*
         alert(parameter);
      */}

      @org.grooscript.GsNative def dummy(){/**/}


Because I really liked the project I started creating a Grails plugin to be able to use it any Grails project. It is not available yet in the Grails repository, but I guess it will be eventually. You can clone it, package it and install it in your Grails application, the code is at github.

The plugin enables you to declare Groovy scripts as static resources and compile those scripts to Javascript code.

Groovy files must have the suffix '.gs'. I still don´t know why files with '.groovy' suffix can´t be 'watched' (Grails doesn´t see any changes made to that files). In the meanwhile I opened an issue at JIRA (The more votes the faster it could be resolved :-) )

You must declare the dependency of the 'grooscript' module in those modules you're declaring any groovy scripts (I also have added here the jquery dependecy because I use it in the example).


modules = {
    myGroovyFiles{
      dependsOn 'jquery'
      dependsOn 'grooscript'

      resource url:'js/gs/GrooscriptNative.gs'
    }
}


In order to proof the native support of Grooscript I did a really simple example. I made a script that changes the Grails logo in your Grails application for the Grooscript logo. Here's the code of the GrooscriptNative.groovy


import org.grooscript.asts.*

class GrooscriptNative{ 
 
 @GsNative def changeImage(selector,image){/*
       $(selector).attr("src",image.url);
 */}   
 
     /* Workaround for an issue */
 @GsNative def dummy(){/* */}
}

class ImageHolder{
    String url
}

def selector = "#grailsLogo a img"
def image = new ImageHolder(url:"http://grooscript.org/img/logo.png")
 
new GrooscriptNative().changeImage(selector,image)

If you've installed the plugin properly, declared the ".gs" file in the resources file and on running the application you opened the browser you should see the following:


Cool!! isn't it?

You can get Grooscript from its site or getting the jar adding the public sonatype repository as an extra maven repository to your project.

Saturday, 22 September 2012

Excluding classes in the CodeNarc Grails plugin

Sometimes you don't want CodeNarc to inspect certain classes, for example, the domain classes the Spring Security Core Plugin creates.

There is a property called doNotApplyToClassNames that you can use to omit those classes you don't want to be inspected for a given CodeNarc rule.

If you want to use it you will only have to put the name of the rule followed by the doNotApplyToClassNames literal and the specify the names of the classes you don´t want to be inspected for that particular rule.

NameOfTheRule.doNotApplyToClassNames="ClassOne, ClassTwo"

In this particular situation I didn't want CodeNarc to bother me about the lack of equals and hashcode methods in those domain classes so I wrote the following lines in my CodeNarc configuration (inside BuildConfig.groovy)

GrailsDomainHasEquals.doNotApplyToClassNames="Role, User, UserRole"
GrailsDomainHasToString.doNotApplyToClassNames="Role, User, UserRole"


Here's the codenarc closure configuration:

codenarc.properties = {
          GrailsPublicControllerMethod.enabled = false

          GrailsDomainHasEquals.doNotApplyToClassNames="Role, User, UserRole"
          GrailsDomainHasToString.doNotApplyToClassNames="Role, User, UserRole"
}