Vivek Krishna « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:

Vivek Krishna

http://www.IntelliGrape.com

Open Source Enthusiast, Agile Practitioner, Grails Lover, jQuery Worshiper.

Posts by Vivek Krishna:

  • Grails 2.2.0 : Namespacing to resolve between controllers of same name

    24 Sep 2012 in Grails&Plugin

    Grails 2.2.0.RC1 was released last week and a new feature to make an entry into the version of the framework is the support for namespaces for controllers and services so that there is no naming conflicts while adding artefacts of the same name from different plugins or within the application.

    I created a sample app and installed the grails console plugin. This brought a ConsoleController to the application.

    grails install-plugin console
    

    Next, I added a controller with the same name, ConsoleController.groovy in the application.

    grails create-controller console
    

    To resolve the two at a mappings level, we need to add an entry in UrlMappings.groovy so that the two URLs are different.

    //UrlMappings.groovy
    class UrlMappings {
    
            static mappings = {
                    "/gconsole"{ //Resolve gconsole to ConsoleController in the plugin
                            controller = "console"
                            plugin = "console"
                    }
                    "/$controller/$action?/$id?"{
                            constraints {
                                    // apply constraints here
                            }
                    }
    
                    "/"(view:"/index")
                    "500"(view:'/error')
            }
    }
    
    

    Now, if I want to hit the console controller from the application, I can navigate to: http://<app_base_url>/console

    And to navigate to console controller from the plugin, I can navigate to: http://<app_base_url>/gconsole

    To use this in the <g:link> tag, all we need to do is provide an extra attribute plugin and grails will create the URL accordingly.

    This means that we can have choose better namings for our controllers without losing control(pun unintended) over their names.

  • GroovyShell.evaluate() : The magician behind Grails Console

    05 Sep 2012 in Grails&Groovy

    Grails console is one plugin that we install as soon as we create a new application. The power and the purpose of the utility is too good to be missed. On one such occasion, I decided to dig the code in the plugin and discovered the magic trick that executes the string that we type in the web interface.

    Turned out that GroovyShell.evaluate() method is the superstar.

    To validate the same, I put together a class and script which is simply an arithmetic expression evaluator which can take either implicit variables(declared in the code body) or assumed values of variables(sent in bindings to the GroovyShell). While the former is apparent, the latter means that we assume some variables/values to be understood while the script is being executed. We assign those objects to the Shell via groovy.lang.Binding

    * Evaluator Class (The equivalent of ConsoleService)

    
    class ArithmeticEvaluator {
         static def evaluate(String expr, Map bindings){
              new GroovyShell(new Binding(bindings)).evaluate(expr)
         }
    }
    
    

    * Test Script (Equivalent of the Console UI)

    String toBeEvaluated = """
    
        Integer x = 10
        BigDecimal y = 20
        return x*y + (x + y) + z
    """
    println(ArithmeticEvaluator.evaluate(toBeEvaluated, [z:5])) // prints 235
    

    Beautifully demonstrates the power of Groovy!

  • Using Data URLs for embedding images in Flying Saucer generated PDFs

    24 Aug 2012 in Grails&HTML-UI-CSS

    We extensively use Flying Saucer to generate PDFs from GSPs in our grails applications. However, there is always the issue of embedding images from within the application because the URLs are usually relative to the environment and as such, embedding them in PDFs with a URL in the src attribute is cumbersome.

    To get around this, we decided to write our own implementation of the ReplacedElementFactory taking some help from this excellent snippets of code. However, we didn’t find a need to go with our custom implementation of Base64 encoding and as such, we ended up using the sun.misc.BASE64Decoder. The resulting class looked like this :

    
    import com.lowagie.text.BadElementException
    import com.lowagie.text.Image
    import org.w3c.dom.Element
    import org.xhtmlrenderer.extend.FSImage
    import org.xhtmlrenderer.extend.ReplacedElement
    import org.xhtmlrenderer.extend.ReplacedElementFactory
    import org.xhtmlrenderer.extend.UserAgentCallback
    import org.xhtmlrenderer.layout.LayoutContext
    import org.xhtmlrenderer.pdf.ITextFSImage
    import org.xhtmlrenderer.pdf.ITextImageElement
    import org.xhtmlrenderer.render.BlockBox
    import org.xhtmlrenderer.simple.extend.FormSubmissionListener
    
    public class B64ImgReplacedElementFactory implements ReplacedElementFactory {
    
     public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {
         Element e = box.getElement();
         if (e == null) {
             return null;
         }
         String nodeName = e.getNodeName();
         if (nodeName.equals("img")) {
             String attribute = e.getAttribute("src");
             FSImage fsImage;
             try {
                 fsImage = buildImage(attribute, uac);
             } catch (BadElementException e1) {
                 fsImage = null;
             } catch (IOException e1) {
                 fsImage = null;
             }
             if (fsImage != null) {
                 if (cssWidth != -1 || cssHeight != -1) {
                     fsImage.scale(cssWidth, cssHeight);
                 }
                 return new ITextImageElement(fsImage);
             }
         }
         return null;
     }
    
     protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException, BadElementException {
          FSImage fsImage;
          if (srcAttr.startsWith("data:image/")) {
             String b64encoded = srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length(), srcAttr.length());
             byte[] decodedBytes = new sun.misc.BASE64Decoder().decodeBuffer(b64encoded);
             fsImage = new ITextFSImage(Image.getInstance(decodedBytes));
          } else {
             fsImage = uac.getImageResource(srcAttr).getImage();
          }
          return fsImage;
     }
    
     public void remove(Element e) {
     }
    
     public void reset() {
     }
    
     @Override
     public void setFormSubmissionListener(FormSubmissionListener listener) {
     }
    }
    

    Now, in the code where we call the Renderer, we used :

     byte[] generatePdf(String content) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] bytes = null
            ITextRenderer renderer = new ITextRenderer();
            SharedContext sharedContext = renderer.getSharedContext();
            sharedContext.setPrint(true);
            sharedContext.setInteractive(false);
            sharedContext.setReplacedElementFactory(new B64ImgReplacedElementFactory());
            sharedContext.getTextRenderer().setSmoothingThreshold(0);
            try {
                renderer.setDocumentFromString(content);
                renderer.layout();
                renderer.createPDF(byteArrayOutputStream);
                bytes = byteArrayOutputStream.toByteArray()
            }
            catch (Throwable e) {
                log.error("Error while generating pdf ${e.message}", e)
            }
            return bytes
        }
    

    Now, we can embed images in the form of data URLs in our GSPs using base64 encoded version of the image bytes.

  • Auto Completion for Grails Scripts with Dynamic Version Determination

    16 Aug 2012 in Grails&Linux

    We are constantly striving to be more productive by minimizing key-strokes for a lot of commonly used shell commands. Alias is one way of achieving it, but it isn’t always the answer. Bash auto completion is one feature that I use a lot.

    To avoid the hassles of working with multiple grails projects, I use this script and for auto completion, I use this wonderful auto completion script by Ted Naleid. However, there were a few more scripts/arguments which we thought would be a great addition to the auto-completion set. Scripts provided by plugins was one such set and this had to come from the appropriate directory under .grails/$GRAILS_VERSION/projects/$PROJ_HOME/plugins/*/scripts. Another set of options which I thought appropriate were the system properties that we provide.

    So, I came up with the custom auto completion script given below

    
    _grailsscripts() {
    
        if [ -z "$PROJ_DIR" ]
        then
           if [ -e "application.properties" ]
           then
              export GRAILS_VERSION=`grep app.grails.version application.properties | sed -E 's/.*=(.*)/\1/'`
              export GRAILS_HOME="/opt/grails-$GRAILS_VERSION"
              PWD=`pwd`
              export PROJ_DIR=`basename $PWD`
           fi
        fi
        SCRIPT_DIRS="$GRAILS_HOME/scripts ./scripts ~/.grails/scripts"
        if [ "$PROJ_DIR" ]
           then for PLUGIN_DIR in $(ls -d ~/.grails/$GRAILS_VERSION/projects/$PROJ_DIR/plugins/*/scripts 2&gt; /dev/null); do
           SCRIPT_DIRS="$SCRIPT_DIRS $PLUGIN_DIR"
           done
        fi
        if [ -d plugins ]
           then for PLUGIN_DIR in $(ls -d plugins/*/scripts 2&gt; /dev/null); do
           SCRIPT_DIRS="$SCRIPT_DIRS $PLUGIN_DIR"
           done
        fi
    
        for D in $SCRIPT_DIRS; do
           if [ -d $D ]
             then ls -1 $D/*.groovy 2&gt; /dev/null | sed -E 's/(.*)\/(.*)\.groovy/\2/' | sed -E 's/([A-Z])/-\1/g' | sed -E 's/^-//' | tr   "[:upper:]" "[:lower:]"
           fi
        done | sort | uniq | grep -vE "^_"
    }
    
    grailsOpts="-Dserver.port= -Dgrails.env= test dev prod"
    
    _grails() {
     COMPREPLY=( $(compgen -W "$(_grailsscripts) $grailsOpts" -- ${COMP_WORDS[COMP_CWORD]}) )
    }
    
    complete -F _grails grails
    complete -F _grails grails-debug
    
    

    Now, all you need is to add this script under /etc/bash_completion.d/


    Hope this helps you save a few keystrokes.

  • Overriding properties in a Spring Bean with BeanFactoryPostProcessor

    12 May 2012 in Grails&Spring

    I was going through the source code of one of the Grails Plugins where I found the use of Spring’s BeanDefinitionRegistryPostProcessor to override some configurations that are available in DataSource.groovy. That involved a complete over riding of a PropertyValue definition.

     

    It set me thinking about whether there is a way to override bean properties like String, Integer etc in a simpler way after the bean has initialized. In comes BeanFactoryPostProcessor, which provides a wonderful hook to do just that.

     

    I created a small grails project and added a class CustomBean which looked like this :

    
    class CustomBean {
           String customVariable
    }
    

    I registered a customBean on resources.groovy using

    beans = {
        customBean(CustomBean) {
            String value = "Test Data From resources.groovy"
            println "Setting value ${value}"
            customVariable = value
        }
    
        customBeanPostProcessor(CustomBeanPostprocessor)
    }
    

    This sets the initial value of customVariable as “Test Data From resources.groovy”.

    If you are wondering what the customBeanPostprocessor is, that is just what I am going to explain next.
    The bean implements the BeanFactoryPostProcessor interface and overrides the methods which provides us with hooks to modify the properties of the bean.

     

    The class definition is:

    import groovy.util.logging.Log4j
    import org.springframework.beans.factory.config.BeanPostProcessor
    
    @Log4j
    class CustomBeanPostprocessor implements BeanPostProcessor{
    
        @Override
        Object postProcessBeforeInitialization(Object bean, String beanName) {
            return bean
        }
    
        @Override
        Object postProcessAfterInitialization(Object bean, String beanName) {
            if(beanName == 'customBean') {
                log.debug("Setting custom value inside post processor")
                bean.customVariable = "Set from Post Processor"
            }
            return bean
        }
    }
    

    What amazed me is the elegance with which the developers of the framework has provided entry points into its internals without forcing the users to shave the yak.

     

  • Writing sentences with Groovy 2.0

    22 Mar 2012 in Groovy

    Groovy 2.0 comes with some amazing new features, which prompted a numbering scheme jump from 1.9.x to 2.0. One of the key features that I took note while going through  Guillaume Laforge’s presentation at 33rd Degree was the support for plain language sentences made possible by optional parentheses,  and dots.

    We love the language and we love pizza! So, I put together a small script to demonstrate the power of natural language support available on Groovy 2.0 (Tested the feature on 2.0.0-beta2).

    The PizzaDelivery takes orders and outputs the order.

    
    class PizzaDelivery {
    
        Integer quantity
        String topping
        Date time
    
        PizzaDelivery need(Integer quantity){
            this.quantity = quantity
            return this
        }
    
        PizzaDelivery with(String topping){
            this.topping = topping
            return this
        }
    
        PizzaDelivery at(String time) {
            this.time = Date.parse('h:mm', time)
            return this
       }
    
       String toString(){
            return "${quantity} ${topping} at ${time.format('h:mm')} hours"
       }
    }
    
    PizzaDelivery pizzaDelivery = new PizzaDelivery()
    pizzaDelivery.with{
        need 3 with 'pepperoni' at '6:00'           // need(3).with('pepperoni').at("6:00")
    }
    
    println pizzaDelivery
    
    

    This will allow us to create very simple yet elegant DSLs which would feel like English or any other language that one feels comfortable with.

  • My Top 9 Features from Grails 2.0

    18 Jan 2012 in Grails

    The groovy world is abuzz about the latest release from the Grails Stable, Grails 2.0, which packs a lot more punch than its predecessors, which by themselves were productivity enhancers and wonderful to develop our web applications with. The new version brings with itself a lot of changes compared to the previous releases and deserves to be truly called 2.0 instead of 1.4 or 1.5.

    I would like to walk you through some of the coolest features from grails 2.0 that I have discovered in the limited time I have spent with the new version and fell in love with.

    1. The Improved Interactive Mode: I love working on the command line and the new interactive mode is a joy to work with. The auto-completions, combined with the quick response times(as a result of not having to load JVM for each command) is a sure shot productivity booster. That I can run normal commands from the grails shell by just prefixing them with a “!” is an added advantage.
    2. Dynamic Domain Class Reloading: One activity that consumed a lot of time with earlier versions of Grails was waiting for the servlet container to restart, once we made even a line’s change in the domain class or src/groovy file. Now, the reloading is dynamic which means that the changes take effect very quickly, this letting us focus on the development without the flow being interrupted by the restart process.
    3. HTML5 scaffolded screens: One of the complaints I had with earlier versions of grails was the not-so-good looking screens that were generated by scaffolding. For most of the admin screens, the scaffolded screens are sufficient and the new HTML5 compatible scaffolded screens are very easy on the eye and provide an excellent user experience. With the new screens however, I can simply change the logo and they make for sufficiently pleasing CRUD screens.
    4. Business Class Citizenship for Testing: Testing has been a first class citizen of the framework right from day 1, but the new testing framework has made life easy for people like me, for whom testing doesn’t come naturally. With scaffolded tests being generated, newbies will find it easier to learn aspects of testing the application. In addition to that, the capability to unit-test criteria queries adds an element which was missing from earlier versions.
    5. Link Generation/Page Renderer APIs: Earlier, generating html from gsp files from non-request bound threads was a pain, especially with mocking the web request. Now, with the PageRenderer API, generating a view in a job or a service is as simple as injecting a groovyPageRenderer bean and calling groovyPageRenderer.render() method just like from within a controller.
    6. GORM Finders with Groovy Collection find/findAll like syntax: If there was one feature I could keep from all the enhancements in 2.0, it would be this. This is also the feature which, I think would go a long way in making GORM queries easier. There couldn’t be a more expressive syntax!
    7. Public methods in controllers as actions which can take arguments: Earlier, it used to be a pain to type-cast the parameters into their respective types(when one felt that command objects are an overhead while working with at most 2-3 params). The new method like syntax lets us define actions as public methods in controllers, which automatically bind data to the method arguments, based on the params. If I have a command object as argument, it works just the way it worked earlier. We talk about thin controllers a lot. This also means that we’ll be more diligent while creating methods in controllers and even if we really must, they have to be private. This just made the controllers thinner!
    8. The New Improved Test Reports: The new test reports are very easy on the eye and even more easier while finding test failures. Though we don’t recommend having println statements in our test cases, the fact that I can see the system outputs on the same page as my test case is a winner.
    9. DB Console: Viewing the contents of the in-memory DB was a pain in the earlier versions. The new dbconsole, which can be accessed only in development mode is a clear winner.

    Grails 2.0 comes with its set of wonderful features which makes development with it, a much better experience.

  • Grails Custom Data Binding in 3 Simple Steps

    29 Dec 2011 in Grails

    The other day, Farid came with an interesting problem of binding a Time String to java.sql.Time. We straight away found the answer in using a CustomTimeEditor and registering it using a CustomPropertyEditorRegistrar bean. We were able to come arrive at this solution, thanks to this StackOverflow thread.

    This set me thinking into using a CustomProperty Editor for, say a Cost object, which could contain a unit and an amount

    
    class Cost{
    
    String unit //Could be constrained to belong to some range of values
    
    BigDecimal amount
    
    }
    
    

    I was able to solve this issue in 3 simple steps which I would like to share with you. I felt that this would take a lesser amount of time compared to the Extended Data Binding Plugin(my gut feeling)

    1. Add a CustomCostEditor to src/groovy

    
    import java.beans.PropertyEditorSupportimport org.springframework.util.StringUtils
    class CustomCostEditor extends PropertyEditorSupport {    private final boolean allowEmpty
            CustomCostEditor(boolean allowEmpty) {
                   this.allowEmpty = allowEmpty
            }
            @Override
            void setAsText(String text) {
                   if (this.allowEmpty && !StringUtils.hasText(text)) {
                         // Treat empty String as null value.
                         setValue(null);
                   } else {
                          setValue(parse(text))
                   }
            }
            @Override
            String getAsText() {
                    Cost cost = (Cost) getValue()
                    return "${cost.unit} ${cost.amount}"
            }
           Cost parse(String text){
                    try{
                         new Cost(unit: text.substring(0, text.indexOf(" ")), amount: text.substring(text.indexOf(" ") + 1).toBigDecimal())
                    } catch(Exception exception){
                         throw new IllegalArgumentException("Cost should be of the format 'Unit Amount'")
                    }
           }
    }
    

    The methods which we need to override are setAsText() and getAsText()
    2. Add a CustomPropertyEditorRegistrar class, which has a registerCustomEditorMethods

    import org.springframework.beans.PropertyEditorRegistrar
    import org.springframework.beans.PropertyEditorRegistry
    
    class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar{
        public void registerCustomEditors(PropertyEditorRegistry registry) {
            registry.registerCustomEditor(Cost.class, new com.intelligrape.example.CustomCostEditor(true));
        }
    }
    

    3. Add a spring bean to add an instance of this custom property editor registrar
    Finally, we create a spring bean by adding the following line in resources.groovy

    beans = {
        customPropertyEditorRegistrar(CustomPropertyEditorRegistrar)
    }
    

    Now, assuming that we have an embedded field cost of type Cost in a domain class Item, we can simply use

    <input type="text" name="cost" value="${fieldValue(bean: item, field:'cost')}"/>
    

    and input “$ 123″ to store $ in the cost.unit and 123 in the cost.amount.

    I believe that the possibilities with such an approach are infinite!

  • Writing JSON APIs : Part II – Creating JSON Named Configs to Control What You Render

    29 Dec 2011 in Grails

    In the 1st part of the series, we looked at how to secure our application with Spring Security Basic Authentication and modifying the JSON Marshaller. However, it could often be the case that the same set of fields shouldn’t be returned on every JSON response.

    For example, we could very well have a summary JSON for Book, which just returns the id and name of the Book, ignoring the other details like ISBN, genre etc. A real life example would be a Product’s complete details when returning JSON for its show view, while returning just the id, name and price for its view in a shopping cart.

    In addition to that, we could choose, not to override the default JSON Marshallers provided by Grails so that the standard rendering method is not tampered.

    Grails provides an excellent solution called “Named Configurations” which comes to our aid here. That, combined with some minor modifications on our CustomDomainClassJSONMarshaller can help us achieve this.

    1. Add a static Map to the domain class, probably jsonProperties :

    This property will hold the group name as key and the list of properties to be included as values.

    
    //Book.groovy
    
    static jsonProperties = [summary:['name']] //summary is the group name
    
    

    2. Update the CustomDomainClassJSONMarshaller to have a property jsonPropertyGroup :

    String jsonPropertyGroup
    public CustomDomainClassJSONMarshaller(boolean includeVersion, GrailsApplication application, String jsonPropertyGroup = "") {
          this(includeVersion, new DefaultProxyHandler(), application, jsonPropertyGroup);
    }
    public CustomDomainClassJSONMarshaller(boolean includeVersion, ProxyHandler proxyHandler, GrailsApplication application, String jsonPropertyGroup) {
          this.includeVersion = includeVersion;
          this.proxyHandler = proxyHandler;
          this.application = application;
          this.jsonPropertyGroup = jsonPropertyGroup
    }
    

    3. Update the custom marshaller registrations to create Named Configs :

    This method needs updation for two reasons

    • Calling the newly created constructors
    • API changes in grails 2.0

    For creating a named config “summary”, we need to write something like

    
    JSON.createNamedConfig(JSONConstants.SUMMARY_JSON_MARSHALLER_GROUP){
         it.registerObjectMarshaller(new CustomDomainClassJSONMarshaller(false, grailsApplication, "summary"), 2)
    }
    
    

    4. Using the newly registered named configs from within the controller:

    This is the final step. We can use the named config with a static method JSON.use(), which takes in the configuration’s name and a closure inside which we will call the render <XYZ> as JSON method

    
    JSON.use("summary"){
         render Book.list() as JSON
    }
    
    

    I have updated the example application to grails 2.0 and added an example to this approach.

    Grails never ceases to amaze me. :)

  • Load Testing Made Easy with a Simple JMeter Utility

    30 Nov 2011 in Test

    Load Testing is one of the major aspect which we all do for our applications, especially for those which have publicly available pages and has very heavy traffic. JMeter is a very commonly used tool for doing load testing. As developers, it is a very good tool to have in our skill set.

     

    However we, as lazy productive developers are always trying to automate the processes so that we just need to configure it once and be able to run it from anywhere. Also added it to is the small matter of eliminating internet speed from the equation while load testing the pages. (Especially when we are concerned only with how the server responds to high loads). This means that we will be running the tests one of our remote servers which are closer to QA servers(or even the same machine!). We may also run schedule the tests to be run at night.

     

    Himanshu and I modified some of the scripts he had written for one of the projects to make it more generic and generate Jmeter scripts and also a utility to run it for us and generate reports. The scripts(which run on *nix machines) are available here.

     

    The steps to set it up are as follows

    1. Download Jmeter and install it at the location /opt/jmeter (The path to jmeter home would be /opt/jmeter)
    2. Install ant by doing (sudo apt-get install ant on Ubuntu)
    3. Clone/Fork the Git repository to your machine
    4. Add the ant-jmeter-<version>.jar file available at the Git Repo to /usr/share/ant/lib

    The steps to configure and run the scripts are as follows

    1. Update conf.txt to suit your needs. It is a CSV file with the following parameters specified. URL,PORT,Path/?QueryParam=Value,TestName
    2. Update generate.groovy to configure parameters like number of threads, duration for the run, Test Name, Test Title etc
    3. Make generate.groovy and driver.sh executable (chmod +x generate.groovy driver.sh)
    4. Execute generate.groovy (./generate.groovy). This generates the required jmx files and updates the build.xml file
    5. Execute driver.sh (./driver.sh). This run the actual test
    6. The reports will be available under the target directory as TestName.html

    The utility is very simple at the moment which caters only to simple get requests. In future, we would like to include Controllers, Config elements etc to be configurable, so that this utility can also be used for running Load Tests for secure pages.

     

    We would be delighted to know what you would like to see in the future versions of this utility. :)