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:

  • 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.

    • Share/Bookmark
  • 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!

    • Share/Bookmark
  • 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. :)

    • Share/Bookmark
  • 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. :)

     

    • Share/Bookmark
  • Writing JSON APIs : Part I – Creating a secure JSON API with Grails and Spring Security in 3 easy steps

    16 Nov 2011 in Grails

    We had a requirement in a recent project to expose some of the functionality we had via a JSON API. The functionality needed to be secure, as was the initial web interface which exposed the functionality. We were using Spring Security for the security aspect of our application.

    The spring security plugin, together with a secured controller and a custom JSON marshaller(which overrides the default functionality of render as JSON method) gave us a very simple, yet elegant and powerful JSON API which was secure. Here are the three steps that we followed

    1. Setting up Spring Security Plugin:

    The first step is to set up Spring Security Plugin to expose our JSON based controllers to use Basic Authentication, instead of the standard web based authentication. This is done by adding the lines given below in Config.groovy

    //Enable Basic Auth Filter
    grails.plugins.springsecurity.useBasicAuth = true
    grails.plugins.springsecurity.basic.realmName = "JSON API Example"
    //Exclude normal controllers from basic auth filter. Just the JSON API is included
    grails.plugins.springsecurity.filterChain.chainMap = [
    '/json/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
    '/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
    ]
    

    More details about the authentication mechanism can be found here.
    2. Adding a Controller with required actions:

    Naturally, this is the next step. We added a controller which would expose the functionalities required(another reason why most of our logic should be in our services instead of controllers). A sample controller would look like this.

    package jsonapi
    import grails.plugins.springsecurity.Secured
    import grails.converters.JSON
    import com.intelligrape.example.json.Book
    
    @Secured(["ROLE_USER"])
    class JsonController {
          def getBooks = {
              render Book.list() as JSON
          }
    }
    

    3. Customizing the Marshaller to change the way some properties like enums are rendered:

    We had to change the way some of the properties like enums were going to be rendered. We just had to render the property name and the id of the enum. So instead of a json map like

    
    "genre":{"enumType":"com.intelligrape.example.json.Book$Genre","name":"FICTION"}
    

    we needed

    
    "genre":"FICTION"
    

    I sought help from David Bower’s post and created my own custom Domain Class Marshaller for JSON with a modification to just use the Enum value if the property happened to be an enum. This is a very powerful feature because it allows us to customize the way in which we want to render the values when creating a JSON or XML document from our classes. We can even customize it to have an excludes list in our domain class where we can specify the properties to be excluded while constructing our JSON or XML

    With this, we had a JSON API ready in very little time. I have extracted the functionality into a small example application, which has been shared on Github.

    Yet another example of how simple grails has made it easy for developers.

    • Share/Bookmark
  • Mounting an EBS Volume to an Instance and Soft Linking a Growing Directory to it

    05 May 2011 in Database& Linux& System

    We were having a crisis on our project the other day. The VPS on which we were running our application had some issues with kernel and Tomcat, for that matter, any java process was running unpredictably. Tomcat would explode the WAR file once in a while and even if it did, it would just pause at “Deploying app.war” forever. After spending some time troubleshooting (we didn’t know that it was an issue with the kernel), we decided to move our infrastructure to Amazon EC2. We picked up an EBS based large instance, running Ubuntu and copied the setup from our production server to this new machine. The setup was a breeze, thanks to the scripts we already had in place for migrating our production setup to our QA machines for testing purposes.

    However, we realized that Image Magick, which was being used from our application was not working as expected. In fact, it wasn’t working at all. We noticed that we were able to perform it as root, but not as any other user. The error which showed up was that there was lack of disk space. Static documents generated by our application were stored on the file system and it was meant to be an ever expanding directory. The EBS instance we had chosen had a capacity of just 8GB and about 6 GB of that was being occupied by the OS and the rest of our infrastructure. We decided to move this particular directory to a new EBS volume.

    This could be accomplished smoothly, thanks to the ease of attaching a new EBS volume to an instance. We added a new volume and then, performed the following steps to move this particular expanding directory.

    
    mke2fs -F -j /dev/sdh #This is to create an ext3 file system for the device attached at /dev/sdh
    
    mkdir /path_to_new_file_system
    
    mount /dev/sdh /path_to_new_file_system #mount the new file system at this directory
    
    cp -r static_documents_location /path_to_new_file_system #Copy the files from the existing directory to the new directory
    
    mv static_documents_location static_documents_location_backup #Backup the existing documents, just in case anything goes wrong
    
    ln -s /path_to_new_file_system/static_documents_location static_documents_location #Create a soft link to refer to the new file location with the same name as the previous one
    

    With these steps, we were good to go on the Amazon machine without even requiring a Server restart. We were expecting a downtime of at least 10 minutes but this happened so flawlessly.

    Hope this helps someone.

    • Share/Bookmark
  • ISO-8859 Based URL Encoding in Grails

    11 Apr 2011 in Grails

    The web application we are developing at the moment interacts with quite a few third party services via REST calls. Most of the third party services use UTF-8 encoding and there was no issues with using the URLCodec, that grails provides out of the box. However, one of the applications our application interacts with, was using ISO-8859-1 encoding. This meant that the use of encodeAsURL() provided by grails resulted in misinterpretation of data sent by us to those services. (The audience to which the site caters has languages extensive use of characters like å, Å, ä, Ä etc).

    On going through the URLCodec which grails provides out of the box, we found that the encoding is UTF-8 by default and can be overridden only by the encoding flag in the incoming HTTP request. However, the REST calls we make were outside of HTTP requests and the encoding for the rest of the application is UTF-8.

    Therefore, we ended up writing a custom IsoURLCodec, which could be used while dealing with this particular service, which needed ISO-8859-1 encoding of URLs as opposed to UTF-8 used by all other services.

    class IsoURLCodec {
    static encode = { obj ->
    URLEncoder.encode(obj.toString(), "ISO-8859-1")
    }
    static decode = { obj ->
    URLDecoder.decode(obj.toString(), "ISO-8859-1")
    }
    }
    
    Now, we could make use of calls like
    "${'<span style="font-family: sans-serif;">Philippe Pétain</span>'.encodeAsIsoURL()}"
    
    to encode the name to the corresponding ISO-8859-1 encoded URL.
    Hope this helps.
    • Share/Bookmark
  • Using Google Analytics for tracking Multiple Steps of a Webflow

    In one of our projects, we are using a webflow for an order wizard. We needed to track the number of users converting a draft to a confirmed order using Google Analytics. This would have been simple if the URLs were different for each step. However, that is not the way webflows work and a similar URL is generated for multiple steps. After some searching around, we found that we could call a trackPageView method in Google Analytics API and set a name for the page being tracked. This could be done using

    <script type="text/javascript">
        try {
            var pageTracker = _gat._getTracker("<ANALYTICS-KEY>");
            pageTracker._trackPageview("/enterDetails.html");
        } catch(err) {
        }
    </script>
    

    Replacing “/enterDetails.html” in each page with the corresponding step name did the trick. However, this is an old version of the Google Analytics API. Our application uses a newer version of the JavaScript code provided by Google.

    In this, we had to use Virtual Page Tracking, which is a method explained in the Google Analytics API Docs under the section, Virtual Page Views. We had to write something like

    
    <script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'ANALYTICS-KEY']);
    _gaq.push(['_trackPageview', '/enterDetails.html']);
    (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();
    </script>
    

    For usage on grails, we used a template, which takes in the pageName and uses /${controllerName}/${actionName}/${pageName} to  generate the virtual page name which is tracked. Now we are successfully tracking the conversions.

    Hope this helps.

    Vivek

    http://in.linkedin.com/in/svivekkrishna

    • Share/Bookmark
  • Grails Mail Plugin with DB Driven configuration

    03 Feb 2011 in Grails

    We have been coming across a certain use case in a couple of projects that the Email credentials/settings used for sending email should be different based on the from address. This is because the applications act as software services that are used by different organizations, which operate in the same business. And each needed their own customized emails and use their email credentials for sending of mails.

    After searching a lot for such a solution, we found that such a use case has arisen for quite a few developers.

    Another demand was that a mail service provider like GMail be used to send emails instead of using a mail server like Postfix of Sendmail.

    What we came up was a modified version of the grails mail plugin, which works with DB driven mail configurations. It defaults to Config.groovy it it fails to fetch the MailConfig domain object based on the from address,  which we usually in the sendMail() method. The plugin makes use of a customMailSender bean, which is actually a copy of the mailSender bean which gets built from Config.groovy, but can be modified in a thread safe environment with values fetched from the DB.

    The plugin is still in its infancy, but you can download the plugin and its source code here. You can read the documentation here.

    Hope you find this useful

    Vivek

    http://in.linkedin.com/in/svivekkrishna

    • Share/Bookmark
  • Request Mocking to use groovyPagesTemplateEngine in backend threads

    27 Dec 2010 in Grails

    We have a setup where a backend thread, fired by the Spring Events, does some processing, generates a PDF and emails the result to the user.
    The code we were using to generate the HTML from a GSP to be converted to a PDF using iText was as follows :

            def webRequest = RequestContextHolder.getRequestAttributes()
            def originalOut = webRequest.out
            try {
                def sw = new StringWriter()
                def pw = new PrintWriter(sw)
                webRequest.out = pw
                groovyPagesTemplateEngine.createTemplate("path_to_gsp").make([model:model]).writeTo(pw)
                return sw.toString()
            } finally {
              webRequest.out = originalOut
            }
    

    There was the obvious fallibility of this code that there was no Current Request associated with the backend thread!

    After doing some googling around it, I came across a few threads and posts which talked about Request Mocking, which has been used in Grails Template Engine Plugin.  We overcame this by using the code snippet given below to mock the web request

    def webRequest = RequestContextHolder.getRequestAttributes()
    if(!webRequest) {
              def servletContext  = ServletContextHolder.getServletContext()
              def applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
              webRequest = grails.util.GrailsWebUtil.bindMockWebRequest(applicationContext)
    }
    

    However, things didn’t end there. This code broke while working on a WAR environment. The problem was that the MockWebRequest class was part of the “org.springframework:org.springframework.test:3.0.3.RELEASE” jar and had to be included in the BuildConfig.groovy as

    
    dependencies{
    
    runtime 'org.springframework:org.springframework.test:3.0.3.RELEASE'
    
    }
    

    Ensure that the line

    
    mavenCentral()
    

    is not commented in BuildConfig.groovy

    We were working on Grails 1.3.4

     

    Hope this helps.
    Vivek

    http://in.linkedin.com/in/svivekkrishna

    • Share/Bookmark