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

Tuesday, July 10, 2012

Grails 2.1.0 performance

In this installment we'll be checking out the performance of the latest (2.1.0) version of Grails compared to 1.3.9 and 2.0.4. So without further due let's jump right into the code.

The HomeController
class HomeController {
  def index() {
    def date = new Date()
    redirect uri: date.format("/yyyy/MM")
  }

  def page() {
    def months = [ '', 'January', 'February', 'March', 'April', 'May', 'June', 
      'July', 'August', 'September', 'October', 'November', 'December' ]
    [ year: params?.year, month: params?.month, months: months ]
  }
}

So we see 2 actions here: one that checks the current date and does a redirect and one that spits out some data to view. So let's see the view then :)

The page.gsp:
<!doctype html>
<html>

<head>
  <title>Galery</title>
</head>

<body>
  <ul>
    <g:each in="${1..12}" var="i">
    <li class="${i == month ? 'current' : ''}"><a href="/${year}/${i}">${months[i]}</a></li>
    </g:each>
  </ul>
</body>

And now - time for benchmark results. All applications started this way:

grails prod run-war

and benchmarked using Apache Benchmark like this:

ab -n 1000 -c 10 http://localhost:8080/example/2012/03 up until the point when the figures became stable (usually between 20-30 executions with 5-10 seconds breaks in between).

Grails 1.3.9

Server Software:        Apache-Coyote/1.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /example139/2012/03
Document Length:        776 bytes

