Uday Pratap Singh « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:
spacer

Uday Pratap Singh

www.IntelliGrape.com

Groovy Follower, Grails Learner, GORM Lover and Spock Jedi . LinkedIn: in.linkedin.com/in/meudaypratap

Posts by Uday Pratap Singh:

  • Groovy annotations for ToString and EqualsAndHashCode

    29 Jan 2012 in Design Pattern& Grails& Groovy

    As I am a lazy programmer most of the time I dont implement toString and equals methods on my grails domain classes. I would like to say thanks to Groovy for helping me out and giving me a ready made recipe for this. Now I just need to annotate my class with ToString and EqualAndHashCode annotation it adds appropriate implementation of these methods for me. Now My domain class looks something like this.

    @ToString(includeNames = true, includeFields = true, excludes = 'dateCreated,lastUpdated,metaClass')
    @EqualsAndHashCode
    class Item {
        String name
        Float price
        boolean active = true
        Date dateCreated
        Date lastUpdated
    }
    

    Before adding this annotation my domain class toString looks like this

    Item item = new Item(name: "Chips", active: false, price: 15)
    println "To String output -: " + item //To String output -: com.intelligrape.myapp.Item : null
    

    Now I get the following output for Item object toString

    Item item = new Item(name: "Chips", active: false, price: 15)
    println "To String output -: " + item //To String output -: com.intelligrape.myapp.Item(name:Chips, price:15.0, active:false)
    

    To get this annotation on all my domain classed I updated the template of grails domain classes so that whenever I do create-domain-class it give me the annotated domain classes

    @artifact.package@
    import groovy.transform.EqualsAndHashCode
    import groovy.transform.ToString
    
    @ToString(includeNames = true, includeFields = true, excludes = 'dateCreated,lastUpdated,metaClass')
    @EqualsAndHashCode
    class @artifact.name@ {
    
        Date dateCreated
        Date lastUpdated
    }
    

    Hope it helps



    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Log Sql in grails for a piece of code

    21 Oct 2011 in Design Pattern& Grails& Groovy& logging

    There are time when we need to see the sql logging statement just for a method of for a particular code. Although we already have logSql property in DataSource to do it for us but it sometimes makes difficult if we need to see the log for a small piece of code rather than for whole project.
    So I need something that will execute my code withing a block which automatically starts sql logging and switch it off when code is finished. Groovy closures are the solution for this problem. For doing it I created a class LogSql which have a static execute method that takes the closure as parameter.

    import org.apache.log4j.Level
    import org.apache.log4j.Logger
    
    public static def execute(Closure closure) {
            Logger sqlLogger = Logger.getLogger("org.hibernate.SQL");
            Level currentLevel = sqlLogger.level
            sqlLogger.setLevel(Level.TRACE)
            def result = closure.call()
            sqlLogger.setLevel(currentLevel)
            result
    }
    

    Now when I want to see the logs I do something like following.

    String name = "Uday"
    Person person
    LogSql.execute {
           person = Person.findByName(name)
    }
    

    This prints the sql statement for all the sql fired in the given piece of code block.

    Hope it helps



    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Annotation for checking required session fields

    21 Sep 2011 in Design Pattern& Grails& Groovy& Java tools

    Recently I worked on a project where I used spring security plugin. Its a very wonderful plugin for making your application secured from unauthorized users. It gives you a simple annotation @Secured to add security to your action and controller. Thats the first time I got to know the real use case of annotation. So I started reading about annotation and few days later I found the use case to implement my own annotation.

    All the projects I have worked on had login functionality where we put the userId and projectId into the session. Then in my code I use to get the user from session.userId. Something like

    def books = {
       User user = User.get(session.userId)
       Project project = Project.get(session.projectId)
       ......
       .....
    }
    

    The above code fails when user directly hits this action because there is no check to verify the user is not null. The simple answer for this problem is either use beforeInterceptor or filters. So we started checking the session.userId in filters. But again there are cases where you dont want to check this session value or you can say there are public urls as well. Now we have to put few if else statements in filter.

    Here I got my use case to implement an annotation for controllers and actions which checks for the required fields in the session before getting into the action. So I created an annotation in src/groovy folder

    import java.lang.annotation.ElementType
    import java.lang.annotation.Retention
    import java.lang.annotation.RetentionPolicy
    import java.lang.annotation.Target
    
    @Target([ElementType.FIELD, ElementType.TYPE]) // Annotation is for actions as well as controller so target is field and for class
    @Retention(RetentionPolicy.RUNTIME) // We need it at run time to identify the annotated controller and action
    @interface RequiredSession {
        String[] exclude() default [] // To exclude some of the actions of controller
    
        String[] fields() default ["userId","projectId"] // The default value is set to userId and projectId that can be overridden while using the   annotation on controller or action.
    
        String onFailController() default "home" // Default controller when the field not in session is set to index page
    
        String onFailAction() default "index" // Default action when the field not in session is set to index page
    }
    

    Now I created a ApplicationFilters and before redirected the request to any action I check for the condition of session fields if the requested action or controller is annotated. The code in the filter is something like

    class ApplicationFilters {
        def filters = {
            validateSession(controller: '*', action: '*') {
                before = {
                    if (controllerName) {
    
    //Get the instance of controller class from string value i.e; controllerName
                        def controllerClass = grailsApplication.controllerClasses.find {it.logicalPropertyName == controllerName}
    
    //Read the RequiredSession annotation from controller class
                        def annotation = controllerClass.clazz.getAnnotation(RequiredSession)
    
    //Get the current action from actionName otherwise read default action of controller
                        String currentAction = actionName ?: controllerClass.defaultActionName
    
    //Look for the annotation on action if controller is not annotated or the action name is excluded
                        if (!annotation || currentAction in annotation.exclude()) {
    
    //Get the action field from string value i.e; currentAction
                            def action = applicationContext.getBean(controllerClass.fullName).class.declaredFields.find { field -> field.name == currentAction }
    //If action is found get the annotation else set it to null
                            annotation = action ? action.getAnnotation(RequiredSession) : null
                        }
    
    //Check for the field in session whether the are null or not if any of the field is null loginFailed is true
                        boolean loginFailed = annotation ? (annotation.fields().any {session[it] == null}) : false
    
                        if (loginFailed) {
    
    // If login is failed user redirected to on fail action and controller
                            redirect(action: annotation.onFailAction() , controller: annotation.onFailController())
                            return false;
                        }
                    }
                }
    
            }
        }
    }
    


    And its all done. Now we just annotate our controller and actions accordingly.

    @RequiredSession(exclude = ["registration", "joinProject"])
    class UserController {
          def edit ={}
          def update = {}
          def list ={}
          def save ={}
    
          def registration ={}
          def joinProject = {}
    }
    

    In above example registration and joinProject action will bypass the session fields check.

    @RequiredSession
    class ItemController {
            def index={}
            def buy ={}
            def save ={}
    }
    

    All the action of above examples can be accessed only when user is logged in.

    class HomeController {
          def index ={}
          def aboutUs={}
          @RequiredSession
          def dashboard = {}
    }
    

    Actions other than dashboard are public actions which can be accessed without login.

    class UserController {
      @RequiredSession(fields = ["loggedInUserId"])
       def updatePassword = {
    
       }
    }
    

    For updating password user dont need to have some project into session so we specified the fields to be checked in session.

    Hope it helps



    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Grails console plugin gotcha

    28 Aug 2011 in Grails& Plugin

    Grails console plugin is one of those which I always add to my projects. It really gives you a very handy way of debugging things and also run some quick fixes.

    Whenever you hit the console action you always gets a predefined message on it about the available variables, which is really good when you are a new user but in most of the cases you need to import few statements and you always need to write them before executing any command.

    So in my recent project I looked at the plugin code and I found a nice way to change the default statements.

    I added the following line in my project application filter.

    consoleImports(controller: 'console', action: '*') {
         before = {
                 String importStatements = """import com.intelligrape.package1.*
                 import com.intelligrape.package2.*
                 import com.intelligrape.package3.*
                 import com.intelligrape.package4.* """
    
                 session['_grails_console_last_code_'] = session['_grails_console_last_code_'] ?:importStatements
          }
    }
    



    It could be a small but great enhancement in the console plugin to just update it to provide the starting code as a configuration option

    Hope it helps


    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Inject custom validation errors in object

    18 Aug 2011 in Design Pattern& GORM& Grails& Java tools

    Reading the grails docs is like my habit, they always enhances your learning. Today I was going through the grails docs again and I found a very good way of showing some custom error messages. As I saw it I found the use case in one of my project that could be refactored by this approach

    There are use cases where we need to show some errors which are beyond your domain / command object constraints validators for these cases you can inject your custom error messages to the object take an example of updating the password. Any of the field is not domain related so we have to create a command object like

    class UpdatePasswordCO {
    
        String password
        String newPassword
        String confirmNewPassword
    
        static constraints = {
            password(nullable: false, blank: false)
            newPassword(nullable: false, blank: false)
            confirmNewPassword(nullable: false, blank: false, validator: {val,   obj ->
                if (obj.newPassword != val) {
                    "confirmPassword.mismatch.newPassword"
                }
            })
        }
    }
    

    Now you have to check whether the logged in user entered the correct password or not. So rather than putting the message in flash scope you can directly put this error to the command object it self

    def updatePassword = {UpdatePasswordCO updatePasswordCO ->
            if (updatePasswordCO.validate()) {
                if (User.loggedInUser.validatePassword(updatePasswordCO.password)) {
                    flash.message = "Password updated successfully"
                } else {
                    updatePasswordCO.errors.rejectValue("password", "password.mismatch.current.password")
                }
            }
            if (updatePasswordCO.hasErrors()) {
                render(view: 'profile', model: [updatePasswordCO: updatePasswordCO])
            } else {
                redirect(action: 'profile')
            }
    }
    

    So in above approach you have injected a new error on password field with a code. By doing this your hasErrors tag on gsp page will show your custom error as well. For more details you can refer Spring



    Hope it helps


    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Groovy Category Annotation

    31 Jul 2011 in Groovy

    Annotations really provides a whole new view of programming things. Groovy also provides some of its own annotations one of them is Category. Lets take an example of using it. We create a IntegerUtil class and annotate it with Category.

    @Category(Integer)
    class IntegerUtil {
        List<Integer> multiples(Integer upto) {
            (1..upto).collect {this * it}
        }
    }
    

    Now the above code made your class any other groovy category class for example Time Category. Now you can use these methods as follows -:

    List<Integer> multiples
    use(IntegerUtil) {
        multiples = 2.multiples(10)
    }
    println multiples  // Output -: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
    

    It really helps when you want some more helper methods on already existing classes.


    Hope it helps


    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Grails Data Binding & criteria reuse

    01 Jul 2011 in Design Pattern& GORM& Grails& Groovy

    Data Binding in grails is something that I love alot. In most of the cases we look at the Binding with respect to some domain class but binding can be one of the best candidate for searching and filtration.
    In my recent project we had a domain Class Article and the user could filter articles on different criteria. The page looks something like following

    spacer

    We had 3-4 such pages but with some extra states (Enum property) of article. So for doing this we created two CO classes, one for basic search properties like max, offset, order and sort and other for article related fields. So the CO goes like following

    class SearchCO {
      Integer max = 10
      Integer offset = 0
      String sort = "id"
      String order = "asc"
    
      def searchCriteria = {
        order(sort, order)
      }
    }
    
    class ArticleSearchCO extends SearchCO {
      List<ArticleType> types  // This is Enum
      List<Long> styleIds
      List<Long> categoryIds
      String topic
      def searchCriteria = {
         and {
          if (topic) {
            ilike("topic", "%${topic}%")
          }
    
          if (categoryIds) {
            subCategory {
                  inList("id", categoryIds)
              }
          }
    
          if (styleIds) {
            writingStyle {
                 inList("id", styleIds)
             }
          }
    
          if (types) {
                inList("type", types)
            }
        }
        super.searchCriteria
      }
    }
    

    In our controller side we got the fully populated object that can be used for searching the different articles based on searching. So our controller side code was something like

    def findWork = {ArticleSearchCO co ->
        List<Article> articles = authorService.findWork(co)
        render(template:"articles",model:[articles:articles,totalCount:articles.totalCount])
    }
    
    def currentWork = {ArticleSearchCO co ->
        List<Article> articles = authorService.currentWork(co)
        render(template:"articles",model:[articles:articles,totalCount:articles.totalCount])
    }
    

    As I already have the searching closures in my CO so the code in my service was something like

    public List<Article> findWork(ArticleSearchCO co) {
        def articleCriteria = Article.createCriteria()
        Closure searchCriteria = co.searchCriteria
        searchCriteria.delegate = articleCriteria
        List<Article> articles = articleCriteria.list([max: co.max, offset: co.offset]) {
          eq("status", ArticleStatus.Unassigned)
          searchCriteria()
        }
        return articles
      }
    

    In the same way for currentWork method I just changed the status i.e; ArticleStatus.InProgress. Thats how I handled the searching, filtering, pagination which was all Ajax. I tried to make my code as DRY as possible . There are still few things that I dont like about it one is so many if statements and other is delegating the searching criteria in each method. I think now with the support of namedQuery I can optimize the method.

    Hope it helps

    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • How to apply liquibase change set conditionally

    18 May 2011 in Database& Grails& Plugin

    In our recent grails project, we were about to move to production so we decided to manage the database changes with liquibase. So we generated the changelog from development env by executing the command “grails generate-changelog /home/uday/projects/projectName/grails-app/migrations/changelog.xml” which contained all the table creation changesets. We updated the dbCreate=’none’ in all env. When we ran the application in test env, having the database in create-drop mode, it worked, but in other envs, which had database in “update” mode, it started failing. Now we wanted some hook to execute the creation changeset only if the tables did not exist.
    We just went through the liquibase site and we got the answer to our problem. The solution was in liquibase PRECONDITIONS. We added the preconditions to the changesets to check whether the table existed or not.

    <changeSet author="uday (generated)" id="1305002274717-1">
        <preConditions>
    

    In the above example the changeset will execute only if the precondition passes, if the condition fails you can specify what needs to be done. In our case we mark it as run so that liquibase marks it as being executed. You can do other things on fail event like HALT, CONTINUE, WARN,MARK_RAN.
    The documentation is quite good, you can find the examples of other changesets like constraints and indexes as well.



    Hope it helps


    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Exception Testing using Spock in grails

    04 May 2011 in Grails& Test& Unit Test

    Testing was never so easy and intuitive before the use of Spock. Earlier when I was using grails unit testing, it never attracted me to write more and more test cases but with Spock you always keen to test each and every line of your code, testing the exceptions is one of them.

    You can always test the exceptions in grails unit test as well but with Spock it looks more clean and more readable. For example you have a method which throws exception like

    String getUserType(int age){
        if(age<=0){
            throw new MyException("Invalid age")
        }else if( age>0 && age<50){
            return "Young"
        }else{
            return "Old"
        }
    }
    

    Now we will write the test case of this method for checking whether exception is thrown for invalid inputs or not.

    def "exception should be thrown only for age less than or equal to 0"{
        given:
            String type = getUserType(34)
        expect:
            type == "Young"
            notThrown(MyException)
        when:
            type = getUserType(0)
        then:
            MyException me = thrown()
            me.message == "Invalid age"
    }
    

    This is how we have tested whether exception is thrown for invalid input or not.



    Hope it helps


    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer
  • Interaction based testing using Spock in Grails

    07 Apr 2011 in Grails& Test& Unit Test

    In my recent project we are using spock test cases to test our application and spock really made it easy for us to test those things we were not able to test in Grails Unit Test or testing such things dont look so intuitive in Grails Unit tests . One of the powerful method of spock testing is interaction based testing, which allow us to test whether the call is made to some other method with the defined parameters and it also tests how many calls are made to the other method.

    The email sending perfectly fits into this example. So you have mail sending plugin in your application and one of your method sends mail to the users like following

    class EmailService {
    def asynchronousMailService
    
    public sendMail(String to, String from, String subject, String body) {
        try {
          asynchronousMailService.sendAsynchronousMail {
            to to
            subject subject
            body to
            from from
          }
        }
        catch (Throwable t) {
          log.error("Exception while sending email to user ${to}, Exception is ${t.getStackTrace()}")
        }
      }
    }
    

    and you have a method which calls this method

    class UserService {
    
    def emailService
    
    void sendActivationMail(User user){
        emailService.sendMail(user.email,"admin@admin.com","Your account is activated", "Congratulation now you can login")
    
      }
    
    }
    

    Now when you are testing sendActivationMail method you would like to can verify whether the call is made to emailService or not by using spock interaction based testing. You will write your test case something like

    def "account activation mail sent to user"(){
    setup:
    UserService userService = new UserService()
    
    def emailService = Mock(EmailService)  // As we are not testing email service, we mocked the emailService
    emailService.sendMail(_,_,_,_) >> true  //This will ensure to return true for any argument passed for sendMail method
    userService.emailService = emailService
    
    User user = new User(email : "testUser@gmail")
    
    when:
    userService.sendActivationMail(user)
    
    then:
    1*emailService.sendMail("testUser@gmail","admin@admin.com","Your account is activated", "Congratulation now you can login")
    
    }
    

    The then block ensures that the exactly 1 call is made to sendMail method with exactly the same arguments.
    We can have other use cases for interaction based testing like making calls to external APIs, logging different statements in different conditions.



    Hope it helps


    ## Uday Pratap Singh ##
    uday@intelligrape.com
    www.IntelliGrape.com/
    in.linkedin.com/in/meudaypratap

    • spacer