Imran Mir « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:

Imran

http://www.IntelliGrape.com

Posts by Imran:

  • Initializations in Grails Unit Test Cases

    14 Jun 2011 in Grails& Groovy& Test& Unit Test

    Most of us have experienced how important the Unit test cases are for our code base. I feel the other thing that is equally important, is the speed at which we can write the unit test cases. In Unit Testing, initializing different objects in setup of the test case (e.g., while testing a method which queries the database) can become a pain, especially when the objects to be initialized have many attributes and relationships. Grails/Spock have simplified initialization process for us. All we need to is to initialize just the required attributes of the objects, along with the id field,e.g., while testing a method of a class Student :

    class Student {
      String name
      String fathersName
      String address
      static belongsTo = [school: School]
    
     static constraints = {
        name(nullable: false)
        fathersName(nullable: false)
        address(nullable: false)
      }
    
      // METHOD TO BE TESTED
      List<Student> findMySchoolsStudentsWithNamesLike(String nameLike) {
        List<Student> students = Student.findAllBySchoolAndNameLike(this.school, '%' + nameLike + '%')
        return students
      }
    
    }
    

    To test the method, a Spock test case with the simplified initializations will be like:

     def "My School students are retrieved correctly"() {
        setup:
        School school = new School(id: 1)
        List<Student> students = (1..10).collect {new Student(id: it, name: "name${it}", school: school)}
        mockDomain(Student, students)
    
        expect:
        students[0].findMySchoolsStudentsWithNamesLike('1').size() == 2
      }
    

    Similar setup can work in Grail Unit test case.
    Simplification of the initialization process has made Unit testing simpler and faster, thus allowing us to write more Unit test cases.

    Cheers,
    Imran Mir
    imran@intelligrape.com

    • Share/Bookmark
  • Handling Instance Based Security

    In my current project, we were required to implement Instance Based Security. The idea was to find a clean solution separate from the main business logic of the application. We took a clue from the Spring Security Plugin to use the Annotations to do our job. All we wanted to do was to develop annotations for actions, which could help to decide what type of access verification needs to be done on a particular request, inside some Filter. So we proceeded like this :

    We created an Abstract Class from which our User domain Class extended. All our Access Verifying functions would remain in this class. The class provides a single entry function (by the name evaluateExpression) to all other Access Verifying functions. This helped us to keep the Filter class clean. The Class looks like :

    abstract class MyAppSecure {
    
      public Boolean evaluateExpression(String methodName, Map params = [:]) {
        this."$methodName"(params.id?.toLong())
      }
    
      // One of the many functions to be used to verify valid access
      public Boolean hasUserAccessById(Long id) {
        return id ? (this.id == id.toLong()) : true
      }
    
    }
    

    So our User domain class looks like:

    class User extends MyAppSecure {
    
    }
    

    Now, the idea is to:

    1. Intercept a request in the filter.
    2. Get the annotation expression placed on top of the respective Controller Action. (The expression(s) would be name of the MyAppSecure method(s) used to verify the access)
    3. Call a corresponding method in MyAppSecure to verify access
    4. Take appropriate action corresponding to a result

    So let us delve into the implementation:

    First step would be to enable the annotations. To do this create an interface in src/java (or you can do it in src/groovy as well):

    @Documented
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MySecured {
        String[] expressions();
    }
    

    Now we are good to go for using annotations. Let us assume an action edit inside AccountController:

    class AccountController{
    
    @MySecured(expressions = ["hasUserAccessToAccount"])
     def edit = {
        User user = params.id ? User.get(params.id) : user
        render(view: "edit", model: [user: user])
      }
    }
    

    Note: We can also give multiple expressions (to evaluate multiple access rules), seperated by a commas inside the list.

    Now we need to implement a method by the name hasUserAccessToAccount in MyAppSecure:

    abstract class MyAppSecure {
    
    public Boolean evaluateExpression(String methodName, Map params = [:]) {
        this."$methodName"(params)
    }
    
    public Boolean hasUserAccessToAccount(Map params) {
    // SAMPLE LOGIC.
        Integer count = Account.createCriteria().get {
          projections {
            count("id")
          }
          eq('id', params.id.toLong())
          eq('user', this)
        }
        return (count > 0)
      }
     }
    }
    

    We would also need some logic to get and parse annotations in MyAppSecure. We wrote something like this :

    public Boolean hasAccess(Class controllerClazz, String actionName,  Map params) { def field = controllerClazz.declaredFields.find {it.toString().indexOf(controllerClazz.name + '.' + actionName) != -1}
     // get the annotation on a Controller action (account/edit in our case)
        def securedAnnotation = field.getAnnotation(AdlSecured)
        return (securedAnnotation ? this.evaluateEveryExpression (params, securedAnnotation)
      }
    
     // Evaluate every expression and combine the result using AND (or we can use OR as well)
      private Boolean evaluateEveryExpression(Map params, def securedAnnotation) {
        Boolean hasAccess = securedAnnotation.expressions().every {String securedExpression ->
          this.hasAccessForExpression(securedExpression, params)
        }
        return hasAccess
      }
    
      //Evaluate expression
      private Boolean hasAccessForExpression(String expressionToBeEvaluated, Map params) {
        return this.evaluateExpression(expressionToBeEvaluated, params)
      }
    

    Now in you Filter you can write something like this:

    mySecureFilter(controller: "*", action: "*") {
          before = {
              User user = someSecurityService.currentUser
              if (user) {
              // gets the controller class for a controllerName
                Class controllerClazz = getControllerClass(controllerName)
    
                if (!user.hasAccess(controllerClazz, actionName, params)) {
                    redirect(controller: 'accessController', action: 'unauthorized')
                    }
                  }
                  return false
                }
              }
    

    That is all that we need to do. I hope you would find this useful. Any suggestions will be welcomed.

    • Share/Bookmark
  • Rich Domain Model in Grails

    14 Oct 2010 in Design Pattern& Grails

    I have been working on grails for quite some time now. As a beginner, I had doubts about where to place the business logic in grails. Seeing the CRUD, one can easily be misled into putting most of the code in the actions, but as the code base goes bigger, it becomes difficult to manage those actions. Coming from the java background, with the previous experience of putting just the getters and setters in the domain classes, it seemed hard for me to visualize business logic in the domain, so I started putting the business logic in the services. It is just natural to use actions as request welcoming and forwarding code blocks. As a result, the actions looked cleaner and easier to follow. The ability of the services to be transactional also simplified the saving of the objects.


    But, again as the code base grew, this type of approach also seemed to be unnatural. This approach surely has a tinge of procedural design in it. Devoiding domain objects of the behavior seems to be against the basic idea of object-oriented design. Martin Fowler has rightly called it as ‘Anemic Domain Model‘, depleting the domain classes of their behavior. To give you an example, for searching all the students of a teacher,

    teacher.getAllStudents()

    seems more natural than

    teacherService.getAllStudents(teacher)


    The former is more Object Oriented than the latter. Adding the behavior to the domain classes makes them rich, that is why it is called Rich Domain Model. Presence of grails dynamic finders in the domain classes seems to corroborate the model. Not only does the code become easier to understand but also becomes easier for some other developer to locate. Putting the business logic in the domain, only is the natural way of Object Oriented Approach.


    But now the question comes what are services for in grails context ? In my point of view, Services can be used on top of the business logic in domain. So, they can encapsulate the different tasks in the application. The ability of Services to be transactional also make this approach natural.


    Hope this helps.

    Imran Mir
    [imran@intelligrape.com]

    • Share/Bookmark
  • First experience with Google App Engine

    14 Sep 2010 in Grails

    A few days back I had chance to work on a googleApp using GORM-JPA plugin,version (0.7.1). I came across a few problems which are as given below.
    Consider the domain : Country -> has many States.

  • At first it appeared that the one to many relationships are to be managed using annotations like :
  • Country {
      @OneToMany(mappedBy = "state")
      List<State> states
    }
     
    State state {
      @ManyToOne
      State state
    }
  • The Country.get() worked fine but State.get() did not work. I think it is due to the fact that Big Table stores states as multivalued attributes of the Country. So to make it work I myself added a field (countryId) to State domain, storing the Id of the Country it belongs to as foreign key. So everytime I needed to find the State from its Id attribute, I first used to search all the States belonging to a Country, and then from these states search for a state with a particular id.
  •  List states = State.findAll("SELECT s FROM State s WHERE s.countryId='${params.countryId}'")
     def pollOptionInstance = pollOptions.find {it.id == params.id.toLong()}
  • Domain.findAllBy() and Domain.findBy() do not seem to work. I used Domain.findAll{query} most of the time to query a domain.
  • Each save() operation needs to be contained in a transaction
  • Only one object can be saved in one transaction
  • I couldn’t save State object with the reference of the Country object in it. It did not allow me, so I stored the countryId instead of the whole object (which exactly is what gorm does for you). So this meant I had to manage hasMany relationships on my own, by storing the refenceIds instead of the objects itself (so annotations were of no use).
  • Hope this helps. You are welcome to share your thoughts on it.

    Imran Mir
    imran@intelligrap.com

    • Share/Bookmark
  • Grails unit testing for beginners

    14 Jul 2010 in Grails& Groovy& Test& Unit Test

    Ques: How is unit testing different from integration testing ?

    Ans: Integration tests need to bring up the whole grails environment.They talk to the database. All the dynamic GORM methods and properties are available here. Unit testing are small focused, fast loading tests that do not load supporting components.

    Ques: How can I unit test a method in a service ?

    Ans: You would need to follow these simple steps:

    Suppose you want to write a unit test case for a someFunction() in MyService:

    class MyService {
        public String myFunction() {
          return "testString"
        }
      }

    -> Create Unit Test File : grails create-unit-test com.intelligrape.xxx.MyService. It will create the test file in the folder /test/unit
    -> Write a testcase function
    -> Create an object of MyService
    -> Call the function and make assertions

    public void testMyFunction() {
        def myService = new MyService()
        String string = myService.myFunction()
        assertEquals "testString", string
      }

    Ques: I am saving an object from this function. How can I test that ?

     public void myFunction(int number, String name) {
        MyDomainClass object = new MyDomainClass(age: number, name: name)
        object.save()
      }

    Ans: Its pretty simple. You would first need to mock the domain class whose object is being saved.

       def instances = []
       def myTestDomain = mockDomain('MyDomainClass',instances)

    instances will serve as a cache of objects. Right now it contains no object. But when you call the save method from the function to be tested, it will automatically put that object in this cache. So, we can make assertions against this cache. Just to remind you, no database communication occurs during the unit testing.

     public void testMyFunction() {
        def instances = []
        def myTestDomain = mockDomain('MyDomainClass', instances)
        def myService = new MyService()
        String string = myService.myFunction(30, 'myName')
        assertEquals 1, instances.size()
      }

    Ques: What does this mockDomain do ?

    Ans: mockDomain is a method of GrailsUnitTestCase, that helps to mock a domain class. mockDomain also mocks most of the injected methods of the domain class like, save(), validate(),delete(),get() and many others. But there are many methods it does not mock,e.g., createCriteria,find,findAll,withTransaction and many others.

    Ques: That was great. But now my function uses some other service to do some job. How can I test that ?

      public void myFunction(String empId) {
        String name = otherService.someOtherFunction(empId)
        MyDomainClass object = new MyDomainClass(name: name)
        object.save()
      }

    Ans: In this case you would need to mock both, other service as well as the method which is called.

    void testMyFunction() {
        def otherService = mockFor(OtherService)
        otherService.demand.someOtherFunction() {empId-&gt; return "testName"}
        def myService = new MyService()
        myService.otherService = otherService.createMock()
        String string = myService.myFunction(30, 'myName')
        assertEquals 1, instances.size()
    }

    Ques: What does this mockFor method do ?

    Ans: It is a method that is used to mock a dependency. We can mock services and its methods with the help of this. The demand method of the object returned by the method can be used to mock different methods of the mockedInstance. We can also specify the number of times the function is actually called in the function.

     otherService.demand.someOtherFunction(1..2) {empId; return "testName"}

    Here, it means someOtherFunction() will be called not more than 2 times in the function.

    Hope this helps.
    Imran Mir
    imran@intelligrape.com

    • Share/Bookmark
  • Unit-Tests : Getting started with Service Unit Test

    14 Jun 2010 in Grails& Groovy

    Hi all,

    Here I am giving a brief introduction about unit testing of services in grails. I will explain it with the help of a simple example.

    We have a domain class named: Item
    Two services : UtilService and ItemService

    Code of UtilService.groovy

    // class UtilService code
     
    class UtilService {
        boolean transactional = true
        Integer calculatePrice(Item item, Integer vat, Integer profit) {
            return item.price * vat * profit
        }
    }

    Code of ItemService.groovy

    // ItemService class code
     
    class ItemService {
        boolean transactional = true
        def utilService
        Integer calculateCost(Item item,Integer quantity) {
            Integer price = utilService.calculatePrice(item,5,8)
            Integer totalCost = price * quantity
            return totalCost
        }
    }

    Our test case:-

      void test_calculateCost() {
     // Step-1: Mocking the domain class
            def instance = [new Item()]
            mockDomain(Item, instance)
     
    //Step-2: Mocking the service and its method used in the function that has to be tested
            def otherService = mockFor(UtilService)
            otherService.demand.calculatePrice(1) {l,m, n -&gt; return 150}
     
    // Step-3: creating the instance of our service
            def itemService = new ItemService()
            itemService.utilService = otherService.createMock()
     
    // Step-4: Calling the method to be tested
            def amount = itemService.calculateCost(instance[0],10)
     
            assertEquals 1500, amount
        }

    Hope it helps.
    For more…. wait for the next blog on unit testing

    Regards
    Imran
    imran@intelligrape.com

    • Share/Bookmark
  • Ordering using Grails CreateCriteria

    14 May 2010 in Grails& Groovy

    Recently, in my project I had to implement search functionality. I used grails createCriteria to implement it.Now I needed to apply the sorting on the result returned. My domain was something like this :

    class MyEntity {
     
        OrganizationName orgName
        PersonName personName
     
        static constraints = {
          orgName('nullable', true)
          personName('nullable', true)
        }
      }
     
      class OrganizationName {
     
        String organizationName
     
      }
     
      class PersonName {
     
        String familyname
        String firstName
     
      }

    The “MyEntity” could either be a person or an organization. In the view, we show just the name, and that could be either the organization-name or person-name. The list needed to be sorted by the name,irrespective of the fact, whether it is a name of a person or an organization. Grails “createCriteria” did the magic for me. I wrote something like this :

      MyEntity.createCriteria ().list {
     
        orgName {
          order('name')
        }
        personName {
          order('familyName')
        }
      }

    The ordering seems to ignore nulls. It sorts the MyEntity objects with orgName, groups them togethor and then sorts the MyEntity objects with personName and makes another group for them and then returns a combined, grouped sorted list of both. Hats off to grails.

    Imran Mir
    imran@intelligrape.com

    • Share/Bookmark
  • Tracking Errors/Exceptions during ajax calls in a view

    If you want to keep track of the errors and exceptions on the view, after making an ajax call, then this might be something of your interest :

    jQuery().ready(function() {
      jQuery.ajaxSetup({
        error: function(x, e) {
          if (x.status == 0) {
            alert('You are offline!!\n Please Check Your Network.');
          } else if (x.status == 404) {
            alert('Requested URL not found.');
          } else if (x.status == 500) {
            alert('Internel Server Error.');
          } else if (e == 'parsererror') {
            alert('Error.\nParsing JSON Request failed.');
          } else if (e == 'timeout') {
            alert('Request Time out.');
          }
          else if (x.status == '401') {
              alert('My Own Exception');
            }   
        }
      });
    });

    And in your action, you can use the following code to send a custom exception code along with a custome message:

    response.sendError(440,"custom message")

    In my project I need the errors and exceptions to be shown on a page which is different from the one from which the ajax request originated. So I added the following statement in the else part :

    else {
             window.location = "${createLink(controller: 'apgException', action: 'somethingWrong')}" + "? status=" + x.status +"&message=" + x.statusText
      }

    Hope you find it useful.
    Imran Mir
    imran@intelligrape.com

    • Share/Bookmark
  • Implementing Delay Between Ajax Calls

    25 Feb 2010 in Javascript/Ajax/JQuery

    Implementing search functionality on the keyup event using ajax has one pitfall. It can bombard our server with unnecessary ajax calls. So it becomes imperative for us to introduce some delay between the ajax calls. One way to implement it will be to make an ajax call after some delay(say 500 ms) after the first character has been typed in the text box. But,a better solution will be to make the ajax call after 500ms, after the last character has been typed. The idea is to clear the timer on each key-up event till the user types in the last charecter.
    This solution can be implemented as given below:

    <input type="text" onkeyup="activateTimer(this.id)" id="firstName"/>
     var alertTimerId = 0;
    function activateTimer(objId) {
        clearTimeout(alertTimerId);
        alertTimerId = setTimeout('sendData("' + objId + '")', 500);
      }
      function sendData(objId) {
        ajax call 
      }

    Here, the instance or identifier of the time out call is captured in a variable and then this identifier is passed to clearTimeout function to clear the timer.
    Another problem associated with ajax search on keyup event is that if we are using tab button to navigate between different search fields, unnecessary ajax calls are shooted. To prevent this we can modify our activateTimer function like this :

    function activateTimer(objId, event) {
        if (event.which == 9) {
        }
        else {
          clearTimeout(alertTimerId);
          alertTimerId = setTimeout('sendData("' + objId + '")', 500);
        }
      }

    Event argument can be passed as parameter like this :

      <input type="text" onkeyup="activateTimer(this.id,event)" id="firstName"/>

    Hope you find this useful.
    Imran Mir
    imran@intelligrape.com

    • Share/Bookmark
  • Batch Processing In Grails

    09 Sep 2009 in Grails

    In one of my project assignments I needed to insert large number of records into the database. I had to read the objects from an external source. Once I read all of the objects into a List, I iterated the list to save each one of them individually. In the beginning the process carried on fine but as the time passed the execution slowed down considerably. It almost took one second to insert one object into the database. Imagine the time it would have taken to insert 50000 records with this pace. Besides, many times it threw OutOfMemoryException. The code I had written did something like this :

     (0..60000).each{
               Person person = new Person(.....)
               person.save()
           }

    One of the solutions that I found was to use transactions and save the objects in batches, each transaction saving a batch of objects. It worked well and reduced the execution time considerably. What I did was like this :

       def startTime = System.nanoTime()
            List <Person> batch =[]
            (0..50000).each{
               Person person= new Person(....)
                batch.add(person)
                println "Created:::::"+it
                if(batch.size()>1000){
                    Person.withTransaction{
                        for(Person p in batch){
                            p.save()
                        }
                    }
                }
              batch.clear()
              session = sessionFactory.getCurrentSession()
              session.clear()
            }
            def endTime =  System.nanoTime()
            def diff = (startTime-endTime)/1000000000
            println "TIME TAKEN IS :::"+diff

    In the previous case the time take to save 50,000 records was around 500 seconds. But, here time taken to save the same number of records came out to be just 80 seconds.

    But there is one flaw in the method. If the objects are bulky, even this method would not work. Each action in a Grails Controller is executed within a Hibernate Session. The session is started right before the action starts and is closed once it returns. Thus Hibernate caches all the newly inserted Person instances in the session-level cache. As the number of objects grows, the session becomes bulkier, which slows down whole process .That also explains the reason for the memory issue, OutOfMemoryException, because all the objects are being cached to the Hibernate session.The solution to this problem is to clear the session regularly so as to keep it light throughout the process. All that needs to be done is to get hold of the current session and clear it after each batch has been written to the database. To do this just inject SessionFactory object into your controller, get the current session object and then clear this current session.

            def startTime = System.nanoTime()
            List <Person> batch =[]
            (0..50000).each{
               Person person= new Person(....)
                batch.add(person)
                println "Created:::::"+it
                if(batch.size()>1000){
                    Person.withTransaction{
                        for(Person p in batch){
                            p.save()
                        }
                    }
                    batch.clear()
                }
              session = sessionFactory.getCurrentSession()
              session.clear()             
            }
            def endTime =  System.nanoTime() 
            def diff = (startTime-endTime)/1000000000
            println "TIME TAKEN IS :::"+diff

    Thank you,
    Imran Mir,
    imran@intelligrape.com

    • Share/Bookmark