Concurrency Level:      10
Time taken for tests:   0.526 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      942000 bytes
HTML transferred:       776000 bytes
Requests per second:    1902.84 [#/sec] (mean)
Time per request:       5.255 [ms] (mean)
Time per request:       0.526 [ms] (mean, across all concurrent requests)
Transfer rate:          1750.47 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:     1    5   3.5      4      41
Waiting:        1    5   3.5      4      41
Total:          1    5   3.6      4      41

Percentage of the requests served within a certain time (ms)
  50%      4
  66%      6
  75%      6
  80%      7
  90%     10
  95%     12
  98%     14
  99%     17
 100%     41 (longest request)

Grails 2.0.4

Server Software:        Apache-Coyote/1.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /example204/2012/03
Document Length:        776 bytes

Concurrency Level:      10
Time taken for tests:   0.235 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      942000 bytes
HTML transferred:       776000 bytes
Requests per second:    4254.25 [#/sec] (mean)
Time per request:       2.351 [ms] (mean)
Time per request:       0.235 [ms] (mean, across all concurrent requests)
Transfer rate:          3913.58 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       5
Processing:     1    2   1.5      2      16
Waiting:        0    2   1.5      2      16
Total:          1    2   1.6      2      16

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      3
  80%      3
  90%      4
  95%      5
  98%      7
  99%     10
 100%     16 (longest request)

As we can see there's quite a performance gain between 1.3.9 and 2.0.4. Good!

Grails 2.1.0

Server Software:        Apache-Coyote/1.1
Server Hostname:        localhost
Server Port:            8080

Document Path:          /example/2012/03
Document Length:        776 bytes

Concurrency Level:      10
Time taken for tests:   0.333 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      942000 bytes
HTML transferred:       776000 bytes
Requests per second:    3002.16 [#/sec] (mean)
Time per request:       3.331 [ms] (mean)
Time per request:       0.333 [ms] (mean, across all concurrent requests)
Transfer rate:          2761.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       3
Processing:     1    3   3.0      2      29
Waiting:        0    3   2.9      2      29
Total:          1    3   3.0      2      29

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      3
  75%      4
  80%      4
  90%      6
  95%      9
  98%     12
  99%     17
 100%     29 (longest request)

It looks like 2.1.0 is a little bit (actually 1/4th) slower in this case than 2.0.4. Interesting...

Rails 3.2.6


For comparison I've done a similar experiment translating the the same routing, controller and view to Rails (just out of curiosity).

We'll start the application under Unicorn with 4 workers (that's how many cores my notebook has)

unicorn -E production -p 9393 -c config.rb

And the config.rb
worker_processes 4

Server Software:        
Server Hostname:        localhost
Server Port:            9393

Document Path:          /2012/03
Document Length:        728 bytes

Concurrency Level:      10
Time taken for tests:   1.109 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1000
Total transferred:      983000 bytes
HTML transferred:       728000 bytes
Requests per second:    901.84 [#/sec] (mean)
Time per request:       11.088 [ms] (mean)
Time per request:       1.109 [ms] (mean, across all concurrent requests)
Transfer rate:          865.73 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     6   11   5.9     10      64
Waiting:        6   11   5.9     10      64
Total:          7   11   5.9     10      64

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     11
  75%     11
  80%     12
  90%     14
  95%     15
  98%     19
  99%     55
 100%     64 (longest request)

Sinatra


Now let's take a look at how a similar case will handle a Ruby framework, Sinatra.
require 'rubygems'
require 'sinatra'
require 'slim'

disable :logging

get '/' do
  date = Time.now
  redirect "/#{date.year}/#{date.month}"
end

get '/:year/:month' do
  @current = Time.new(params[:year], params[:month])
  @months  = [ '', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]
  slim :index
end

__END__

@@ index
doctype html
html
  head
    title Galery
  body
    ul 
      - (1..12).each do |month|
        li class="#{@current.month == month ? "month current" : "month"}"
          a href="/#{@current.year}/#{month}" #{@months[month]}

We're using sinatra with slim templating engine (my favorite!). We'll start the application the same way as the Rails app above.

Now for the actual results:
Server Software:        
Server Hostname:        localhost
Server Port:            9393

Document Path:          /2012/03
Document Length:        709 bytes

Concurrency Level:      10
Time taken for tests:   0.449 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      922000 bytes
HTML transferred:       709000 bytes
Requests per second:    2227.71 [#/sec] (mean)
Time per request:       4.489 [ms] (mean)
Time per request:       0.449 [ms] (mean, across all concurrent requests)
Transfer rate:          2005.81 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     1    4   2.8      4      29
Waiting:        0    4   2.8      4      29
Total:          1    4   2.8      4      29

Percentage of the requests served within a certain time (ms)
  50%      4
  66%      4
  75%      5
  80%      5
  90%      6
  95%      7
  98%     12
  99%     22
 100%     29 (longest request)

Ok, now you can really see the difference in count of bytes sent over the wire. That's due to the differences in view technology (slim is very compact in the actual output)

At the end of the day the performance of both Grails and Sinatra (even though not very comparable) is similar with a clear performance winner :) Rails lacks a bit in performance.

There is however a difference in startup time and memory usage:

FrameworkMemoryStartup time
Grails 1.3.9485.1MB21.95s user 0.76s system 109% cpu 20.656 total
Grails 2.0.4699.3MB53.51s user 1.38s system 152% cpu 35.942 total
Grails 2.1.0713.1MB30.19s user 1.30s system 106% cpu 29.609 total
Rails 3.2.6169.8MB9.64s user 0.68s system 259% cpu 3.977 total
Sinatra on Unicorn82.1MB1.46s user 0.18s system 55% cpu 2.963 total

Have fun!

Thursday, April 5, 2012

Grails, Hazelcast, Hibernate and 2nd level cache

If you'd like to use Grails with Hazelcast caching solution you need to be aware that there is an issue with Hazelcast compatibility with the version of Hibernate used by Grails (3.6.10.Final).

Reading on the Hazelcast Wiki you'll be tempted to use the "new" ways and specify hibernate.cache.region.factory_class. Unfortunately that doesn't work. See this bug report for more information.

But there is hope! Instead you can specify hibernate.cache.provider_class and everything should work as expected. Hibernate does all the adapter heavy lifting and life is good again :)

Anyways, Hazelcast is plain ecstatic - you should really give it a try and get a feel of what a good library feels like when you use it. It's awesome!!!

Wednesday, February 15, 2012

Grails, documentation and images

A quick tip of the day:

if you're creating a Grails project and want to provide documentation for it it might stand a chance you'll need to include images in that documentation. Unfortunately the official documentation is very sparse in this regard showing you only the syntax for including external images. As it turns out it is possible to have images that come specifically with the docs. All you need is to specify
grails.doc.images = new File("src/docs/images")
and then include them in the docs as usual but without a URL
!my-image.png!
Thanks to Lauro Becker for that hint!

Sunday, January 29, 2012

Grails and Ratpack

Today I've found out about the Ratpack plugin. Being a huge Sinatra fan I was quite fond of the Ratpack framework to begin with and naturally I was amazed to see it incorporated into Grails as a plugin. And it works!

Let me walk you through a very simple example of using Ratpack inside Grails.

We start by enabling the Ratpack plugin in our application. I called mine app "example" so all the URLs will be prefixed with "/example". To include the plugin you need to add it to grails-app/conf/BuildConfig.groovy like this:

With that in place we'll create a domain class to have some data to display. I'll go with the simplest possible class that represents a person grails-app/domain/Person.groovy:

Simple enough, right? Let's go an make some use of it in a Ratpack file. Create a folder grails-app/ratpack and inside of it a file called PersonRatpack.groovy:

As you can see here all we're doing is responding to the GET method on some root URL. Ratpack uses SimpleTemplateEngine from Groovy. We have to tell it where to look for templates Config.groovy:

So let's create one to display the people from database grails-app/ratpack/templates/list.html:

Simple enough, right? It almost looks like a mix of ERB and expression language from JSP. I think you'd have to ask the authors of SimpleTemplateEngine if those similarities have been made on purpose of if this syntax just seemed to be the only one that made sense...

Anyways, with all that in place we can add some people to the database in our grails-app/conf/BootStrap.groovy file like this:

And that's it! start the application, navigate to http://localhost:8080/example/ratpack and you should see the list of two people on the screen.

Needless to say you can accomplish the exact same thing using a controller and a view. The idea here however is to show you that there is life beyond the standard artifacts and that the beauty lies in diversity!

Hope this will help someone get started with this awesome piece of code!

Wednesday, December 28, 2011

Grails, Heroku and spring-security-core

This one is going to be quick, but made me spent almost 2 hours to google it...

If you install the spring-security-core plugin and want to deploy your application o Heroku you'll end up with a nasty-looking exception like this:

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.


If you google for No thread-bound request found you'll find some Jira issues that'll tell you pretty much nothing besides that it is a Grails issue.

Among other search results is also this one stating that the actual issue is with the webxml plugin being snatched in the wrong version and that you need to force Grails to use the right one like this:
BuildConfig.groovy:
compile ":webxml:1.4.1"
Just put the line above in your build config and life is good again.

See ya!

Edit 2012-04-05

As of Thu Dec 22 22:35:30 2011 -0500 Burt has upgraded to webxml-1.4.1 so you shouldn't experience this problem anymore.

Saturday, December 3, 2011

Grails routing plugin family updated

It's about time the routing plugin providing EIP functionality for Grails be updated to work with the latest version of Grails which at the time of writing is 2.0.0.RC3. And so today the plugin has been updated to 1.1.4-SNAPSHOT with the plan to release 1.1.4 by the time Grails 2.0.0 final will be out.

Here are the highlights of 1.1.4-SNAPSHOT:

  • Apache Camel core libraries updated to 2.9.0-RC1 (with the plan to upgrade to 2.9.0 final once it gets out)
  • Apache ActiveMQ (routing-jms plugin) upgraded to 5.5.1

Also the example project has undergone some extensive upgrade:


The last feature is a response to an issue posted on GitHub that had to do with providing access to services from processors which Camel is already capable of - it just requires some additional work but it is so not without reason.

I hope you'll enjoy!

Monday, November 28, 2011

Grails 2.0 - the power is back

Recently I've been bitching about the stability of Grails 2.0 and specifically the lack of it. Tons of stuff was just wrong: the new GSP parser was buggy like hell, hot-reloading using the new agent just didn't work - you name it. But with the RC1 release most of it is gone and the new version of Grails starts to look like something you could actually use!

Hot reloading.

Since its early days Grails was the number one framework and that in most part due to its hot-reloading capabilities. You could just change a view, controller or service, wait just a few seconds and the result would emerge after refreshing the page. That presented a huge advantage over classic Java EE development where a single change in the code forced the developer to recompile and restart the whole application. That's why I hate regular Java EE development with a passion. Sure there's the Java Rebel thingy but it costs money - a lot of money!

Grails 2.0 uses a different approach than the one in 1.x series but a similar one to Java Rebel. There's a Java agent that does all the heavy lifting of incorporating new code into existing application. So let's summarize what works and what doesn't:

- reloading controller - check
- reloading services - check
- reloading url mappings definition - check (with the exception of mapping to HTTP codes)
- reloading domain classes - not working
- reloading Groovy sources under /src/groovy - check!
- reloading Java sources under /src/java - check!

There might be other areas but the general impression is really awesome!

New scaffolding templates


Well.. they are nice and green and dandy and... well I liked the old ones better (from the general look-and-feel point of view). The new ones still use the word "main" for everything: CSS, template and the application.js. Does anyone knows who made that stupid decision to call "main" or "application" something that should be called "scaffold"??? In the current state of things if you're thinking about doing anything serious with Grails you should install the templates and rename them to something that makes sense, like for example main.gsp -> scaffold.gsp or main.css -> scaffold.css. Other than that it's looking really good! Just the fricken naming...

Resources and other capabilities


Well, finally the resources plugin made it into the core! So from now on the problems like having lots of small JavaScript or CSS files and cramming'em together for the release version are gone. This is probably the only platform out there (besides ASP.NET :D) that does it right from the start. Granted it doesn't come for free - you need to configure it properly and it can be an unpleasant experience all along (unlike in ASP.NET where it's actually a part of the page itself). But at the end of the day it is really useful and you should use it.

Also the Datasources plugin found its sibling in the new release! This will be a blessing for everyone that needs to work with multiple databases in their Grails applications. In the databases plugin configuration was "almost" like the one you'd normally have but different enough to make you curse the creator more than once. I'm delighted to say that this has been unified and finally all datasources can be specified in the same configuration file, DataSource.groovy. Yay!!!

And last but not least - testing. Finally someone took the hard dependency on old 3.x JUnit and flushed it down the toilette! Man that was really what I was looking for. All test cases are now JUnit version independent and use the coolest Groovy feature ever: Mixins!
Finally testing domain classes in isolation is possible and doesn't make you puke at the mockDomain() call every time you see it. Finally the power is back!

Plugins


I've received some notifications that the plugin architecture has change a bit and that some of my plugins (namely the json-rest-api) don't work properly. It's sad but not unexpected. The general idea is that plugin authors will have to take a good look into regression before they can 'certify' their plugins as 2.0-ready.

Summary


The general feeling of Grails 2.0 is really great. Finally playing around with most of the UrlMappings is simple and fast (which it wasn't in 1.x), testing is fun again (even with Spock and the like) and all the rest is just great. So I guess the final message should be "go and use and forget about 1.3.7 that has been around for like ages".

And finally I really need to get this out of my chest: when it comes to regular Java EE development like with JSF (outch), Struts or what have you one should really go kick some corporate butts to get them to start thinking again that web development shall not be a nightmare anymore. We have the technology, you know, to make it right for a change!

Go spread the word!

Sunday, October 16, 2011

Hazelcast and Grails

If you'll ever find yourself in need to partition your Grails application in order to provide high or availability or if you're lucky enough in order to increase processing power because your database is already not the bottleneck (which it will be for a long long time) then you should definitely check out Hazelcast and its Hazelcast WM module. Configuration is dead simple (a few lines in web.xml) and the thing is capable of auto discovery using multicast so you just add instances of both the Hazelcast distributed cache as well as instances of your application and everything just works.

Man, it's been a while since I found a tool that just does the job no questions asked and Hazelcast definitely is one of them!

And live is good again :)

Thursday, September 8, 2011

Grails, multi-tenant plugin and a bag of small issues

If you'll ever need a multi-tenant solution and you're lucky enough to use Grails going with the multi-tenant-core plugin is definitely the way to go. It's pretty easy to use in the "multiTenant" mode but some strange issues come up when trying yo use the "singleTenant" mode. In this installment I'm going to walk you through a solution that'll allow you to understand how things are and what you should avoid.

The debug solution

To make our "explorer" live easier we're going to provide a custom tenant resolver so that we'll be able to specify a query string like ?tid=1 to select the tenant with id = 1.
package org.example

import javax.servlet.http.HttpServletRequest
import grails.plugin.multitenant.core.TenantResolver

class TestTenantResolver implements TenantResolver {
    Integer getTenantFromRequest(HttpServletRequest request) {
        def tid = request.queryString =~ /tid=(\d+)/
        return tid ? Integer.parseInt(tid[0][1]) : 0
    }
}
To use it just register a bean with name tenantResolver in resources.groovy like
tenantResolver(org.example.TestTenantResolver)
this and you're all set.

The data sources

Although the documentation will tell you that in the tenant configuration DSL you can specify JDBC URLs directly it is unfortunately not true. You need your JDBC datasources registered in JNDI for the multi-tenant plugin to pick them up. It's done in Config.groovy like this:
grails.naming.entries = [
    "jdbc/foo": [
        type: "javax.sql.DataSource", 
        driverClassName: "org.hsqldb.jdbcDriver",
        url: "jdbc:hsqldb:file:target/db-dev-tid-1;shutdown=true",
        username: "sa",
        password: "",
        maxActive: "8",
        maxIdle: "4"
    ],
    "jdbc/bar": [
        type: "javax.sql.DataSource", 
        driverClassName: "org.hsqldb.jdbcDriver",
        url: "jdbc:hsqldb:file:target/db-dev-tid-2;shutdown=true",
        username: "sa",
        password: "",
        maxActive: "8",
        maxIdle: "4"
    ]
]
And then you need to tell the plugin about your datasources:
tenant {
    mode = "singleTenant"
    dataSourceTenantMap {
        t1 = "java:comp/env/jdbc/foo" 
        t2 = "java:comp/env/jdbc/bar" 
    }
}

Catch No. 0 (zero)

Be warned that the tenant 0 (zero) has a special meaning that's not mentioned anywhere in the docs. It means "use the connection returned originally by TransactionAwareDataSourceProxy". This means that tenant with id 0 is off limits for you. Don't ever use it!!!

Summary

Other than the 2 small issues the plugin is really fun to work with. Good job guys!

Monday, July 25, 2011

Grails, Camel and Hibernate session

It's been a while since I thought about manually opening Hibernate sessions to do some work on the database. The usual thing is simply to call one of the GORM methods like get() or save() and have the framework tackle all the bits and pieces regarding low-level Hibernate usage for me.

From time to time however it is important to have a high-level understanding of what's going on behind the scenes. One example of that is saving entities in services utilized as part of Camel routes. But let's start from the beginning...

In Grails opening Hibernate session is handled by a Spring class called OpenSessionInViewFilter. This is a filter that opens a Hibernate session before anything else is happening and closes it after the processing is done. With this filter in place a Hibernate session is available throughout the whole request cycle.

When doing processing in Camel we're in a separate thread completely outside the normal Grails request processing so there's nothing there to open the Hibernate session for us. As a side note one needs to remember that the same happens in pretty much every case where a separate thread is fired to do some processing. In all those cases Hibernate session is not available.

But I still want to use GORM in those places! How can I open a session manually?

Well, that's the easiest thing ever. GORM-managed entities expose a method called withNewSession that takes a closure with one parameter (the newly created session) and life is good again.
To make this more common I'll give you two other examples of such a method: withTransaction and withSession. The first one fires of a new transaction and closes it after the processing is done and the second one is kind of a utility that allows you to access the currently active Hibernate session if you find yourself in need doing so.

I hope this will save someone some time :)

Friday, July 22, 2011

Grails and Spring inc.

I just found a very nice article by Peter Ledbrook showing how you can integrate a regular Spring MVC part of your application with Grails. If you need to do any sort of Spring-related stuff in your Grails application I suggest you check it out!

http://blog.springsource.com/2010/06/08/spring-the-foundation-for-grails/

Have a nice day!

Grails, routing plugin and GORM

I's been brought to my attention today that it is possible that Camel routes start sooner than some of the other services in Grails (GORM in particular). This leads to issues like missing methods in domain classes. To get around this problem you can do as follows:

In your route definition add the .noAutoStartup() part like this:
from('direct:foo').routeId('myRoute').noAutoStartup()....
In BootStrap.groovy's init closure add the following code:
import org.codehaus.groovy.grails.web.context.*
[...]
def ctx = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
ctx.camelContext.startRoute('myRoute')
This will give you the possibility to start and even stop a route anytime you want.

You can read more on this topic on fusesource.com.

I hope this will help someone :)

Tuesday, July 19, 2011

Grails routing 1.1.3 released!

I'm happy to announce the immediate availability of the routing and routing-jms plugins. The major theme for this release is hot reloading of Camel inner-workings when service classes are changed.

So.. well... it works. For the most part at least. It wasn't easy but let's examine the changes and new capabilities one step at a time.

Apache Camel.

In Apache Camel there's no obvious way to force the routes to re-get the bean from Spring context. An endpoint caches an instance of BeanProcessor that's created with ConstantBeanInfo instance and that's pretty much it.
Thankfully the BeanProcessor instance is not final and is lazy initialized so if you force it to be null by calling setProcessor(null) the next time the endpoint is called it needs to re-create the processor and all is good. It's a pity no one thought of a "forceReinitialize" method in Camel but this way works too.

Grails.

In Grails it is pretty much standard that you are allowed to overwrite the existing instance of a service class with a new implementation. This mechanism is sort of baked in into the core.
However when reloading services that are marked as transactional there's some AOP going on with cglib and caching that I couldn't quite crack so those kind of services when reloaded will produce an exception that says "SomeService cannot be cast to SomeService" or something of this sort. I'll have to get back to it some day and figure out if this is a general problem with Grails or if it is something I'm missing in my onChange handler. For now if you need your method to participate in transaction you'll have to manually call the withTransaction { } helper.

Bottom line.

The bottom line is that you finally can use the routing plugin to do normal Grails development and it should catch you with no surprise (other than the transactional services...). Go and give it a shot. Let me know if it works for you!

Happy Cameling!

Grails routing plugin - report from the battlefield

Just wanted to let you all know that I've resumed work on improving the routing plugin for Grails. There's already version 1.1.2 that introduces a new method added to controllers, services and (if Quartz plugin is installed) jobs that allows you to send messages with headers.

The next task however isn't simple and will take some time. It's the long standing problem with Camel routes that target beans that are reloaded.

Will see where this will lead me.

Wednesday, April 27, 2011

Running test on a live test instance of the application

I've faced a unique challenge today: test my json-rest-api plugin. Unique, isn't it? :D

The problem


Well all would be really easy if not for the fact that I wanted to do an end-to-end test just like a client would use the generated API for a domain class. In this case using integration tests was out of the question because the actual http listener is not running. And I wanted to test it all the way through...

After some digging I've found out that there's a number of plugins that provide this kind of functionality where the application starts and tests are being executed. Those plugins are functional-test, easyb-acceptance-test and webtest.

The unhappy seeker


I've tried to play around with those and one thing struck me down the most: they are mostly targeted at testing web pages and not RESTful services. So they were not as nice for my case as I'd like them to be.

What made me wonder though is that all of those plugins do exactly the same thing to actually spawn the application before tests:
eventAllTestsStart = {
if (getBinding().variables.containsKey("functionalTests")) {
functionalTests << "functional"
}
}
Obviously different plugins use different names for their tests but the idea remains the same. So I asked myself what would happen if I'd introduce the same thing in my scripts/_Events.groovy without those plugins installed... Much to my surprise Grails build system started the application right after spitting out "Starting integration test phase ..." :)

The road continues


Now all I had to do was to find out a nice way to actually get the test going. As it turns out there's a fantastic utility called HTTPBuilder that does exactly what I needed! Just a couple of lines in BuildConfig.groovy later...
test('org.codehaus.groovy.modules.http-builder:http-builder:0.5.0') {
excludes "commons-logging", "xml-apis", "groovy"
}
... and testing RESTful services has never been easier!
import groovy.util.GroovyTestCase
import org.junit.Test

import groovyx.net.http.*

class RESTfulTests extends GroovyTestCase {
@Test
void willReturnErrorIfSavingNotSuccessfull() {
def client = new RESTClient("http://localhost:8080/example/api/")
def response = client.post(
path: "person",
body: [ data: [ firstName: 'John', lastName: 'Doe' ] ],
requestContentType : ContentType.JSON.toString())
assert response.status == 200
}
}

If you want to see a more sophisticated usage of this approach with more assertions I encourage you to take a look at the basic application in json-rest-api-examples project.

The obvious


One note to add: if you'd like to run those integration tests as part of your continuous integration it'll most probably fail because the port is already in use by Hudson... To overcome this issue set the server.port parameter to some port value that's not in use. In Hudson it looks more/less like this:



Obviously you need to use this port in your tests instead of the default 8080...

Have fun!

Thursday, April 14, 2011

I still hate JSF - but a little less :D

If you know me you also know this for a fact: I hate JSF with a passion! There are no bad enough words that you could use to express the hatred I feel. What can I say - I'm broken this way...

Today I finally gave JSF2 a spin. This time I already knew that working with Java EE is a pain in the neck so I've decided to use my usual environment (Grails) to do the test.

JSF / JSF2 has some major drawbacks out of the box. It's heavy and it's a misery to introduce changes (again, out of the box). Sure you can use like JRebel and stuff to make your life easier but then JRebel costs money and if you're just playing with the technology with no apparent reason spending any money is just not justified at all.

So back to the topic: JSF2 on Grails. Sounds, scary, right? Yes, I've got the goosebumps too :)

What's in the box? (cited after http://grails.org/plugin/jsf2):

- Bean By convention (no need for faces-config)
- Bean access to controller parameters (session,request,params...)
- Beans dynamic methods for navigation redirect(action?,bean?,view?,uri?,url?) and - render(action?,view?,bean?),
- Automatic bean and service properties resolution
- - 'void init()' called at bean initialization if present
- 'void dispose()' called at bean destruction if present
- JSF Extended request scope ('view')
- Access to web.xml configuration via Jsf2Config.groovy
- Access to faces-config generated in web-app/faces-config.xml
- Converters for Locale, Closure, Currency, Timezone
- i18n ready, fast access with #{m['key']}
- create-bean script
- Hibernate session managed from view rendering to view response
- Execute groovy code in EL expression ( #{gtag.groov[' def i = 2; 3.times{ i++ }; i; ']} )
- Support JSF2 Components - @ManagedBean ...

And so my test went like this. I've installed the plugin the usual way, I've create a class called StatusBean (in a .groovy file!), a little bit of copy-paste from the plugin's page to figure out the signature of an event listener did the heavy lifting for me, I've checked the FAQ section to see where should I put my xhtml files and it all worked right out of the box!

Well, I'd definitely NOT go as far as saying that I actually like JSF2. Hell no! I despise it just as much as I did before. I do however recognize that there's world outside of GSPs and SiteMesh and the alternatives are good for some things.

Friday, April 1, 2011

Grails gotcha - controllers with same name in different packages

Well... it's tough, isn't it? You get a controller with the plugin you use and this damn controller has the same damn name as your controller. And this name is just perfect for what your controller does...

I've just found myself in this kind of situation. I asked on the Grails users group and found out only what I already knew - those damn classes have to have different names. Period.

But I'm the wild one. I need to bend software to my will. I just have to do it :D After a couple of hours of reading Grails sources and experimenting with Grails console (fricken best thing EVER!!!) I came up with this:
class BootStrap {

def grailsApplication

def init = { servletContext ->
grailsApplication.getArtefactInfo("Controller").grailsClasses.each {
it.uri2closureMap.put('/' + it.fullName, 'index')
it.uri2closureMap.put('/' + it.fullName + '/', "index")
it.uri2closureMap.put('/' + it.fullName + '/index', "index")
it.uri2closureMap.put('/' + it.fullName + '/index/**', "index")
it.configureURIsForCurrentState()
}
}

def destroy = {
}
}
With this I can use fully qualified class names in my UrlMappings.groovy!

And as usual life is good again :D

Tuesday, March 29, 2011

Ext JS/Core and formatting date for Grails backend - reloaded

Here's the ultimate solution for modern browsers (works in FireFox and Chrome, there's a fix for IE):
Ext.util.JSON.encodeDate = function(o) { return JSON.stringify(o); }
I feel this needs some explanation :D So here it is:

The JSON object in modern browsers is a serializer/deserializer for JSON format. It uses all the necessary stuff (like the UTC version of date methods and adds the "Z" at the end denoting that this in fact is a Zulu time).

What about Internet Explorer? Well... There's this "fix" for this browser called json2.js. You can download it at https://github.com/douglascrockford/JSON-js/raw/master/json2.js.

The beauty of this solution however lies in the fact that it's an extremely fast solution because the browser's manufacturers are in fact able to provide an optimized version of the stringify and parse methods!

Ext core, Grails and formating dates

In my previous post I've show how to provide the Grails date JSON deserializer with proper date format from Ext JS. This time we're going to look at the same problem but with a solution that also works for Ext-Core:
Ext.util.JSON.encodeDate = function(o) {
function pad(n) {
return n < 10 ? "0" + n : n;
}
return '"' +
o.getUTCFullYear() + '-' +
pad(o.getUTCMonth() + 1) + '-' +
pad(o.getUTCDate()) + 'T' +
pad(o.getUTCHours()) + ':' +
pad(o.getUTCMinutes()) + ':' +
pad(o.getUTCSeconds()) + 'Z"';
}

This function performs much better and uses methods exposed by JavaScript's Date object instead of custom Ext JS date operations. I'd suggest this function instead of the previous one for both Ext-Core and Ext JS.

ExtJS, Grails and dates

Recently I've been made aware of a problem with interoperability between ExtJS and Grails in regards to date serialization. Here's the deal:

1. Grails expects the date to be UTC
2. Grails expects the date to end with a 'Z' (denoting that it actually is UTC)
3. ExtJS by default when parsing date thinks just concatenates the year, month, day, hour, minutes and seconds and does no other processing.

To change this behavior and make it work across different time zones right out of the box simply provide the following implementation of Ext.util.JSON.encodeDate:
Ext.util.JSON.encodeDate = function(d) {
return d
.add(Date.MINUTE, d.getTimezoneOffset())
.format('"Y-m-d\\TG:H:i\\Z"');
};

That's it when it comes to passing dates from client to server. More on serializing date on the server next time!