Thursday, March 22, 2012

TypeSafe Stack 2.0 missing "play debug" like feature

A quick one to help players that are using TypeSafe stack instead of the Play! 2.0 distribution package.
Because I discussed some points on the groups and I saw related StackOverflow entries, that this post might  avoid in the future ^^.


TypeSafe Stack


With its second version, the TypeSafe stack stroke a hit integrating Akka 2.0, Play 2.0 and... its amazing console built on top of both technologies.

With the Scala IDE 2.0 (yeah a lot of 2.0), this stack is ready to tackle the SpringSource Tool Suite, but I don't want to make the comparison here neither explain all of these components... would be long and longer.

But once you've installed the stack and you want to Play! around, they recommend you to use the giter8 template from the typesafehub on github (it also contains a lot of plugins, which you might want).


SBT instead of Play launcher


Using the stack, you won't have the play tool in your hands to generate application and so on, because the way to go is to use g8 and sbt.

This is not an issue but there are some points you'll need to have in mind:

  • the secret is not generated at creation: they're not so far, because the secret is only a random string, and an issue on giter8 is on-going. So, you can create a random string by your own until it will be done. I've also proposed that a new command in sbt might be helpful to regenerate the secret.
  • play debug isn't available: when you need to debug your Play! 2.0 app you need sbt to activate the jdwp when running. For that, there is a MVN_OPTS like SBT_OPTS that comes in your help. Set it with the regular options (-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9999).

HTH

Thursday, March 15, 2012

Gatling-Tool Plugin for Play 2.0

Goal

This post will be a kind of write-up of what I'm trying to do now. And for what I already achieved some tasks.

Since I'll soon start products in my company that will be based on technologies like Scala, Play 2.0, Neo4J, MongoDB, Heroku and misc, and that I'm a bit control freak; I wanted to be sure that what I'll build will mach the requirements in terms of capacity.

This is where Gatling-Tool comes in the equation, this is a very powerful (and scala based) stress testing tool, which the name recall.

We're about to have some words on it, but first let me tell you that a GitHub ready to be fork is available with my first step into a gatling plugin, find it here.

Gatling Tool

Gatling Tool is a cute, smart and intuitive stress testing tool for web application, which a neat DSL for http request and asserts.

The DSL written in scala, and following the good conventions for it will aim anybody to be able to write stress tools. In a way that even non-programmer peoples with a basic understanding will be able to do basic stress tests with a good learning curve.

It's integration with browsers (Firefox, through a proxy) ease much more the work because you'll be able to register like macros (or like badboy does) your scenario to be repeated again and again. This is what is called the recorder.

Scenarios could be written with a custom external DSL, but they're also available as regular scala code (internal DSL) and there is where the coupling with Play 2.0 scala should pay.

Integration with Play2.0

Akka 2.0

Fact: since the RC-5, Play 2.0 comes with the Akka 2.0 support.
Fact: Gatling being it-self based on Akka (and they're right for that) but on a previous version for the stable version (logical because Akka 2.0 is pretty new).

So an integration must go through an update of the Gatling-Tool to the same version of Akka 2.0 in order to be able to use them correctly using the same project (testing phase, but still).

That's why I decided to fork the Gatling-Tool on GitHub (aaah the great world of open source), in order to switch the support of Akka from their 1.x to 2.0.

Even if it is true that I did it roughly (at first), it remains that it works and is the two needed projects for the following are:
  • https://github.com/andypetrella/gatling
  • https://github.com/andypetrella/gatling-highcharts
So fork, clone them and build them locally using maven using the classical mvn clean install.

You'll have a brand new version of gatling 1.1.0-SNAPSHOT.

NOTE: I had some difficult choices when doing the migration, some are breaking the runtime behavior (a bit) and I'll have to discuss them further with the Gatling team. I've already been contacted by St├ęphane Landelle who told me that we was interested by the work since it was planned the 1.2 release.
So don't be afraid, the official release will match the needs soon. (But ping me if you want more info and help me.)

Typesafe Stack 2.0

I recommend you to install this brand new stack that integrates all stuffs that you'll need for scala development, including Play 2.0 project. 
Now, simply follows this link for further steps, and then create a play-scala project.

Sbt

Since Play 2.0 is using Sbt for building its project, and the custom gatling library we built is in our .m2 repo, we have first to add our local maven repo to the repositories list this way (updating your Build.scala):

Tada, now we have a Play 2.0 project having our custom gatling as dependency.

Plugin

Before going in further details with integrating Gatling as a Play 2.0 plugin, I'm gonna talk about an uncovered subject in Play 2.0 (or not easy to track); the Plugin feature.

Play 2.0 comes with a pretty easy simple Plugin integration, this through the specific file, in the conf folder, named play.plugins. This file is meant to contain one single line by defined plugin, shaped this way: {priority}:{plugin's class path}.

But what is a plugin finally, this is a classical class extending play.api.Plugin... simply. This Plugin trait only defines three methods which are:
  • onStart: this adds a hook when the application starts, helpful for initializing objects.
  • onStop: cleaning the fields.
  • enabled: helpful to disable the plugin in some specific cases.
Another point, that I have to highlight is that it seems that such Plugin's constructor must have an argument being the application it-self.

Test only

Hey wait gatling should be available in tests only ?! Right!
The first way to achieve this is the easies also, while implementing isEnabled, you can use the application (remember it is part of the constructor) which has a method isTest that should toggle the plugin.

The second way is to create a Specification that starts a FakeServer (since we'll stress the entire Play 2.0 flows) and give it a FakeApplication which is defined with the Plugins you wish. 1000 words replaced by one Gist:

Gatling integration

Now you're wondering what the heck is that Gatling Plugin class, don't you?
Gatling Plugin
The Gatling plugin class, located in my repo under the test/gatling folder, is extending the play.Plugin class (which defines dummy implementation of the three methods), this way I can concentrate on the only method I need, onStart

Actually I need some initialization in order to use gatling, it needs some folder to be defined, including the one interesting use the more: results.

So, the Gatling#onStart method is creating ephemeres folders under the target directory (that can be cleaned) and also the needed Gatling configuration file. And that's it.

We can now stress test our app.

How?
Gatling is able to understand Scala written scenarios, those Scala script have only one constraint: being an instance of com.excilys.ebi.gatling.core.scenario.configuration.Simulation.

This trait is actually a Function0 and thus defines only one helpful method which is apply(). The latter method is the container for building the stress test that we want to execute.

What is very common now is that you can write Gatling scenarios using the Scala Type System being checked in your favorite IDE, and they will be compiled by Sbt it self when requested (and hot swapped ^^). Where the classical Gatling workflow is to compile them on the fly, using their internal routines.

Run 'em
Having simulations written (example here), you can now ask Gatling to run them by creating a gatling runner instance on them. I won't go into deep details because it is not the purpose here, but here is how you can do.

See 'em in action
That's the easiest part, entering the play environment using sbt in console, you can launch the tests by typing test.

What'll be done is:
  1. enter the specification
  2. create the fake application
  3. load the additional plugin
  4. create the gatling folder and conf
  5. configure the gatling system
  6. create the fake server on 3333
  7. create the simulations
  8. run them
  9. generate reports on them (located in the target folder => look 'em in your browser and you'll see how they're cute)

Problems

There are problems for now when executing several tests, because streams are closed (while generating further reports), that comes from a choice that I've have to do and which is commented on github here. This is mainly related to a feature that is no more available in Akka 2.0 (for good reasons, I'd say).

To be continued

If you want to help me going further, don't hesitate to contact me on my mailbox, or comment this post or on twitter.

What I like to have in the future is :
  • clear Specification for Gatling (preventing the need to define each time the server and plugin)
  • website for enabling test one by one, or any, or...
  • redirecting to results reports
  • more
  • and more

Sunday, March 11, 2012

Play 2.0 and Salat (MongoDB DAO provider)


Play 2.0 using MongoDB document storage through Salat


In this post, I'll cover some points and library that ease such use case.

I won't go into deep details about Play and MongoDB, instead I'll jump straight to the MongoDB usage.

Let's talk a bit about Salat

Salat

This free library available on github here (and deployed on ivy repo, so that easily usable with sbt and Play) is able to deal with case classes and MongoDB as we'd do with JPA.

That say, case classes can be used directly for storing document by simply declaring a DAO and with the help of some annotations (not mandatory).

Grater

Salat as the notion of Grater that is responsible to the de/serialization of a case class. This through two simple functions, let have a Grater for the type T:
  • asDBObject(t:T) : returns a MongoDB representation of t
  • asObject(dbo:DBObject) : returns a T instance based on the provided MongoDB content

The latter thing to note is how to create such Grater? What do we have to do? The answer is almost nothing, in the package com.novus.salat is available the very handy method grater[Y <: AnyRef].

What that grater method does is to parse your case class provided as the method generic, and create the related Grater instance. The important thing to note at this stage is that the latter Grater is cached for further needs.

So now, you're already able to deal with you case class. What is missing is the DAO part, that will ease again your job.

SalatDAO

Salat provides another handy structure named SalatDAO. This trait defines all lifecycle operations that you might need for your domain objects.

Its usage is very simple, you just have to define an object that extends this trait by giving the Domain Specific class and Id type for your structure. The last parameter it needs is a reference to the collection.

Here is an excerpt I pulled from the salat wiki:
object UserDao extends SalatDAO[User, ObjectId](collection = DB.connection("users"))

Play 2.0

Having covered the basic of Salat, it's time to use it in our Play 2.0 application.
There is a cool wiki page, that I wished have discovered before which explain how to use salat with Play 1.2.x. I recommend you to read it, even if I'm gonna cover some of the important steps here too.

Dependencies

This step is more easy that for the previous version of Play. Because now the only two things required are:
  • add the novus repo
  • add the deps to salat
Both in the Build.scala in the project folder of your Play 2.0 app.

**Edit (on 21th June 2012)**
Before you continue, this post that explains some basics about how to deal with Salat and Play, you can now choose to simply move to this module https://github.com/novus/salat/wiki/SalatWithPlay2.
It introduced the tricks that I'll explain below, and add amazing functionalities for Model and DAO creation.
So starting at this point, it's no more mandatory to read this post... unless you're curious ;-)
**end of EDIT**

Context
Here is the main thing I have to discuss here: Salat makes intensive usage of a structure named Context which holds a reference to what have been processed along the classes and structures.

Such instance is created by default in the package object com.novus.salat.global, and the quick start of Salat recommend to import it along with salat and annotations. Don't!

Doing so will fail when using Play 2.0 in DEV mode (only) because of the cool-hot-reload-on-change feature of Play. The specific case where it will fail is the following:
If you want to keep a static reference to the Grater instance of a specific case class.


Why? Because of the (needed for sure!) graters' cache which keeps a reference to the Class instance.
But this class instance might change on bytecode refresh, moreover the fact that Play has a specific ClassLoader for that (ReloadableClassLoader).

The result is incomprehensible errors when you change your code, which errors saying the there is a mismatch between classes that you even not change yet... 

The solution (which is referred in the wiki page I told above)

Instead of importing com.novus.salat.gobal._ which only contains an implicit definition of the Context object to use in Salat core system, create a new one using the correct ClassLoader.


In the above Gist, we can see that we simply created a Context that will refer to the provided ClassLoader by the Play app itself.

That will keep enabled the class reloading, without impacting caches instances.

That's all folks!

Now you're ready to use both Play 2.0 and Salat without messing around with conversion between DSM and MongoDB and so on.
Have a gode work.