Tag Archives: open source

Functional tests in Play! 2 with REST-assured

In the Play! documentation, several flavours of functional testing are mentioned, including starting a HTTP server for the duration of the test – this is very useful for testing web services. In code, this looks like

import static play.test.Helpers.*;
...
@Test
public void testInServer() {
  running(testServer(3333), new Callback0() {
      public void invoke() {
         assertThat(
           WS.url("http://localhost:3333").get().get().status
         ).isEqualTo(OK);
      }
  });
}

A few days ago, when I was looking for a good way to test applications built on a CXF stack, I came across REST-assured. It was simple, elegant and useful so it’s the one I picked. In that case, I had to build some extra support for handling Jetty start-up and shutdown, application loading, etc.

With the full-stack approach of Play, however, you get this support for free out of the box, so all that is left is to integrate the tool of your choice. To add REST-assured to your project, edit the project/Build.scala file and add the dependency. If you already have Play running, don’t forget to reload the project for the changes to be visible.

val appDependencies = Seq(
    "com.jayway.restassured" % "rest-assured" % "1.7" % "test"
)

The above example re-written to use REST-assured then looks like this:

import static play.test.Helpers.*;
import com.jayway.restassured.RestAssured;
...
@Test
public void testInServer() {
  running(testServer(3333), new Runnable() {
      public void run() {
         RestAssured.expect().statusCode(200).when().get("http://localhost:3333");
      }
  });
}

REST-assured defaults to localhost for requests, so it’s possible to cut down on the boilerplate and use relative URLs by tweaking the configuration a little.

import static play.test.Helpers.*;
import com.jayway.restassured.RestAssured;
...
private static final int PORT = 3333;

@Before
public void setUp()
{
    RestAssured.port = PORT;
}
...
@Test
public void testInServer() {
  running(testServer(PORT), new Runnable() {
      public void run() {
         RestAssured.expect().statusCode(200).when().get("/");
      }
  });
}

I’ve written a small example that’s available on github, and here’s a sample from it which features an entity being persisted, and then retrieved for testing.

@Test
public void testGetBeer_present()
{
    running(testServer(PORT), new Runnable()
    {
        @Override
        public void run()
        {
            // Create the beer
            RestAssured.given()
                       .contentType(ContentType.JSON)
                       .content("{\"name\":\"Westmalle\"}")
                       .expect()
                       .statusCode(200)
                       .when()
                       .post("/");

            // Retrieve it by name, and bind the response body into a Beer instance
            Beer beer = RestAssured.expect()
                                   .statusCode(200)
                                   .when()
                                   .get("/Westmalle")
                                   .andReturn()
                                   .body()
                                   .as(Beer.class);
            Assert.assertEquals("Westmalle",
                                beer.name);
        }
    });
}

To run the tests, just start up Play in on your command line, and use the test command:

[play-rest-assured] $ test
[info] controllers.BeersTest
[info] + controllers.BeersTest.testGetAll_emptyDatabase
[info] + controllers.BeersTest.testGetAll_populatedDatabase
[info] + controllers.BeersTest.testGetBeer_emptyDatabase
[info] + controllers.BeersTest.testGetBeer_present
[info] + controllers.BeersTest.testUpdate
[info] 
[info] 
[info] Total for test controllers.BeersTest
[info] Finished in 6.954 seconds
[info] 5 tests, 0 failures, 0 errors
[info] Passed: : Total 5, Failed 0, Errors 0, Passed 5, Skipped 0
[success] Total time: 7 s, completed Oct 29, 2012 7:37:52 AM

Resources

Controlling distributed presentations

In a previous post, I talked about how a projector failure at the 010DEV event resulted in the presentation using laptops, smartphones and tablets to display the slides. One of the problems here, as noted by speaker Trisha Gee, is that on every device the next slide must be manually selected.

A couple of weeks ago, I came up with the idea of FilthyHackFriday – the idea being that you take a problem, and code up a quick’n’dirty solution in 30 minutes as a proof of concept. For my first FHF project, I chose to address this problem and wrote DistPres. It lets you upload Powerpoint or PDF presentations and converts each slide to an image. When you view a presentation, AJAX polling checks for changes to the current slide index and updates the view accordingly. You can control the presentation using the left and right arrow keys, and reset it to the first slide using the R key.

The use-case for this as follows. You’re in an upstairs room in a bar, trying to give a presentation but the projector doesn’t want to join in. So, you fire up DistPres and upload your presentation. Everyone points their device to your web server, and selects the correct presentation. From that point on, every time you change a slide everyone else will get the new slide automatically within a second.

Here’s an example using a presentation I downloaded from Slideshare. Three browsers – Chrome, Firefox and an Android emulator – are viewing the same presentation. When I use the left/right arrow keys (or, technically, just the right arrow key in this video), the current slide is updated in each browser within a second.

DistPres example using Chome, Firefow and an Android emulator from Steve Chaloner on Vimeo.

Notes:
- It’s quick and dirty, but it works.
- With some cleaning up it could actually be pretty handy.
- It’s written using Play 2
- Originally I wrote it using WebSockets, but that automatically excludes certain browers and devices. AJAX polling opens the field a bit more.

You can find the code on GitHub here, or download it directly from here.

The Play Framework is now officially an embarrassment

If you’ve read any other entries on this blog, you’ll know that I’m an advocate of the Play! Framework.

As of today, this has changed.

My client is currently in the process of migrating their services to a federated collection of web services. Business metrics are required, and so we needed to look at a logging service. We discussed various options, and my proposal was accepted. We have a few well-defined fields, and service-specific data is logged as a JSON document. The discussion lasted about 25 minutes or so.

I went back to my desk, and wrote the code – a RESTful service, an asynchronous client using Akka, and a front-end in 15 minutes – using Play 2.

Let me spell that out, in case you missed the figures. Implementing the entire solution took 3/5s the length of time of the meeting.

Can you imagine doing that with another web framework, especially in the Java space? Play is, by definition at this point, an embarrassment – it can, should and will make other frameworks embarrassed of what they can offer.

I’m no longer an advocate of the Play! Framework. I’m an unequivocal advocate of it.

Edit: I’ve changed ashamed to embarrassed – ashamed was the wrong word to use, and gave negative connotations.

jQuery AJAX with Play 2

I’ve just prepared a course on jQuery to give to my colleagues, and one of the sections covers jQuery’s AJAX features. To demonstrate these, I wrote a quick web app using Play 2. Since there have been a few questions asked in various places on how this works, I’m going to break it down here with some simple examples of the main $.ajax() method, plus the shorthand methods that simplify its use.

$.ajax()

jQuery’s $.ajax() method is part of the low-level interface, and can be configured to provide all your AJAX needs. For this example, we’re going to do a simple GET that will result in a 200 response from the server, along with a text message.

The JavaScript:

$.ajax(ajaxParameters({
      url: '/ajax',
      success: function(data, textStatus, jqXHR) {
        window.alert(data);
      },
      error: function(jqXHR, textStatus, errorThrown) {
        window.alert(textStatus);
      }
    }));

Note the URL – this results in a call to http://localhost:9000/ajax, and so must appear in the routes file:

GET     /ajax                       controllers.Application.ajax()

The server-side implementation is about as simple as it gets:

public static Result ajax()
{
    return ok("Here's my server-side data");
}

Responding to errors

Take a look at the JavaScript again – you will see there are handlers declared for success and error conditions. What’s the difference? A 200 response will trigger the success handler, and other codes trigger the error handler. Let’s tweak the code to show this working.

The JavaScript. The only thing that has changed here is the URL – it now points to a URL that is guaranteed to return a non-200 response.

$.ajax(ajaxParameters({
      url: '/ajaxWithError',
      success: function(data, textStatus, jqXHR) {
        window.alert(data);
      },
      error: function(jqXHR, textStatus, errorThrown) {
        window.alert(textStatus);
      }
    }));

The route:

GET     /ajaxWithError              controllers.Application.ajaxWithError()

And the server-side implementation:

public static Result ajaxWithError()
{
    return badRequest("Somehow, somewhere, you screwed up");
}

And that’s it – you’re now handling success and error conditions.

Shorthand methods

jQuery usefully provides shorthand methods that simplify usage of $.ajax(), and in some cases provide additional functionality such as parsing repsonse data into JSON objects, or loading content into elements.

$.get()

$.get() is, unsurprisingly, for issuing asynchronous GETs to the server. You can provide parameters, and give a single function that will be executed if the call is successful.

The JavaScript:

$.get('/get',
      {'foo': 'bar'},
      function(data) {
          window.alert(data);
      });

The route – note this doesn’t specify a method parameter!

GET     /get                        controllers.Application.get()

The server-side implementation:

public static Result get()
{
    Map queryParameters = request().queryString();
    return ok(String.format("Here's my server-side data using $.get(), and you sent me [%s]",
                            queryParameters.get("foo")[0]));
}

Handling errors

In the real world, you will receive errors sometimes and the above JavaScript doesn’t handle this. The key is to use jQuery’s event-handling features instead of providing callbacks. In this example, any success, error and completion events fired by $.get() are handled.

$.get('/getWithError')
      .success(function(data) {
        window.alert('Success: ' + data);
      })
      .error(function(data) {
        window.alert('Error: ' + data.responseText);
      })
      .complete(function(data) {
        window.alert('The call is now complete');
      });

The route:

GET     /getWithError               controllers.Application.getWithError()

The server-side implementation:

public static Result getWithError()
{
    return badRequest("Something went very, very wrong");
}

$.post()

So far, so good, but what if you want to POST data to the server? You can use $.post() for this. Interestingly, there are no shorthand methods for DELETE, PUT, etc – you have to use the $.ajax() method for these.

The semantics are the same as for $.get(), so I’m not going to provide an event-driven here. This is using a regular callback.

The JavaScript:

$.post('/post',
      {'foo':'bar'},
      function(data) {
          window.alert(data);
      });

The route – note the POST HTTP method is used.

POST    /post                       controllers.Application.post()

And the server-side code:

public static Result post()
{
    Map parameters = request().body().asFormUrlEncoded();
    String message = parameters.get("foo")[0];

    return ok(message);
}

$.getJSON()

$.getJSON() loads JSON-encoded data from the server using a GET HTTP request (to steal a line from the jQuery docs). This means the data returned can be treated immediately as a JSON object without the need to process it further.

The JavaScript:

$.getJSON('/getJson',
          function(data) {
              // data is a JSON list, so we can iterate over it
              $.each(data, function(key, val) {
                  window.alert(key + ':' + val);
          });
       });

The route:

GET     /getJson                    controllers.Application.getJson()

Server-side code:

public static Result getJson()
{
    List data = Arrays.asList("foo", "bar");
    return ok(Json.toJson(data));
}

$.getScript()

$.getScript() loads a script from the server using a HTTP GET, and then executes it in the global context.

The JavaScript:

$.getScript('/getScript');

The route:

GET     /getScript                  controllers.Application.getScript()

Server-side code:

public static Result getScript()
{
    return ok("window.alert('hello');");
}

Handling events

This example couldn’t be simpler. It could, however, be slightly more complex. The events generated by $.getScript() are slightly different to the success, error, etc events of the other methods. For $.getScript(), there are done and fail events. For success, you have to use a callback.

$.getScript('/getScriptWithError',
            function() {
                window.alert('This is the success callback');
            })
            .done(function(script, textStatus) {
                window.alert('Done: ' + textStatus);
            })
            .fail(function(jqxhr, settings, exception) {
                window.alert('Fail: ' + exception);
            });

The route:

GET     /getScriptWithError         controllers.Application.getScriptWithError()

The server-side implementation. Note it’s returning a 200 response but with broken JavaScript.

public static Result getScriptWithError()
{
    return ok("this is not a valid script!");
}

.load

Last but not least is .load(). Note this isn’t $.load(), but rather $(a selector).load() as its purpose is to retrieve HTML from the server and place it into the matched element.

The JavaScript:

$('#loadContainer').load('/load');

The route:

GET     /load                       controllers.Application.load()

The server-side implementation:

public static Result load()
{
    return ok(snippet.render());
}

The template:

<div id="aTable">
    <table>
        <tr>
            <td>Foo</td>
            <td>Bar</td>
        </tr>
        <tr>
            <td>Hurdy</td>
            <td>Gurdy</td>
        </tr>
    </table>
</div>
<div id="aList">
    <ul>
        <li>Foo</li>
        <li>Bar</li>
    </ul>
</div>

Loading fragments

.load() can take a second parameter within the URL string, separated by a space. This parameter is a selector – if present, jQuery will extract the selected element from the HTML and insert only that into the target.

$('#loadFragmentContainer').load('/load #aList');

Note there is no change to the route, the server-side code or the template here – this is purely a client-side operation.

That’s all, folks

jQuery simplifies making AJAX calls, and Play simplifies receiving and responding to those calls. A perfect match!

An example implemtation of all these features is available here: jquery-ajax

Publishing Play 2 modules on github

Now you’ve doubtless followed my earlier guides on writing modules for Play 2, I imagine you’re keen to show your coding chops to the world. The problem is – and this is quite a big one, I’m afraid – there is no place to publish your modules to. When I first starting writing Play modules, the repository was already set-up and ready to go – however, it used a custom format (state of the art download-and-unzip). This changed to some degree with Play 1.2, but I have to say I’m not a fan of that dependency management mechanism; I’m just too damn old to learn these shiny new things.

With Play 2, things swung around again and the dependency mechanism is compliant with Maven and Ivy. I can hear enterprises up and down the planet rejoicing.

However, this still doesn’t help you achieve your well-deserved glory and fame, unless you happen to host your own Maven/Ivy repo or feel like hacking the auto-generated artifact models that Play generates. Help is hand, until Play 2 modules have an official release mechanism, using GitHub’s Pages feature. Very simply, we’ll use Play’s publish-local task to generate all the files we need in the correct directory structure, and then copy that structure as-is directly into GitHub pages. A publish in this manner can be done in less than a minute, after you’ve done the initial set-up in GitHub.

Creating the repository in GitHub

If your GitHub user name is, for example, foo, then creating a repository called foo.github.com hooks you into Pages – what you commit here will be available at http://foo.github.com. There’s no GitHubby goodness when it comes to displaying files here – what you commit is what’s available in its native form. Commit a HTML file (let’s call it bar.html), and point your browser at http://foo.github.com/bar.html and you’ll see the rendered HTML – not the source of it. This makes it ideal for exposing files that you want represented in their raw form – say, the jar file containing your Play 2 module.

So, go ahead and create a .github.com repository and clone it to your workspace, and cd into it. In here, you can replicate (kind of – see later) a meven repository.

To keep things nice, the first directory you should create is releases. If you also want to add a snapshot directory, do it at this level.

Note: When you first create the repository in GitHub, it can take up to 10 minutes for it to become available. If you haven’t changed your email preferences, you should receive a notification when it is ready. This doesn’t stop you committing to the repository in the meantime.

Publish the files locally

Let’s assume your module name is hurdy as the artifact name. Your Build.scala looks like this:

import sbt._
import Keys._
import PlayProject._

object ApplicationBuild extends Build {

    val appName         = "hurdy"
    val appVersion      = "1.0"

    val appDependencies = Seq(
    )

    val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
    )
}

(The mainLang value may be something else, depending on your primary language).

In the root of your module, start up Play and publish it locally:

steve@hex:/tmp/hurdy$ play
[info] Loading project definition from /tmp/hurdy/project
[info] Set current project to hurdy (in build file:/tmp/hurdy/)
       _            _ 
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/ 
             
play! 2.0, http://www.playframework.org

> Type "help play" or "license" for more information.
> Type "exit" or use Ctrl+D to leave this console.

[hurdy] $ clean
[success] Total time: 0 s, completed Apr 21, 2012 9:49:00 AM
[hurdy] $ compile
[info] Updating {file:/tmp/hurdy/}hurdy...
[info] Done updating.                                                                  
[info] Compiling 4 Scala sources and 2 Java sources to /tmp/hurdy/target/scala-2.9.1/classes...
[success] Total time: 7 s, completed Apr 21, 2012 9:49:08 AM
[hurdy] $ publish-local
[info] Packaging /tmp/hurdy/target/scala-2.9.1/hurdy_2.9.1-1.0-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Wrote /tmp/hurdy/target/scala-2.9.1/hurdy_2.9.1-1.0-SNAPSHOT.pom
[info] :: delivering :: hurdy#hurdy_2.9.1;1.0-SNAPSHOT :: 1.0-SNAPSHOT :: release :: Sat Apr 21 09:49:12 CEST 2012
[info] 	delivering ivy file to /tmp/hurdy/target/scala-2.9.1/ivy-1.0-SNAPSHOT.xml
[info] Generating API documentation for main sources...
[info] Packaging /tmp/hurdy/target/scala-2.9.1/hurdy_2.9.1-1.0-SNAPSHOT.jar ...
[info] Done packaging.
model contains 23 documentable templates
[info] API documentation generation successful.
[info] Packaging /tmp/hurdy/target/scala-2.9.1/hurdy_2.9.1-1.0-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] 	published hurdy_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/hurdy/hurdy_2.9.1/1.0-SNAPSHOT/poms/hurdy_2.9.1.pom
[info] 	published hurdy_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/hurdy/hurdy_2.9.1/1.0-SNAPSHOT/jars/hurdy_2.9.1.jar
[info] 	published hurdy_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/hurdy/hurdy_2.9.1/1.0-SNAPSHOT/srcs/hurdy_2.9.1-sources.jar
[info] 	published hurdy_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/hurdy/hurdy_2.9.1/1.0-SNAPSHOT/docs/hurdy_2.9.1-javadoc.jar
[info] 	published ivy to /home/steve/development/play/play-2.0/framework/../repository/local/hurdy/hurdy_2.9.1/1.0-SNAPSHOT/ivys/ivy.xml
[success] Total time: 3 s, completed Apr 21, 2012 9:49:15 AM

Move the published files into GitHub

The files have been published to ${PLAY_HOME}/repository/local, and are contained in the hurdy directory. Move this entire directory to your new git repository

cp -rv ${PLAY_HOME}/repository/local/hurdy <your username>.github.com/releases

Change directory to .github.com, and add all the files to the git repository, commit and push them.

steve@hex:/tmp/schaloner.github.com$ git add .
steve@hex:/tmp/schaloner.github.com$ git commit -m "Added release 1.0 to repository"
steve@hex:/tmp/schaloner.github.com$ git push -u origin master

Use the dependency

Create a new project (or open up an old one), and add the dependency and its location.

object ApplicationBuild extends Build {

    val appName         = "my-cool-project"
    val appVersion      = "2.1"

    val appDependencies = Seq(
      "hurdy" %% "hurdy" % "1.0"
    )

    val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
      resolvers += Resolver.url("My GitHub Play Repository", url("http://<your username>.github.com/releases/"))(Resolver.ivyStylePatterns)
    )
}

Note: Play has published the files in an Ivy style pattern, so this needs to be specified in your Build.scala

Start Play in your application root, and run the “dependencies” task. If all goes well – and I’m sure you’ll let me know if it doesn’t – your module will be pulled from GitHub and made available to your application.

Specifiying an organisation

Because there’s no organisation specified in Build.scala, the organisation (repository/local/hurdy/hurdy_2.9.1) is taken to be the same as the module name. If you want an organisation, add it in the main definition:

val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
      organization := "com.example"
    )

Now, when you publish locally the files will be placed in repository/local/com.example/hurdy_2.9.1. In this case, it’s the com.example directory that should copied from the local repository to your GitHub repo. The Build.scala of any application using your dependency will be similarly different:

val appDependencies = Seq(
      "com.example" %% "hurdy" % "1.0"
    )

Real-world proof this works

Deadbolt 2 is currently available using this mechanism, using http://schaloner.github.com as the repository. Here, there are release and snapshot versions so the Build scala of the sample applications looks like this:

import sbt._
import Keys._
import PlayProject._

object ApplicationBuild extends Build {

    val appName         = "deadbolt-usage"
    val appVersion      = "1.1.3-SNAPSHOT"

    val appDependencies = Seq(
      "be.objectify" %% "deadbolt-2" % "1.1.3-SNAPSHOT"
    )

    val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
      // Change this to point to your local play repository
      resolvers += Resolver.url("Objectify Play Repository", url("http://schaloner.github.com/releases/"))(Resolver.ivyStylePatterns),
      resolvers += Resolver.url("Objectify Play Repository", url("http://schaloner.github.com/snapshots/"))(Resolver.ivyStylePatterns)
    )
}

If I change the required version from 1.1.3-SNAPSHOT (which is in the snapshots/ directory) to 1.1.3 (which will be in the releases/ directory), the dependency will be resolved correctly.

The all-new Play Module Repository

Back in November, I spoke to Nicolas Leroux of the Play framework about creating a module repository. He agreed it would be a good idea, but lack of time has prevented me from starting this. Following the stormy events of last week in the Play Google Group, I’ve decided to prioritise it. A working prototype should be available in a couple of weeks.

The overview:
1. It’s open source
Obviously

2. It’s written in Play 2
Just to piss off the nay-sayers :)

3. Module creation
At the moment, to get a module into the module repository you have to get authorisation from a member of the Play team. I want to have a repo where you can upload any module, as long as it conforms to certain minimum requirements. These are
* a README file
* a license (preferably, but not constrained to, a business-friendly one)
* actual code, to prevent a bunch of empty modules being created

4. Open accounts
Users can create accounts by logging in via twitter, facebook, etc, and link multiple sign-in methods to their accounts.

5. Security
Authentication will come via SecureSocial (so Jorge Aliss needs to start coding!) and authorisation will be implemented in Deadbolt 2. As a result, this will supercede the SociallySecure example app which showed how to integrate the two.

6. Modules are web-accessible
Modules can be downloaded directly through the browser

7. Modules are framework-accessible
Regardless of the version of Play, and therefore regardless of the dependency mechansim, the repository will serve modules directly to the framework. In other words, when you add modules to dependencies.yml or Build.scala, those modules will be fetched by the framework. Manual installation is not required.

8. Voting
Any logged-in user can vote up a module. One vote per module, to keep things fair.

9. Commenting
Any logged-in user can comment. Because of the open sign-in method, I think it doesn’t make sense to have anonymous comments. Trolls can go elsewhere.

10. Play 1 modules
Play 1 modules will be hosted directly in the repo.

11. Play 2 modules
Play 2 modules can also be hosted in the repo, but since they can also be hosted in any Maven or Ivy repo it’s possible to link to the remote repo instead. This doesn’t impact point #7 since it will be transparent to the framework itself.

12. No ambiguity
One very important point comes from Ben Verbeken – “We’ll just have to make sure it’s really obvious to the visitor that they are browsing either the play 1 or play 2 modules (no hidden filter feature, but a big red switch at the top e.g. ;))”

The github repository (which is currently empty, because it was created nine minutes ago) can be found at https://github.com/playframework/modules.playframework.org

At the moment, we’re purely at the planning stage but I plan to use my favourite development style (evolutionary prototying) to get something up and working fast. The github repo will be created tonight, and regular updates will be posted here.

Peter Hilton has posted some more details over at the Play Google Group.

Writing modules for Play 2, part 1: Get something working

A couple of weeks ago, I migrated the Play! framework 1.x version of Deadbolt to the Play 2 platform, and was surprised at the lack of information on creating modules. This topic was covered in detail in the Play 1.x docs, and this made creating modules very simple. Clearly, something needed to be done – and so this is the first in a three-part series on creating modules and plugins for Play 2.

It’s important to note this is not a definitive guide – instead, it’s a collection of the information and techniques I’ve used when working on my own modules.

I’m going to assume you already have a working installation of Play 2 – if you don’t, head over to http://www.playframework.org/documentation/2.0/Installing for details on how to set this up.

In this first part, we’re going to cover the fundamentals of creating and publishing the module, and adding a sample application. The next two parts will go into greater depth on plugins, interceptors, tags and other useful tools.

First, a small note on the difference between a module and a library. In Play 1.x, a module was created using “play new-module” and distributed via the module repository. Up until Play 1.1, modules were controlled through application.conf entries, and libraries were added locally. From Play 1.2, both modules and libraries were controlled through the dependency management mechanism based on Ivy. In both cases, though, there was a clear concept of module (something tightly integrated with Play, which followed its conventions on package structure, etc) and a library (a general third-party library).

In Play 2, the line is blurred to some degree. Modules are now distributed in the same way as libraries, though Ivy or Maven, and the package structure can be arbitrary so you can have a traditional com.example.whatever structure. From this point of view, the only real difference between modules and libraries is that modules use the Play API directly.

Secondly, a note on language. Since both Java and Scala are natively supported by Play 2, you can implement your module in either language. If the module has its own API that applications can use, the superb interoperability between Java and Scala means your language choice is – in most cases – irrelevant to whichever application uses your API.

1. Getting started

As a simple introduction, we’re going to create a basic logging module that – following industry best practices – writes output to the console window. This module is called mylogger, because it’s Monday and I’m not feeling very creative right now. This module is going to be (mainly) written in Java.

You can think of a Play 2 module as being a Play 2 application with a couple of files missing. So, you create a module in the same way as you would an application. Go to, or create, a directory where you keep your projects, and use “play new mylogger” to create the app. Choose option 2 when prompted, to create a simple Java app.

steve@hex:/tmp$ play new mylogger
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/

play! 2.0, http://www.playframework.org

The new application will be created in /tmp/mylogger

What is the application name?
> mylogger

Which template do you want to use for this new application?

  1 - Create a simple Scala application
  2 - Create a simple Java application
  3 - Create an empty project

> 2

OK, application mylogger is created.

Have fun!

Because we’re going to have a sample application alongside the module, we’re going to change the directory structure a little. At the moment, it looks like this:

mylogger
– app
– conf
– project
– public
– target
– .gitignore
– README

In the mylogger directory, create two new directories, project-code and samples. Copy all the files listed above into the project-code directory. You should now have

mylogger
– samples
– project-code
     – app
     – conf
     – project
     – public
     – target
     – .gitignore
     – README

The conf directory contains two files – routes, and application.conf.

- application.conf needs to be present for Play to recognise mylogger/project-code as a Play application, so we can’t delete it but we can remove everything it contains. Any configuration your module needs should be added to the application.conf of the “real” application.
- routes *must* be deleted. If you don’t do this, it may/will supercede the routes file of whichever application uses it, and this is A Bad Thing (mainly because nothing will work).

With application.conf emptied and routes deleted, type “play” in the project-code to start the Play console.

steve@hex:/tmp/mylogger/project-code$ play
[info] Loading project definition from /tmp/mylogger/project-code/project
[info] Set current project to mylogger (in build file://tmp/mylogger/project-code/)
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/

play! 2.0, http://www.playframework.org

> Type "help play" or "license" for more information.
> Type "exit" or use Ctrl+D to leave this console.

[mylogger] $

We now have a valid Play 2 module (that, admittedly, doesn’t do anything).

If you use an IDE, this is a good time to create the project – this tutorial is IDE-agnostic, however, so you can use the guide at http://www.playframework.org/documentation/2.0/IDE if you want to do this.

2. Adding some functionality

As I mentioned above, Play 2 modules can have a more traditional package structure of com.example.whatever, but a default Play application has the tradtional app/controllers, app/models, etc, structure. We’ll keep this for now, and change it in later parts of this tutorial.

2.1 Slash and burn

In the app folder, we have the following structure as created for us by the “play new” command:

app
– controllers
     – Application.java
– views
     – index.scala.html
     – main.scala.html

For the initial iteration of this module, we don’t need any views so you can delete the views package.

You can also delete Application.java, as we’re writing this from scratch.

2.2 Add some module code

In the controllers package, create a new class called MyLogger.java. It doesn’t need to extend or implement anything, and it contains a single method:

package controllers;

/**
 * @author Steve Chaloner
 */
public class MyLogger
{
    public static void log(String message)
    {
        System.out.println("MyLogger: " + message);
    }
}

2.3 Have a beer

You’ve just written a module. Go have a beer.

2.4 Post-beer realisation

As you gaze into your now-empty glass, abuzz with the joy of creation and impending feeling of industry-wide fame, you might realize that no-one can actually get to your module because it’s sitting on your computer. You need to publish it.

3. Publish and be damned

For this example, we’re just going to publish to your local repository. In the root of your Play installation, there is a repository directory, and this is where you wil first push your module.

Before publishing, always ensure you have run a “clean”, otherwise some classes/files that you have removed from the source tree may still exist in compiled form and end up in your module jar file. If the class matches one that’s in your actual application, it can be called in place of your actual class. Which sucks.

In the Play console, use “clean” and then “publish-local” to package up your module and publish it to the local repo:

[mylogger] $ publish-local
[info] Updating {file:/tmp/mylogger/project-code/}mylogger...
[info] Packaging /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1-1.0-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Wrote /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1-1.0-SNAPSHOT.pom
[info] Done updating.                                                                  
[info] :: delivering :: mylogger#mylogger_2.9.1;1.0-SNAPSHOT :: 1.0-SNAPSHOT :: release :: Mon Mar 19 20:57:26 CET 2012
[info] 	delivering ivy file to /tmp/mylogger/project-code/target/scala-2.9.1/ivy-1.0-SNAPSHOT.xml
[info] Compiling 1 Java source to /tmp/mylogger/project-code/target/scala-2.9.1/classes...
[info] Generating API documentation for main sources...
model contains 4 documentable templates
[info] Packaging /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1-1.0-SNAPSHOT.jar ...
[info] Done packaging.
[info] API documentation generation successful.
[info] Packaging /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1-1.0-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] 	published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/mylogger/mylogger_2.9.1/1.0-SNAPSHOT/poms/mylogger_2.9.1.pom
[info] 	published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/mylogger/mylogger_2.9.1/1.0-SNAPSHOT/jars/mylogger_2.9.1.jar
[info] 	published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/mylogger/mylogger_2.9.1/1.0-SNAPSHOT/srcs/mylogger_2.9.1-sources.jar
[info] 	published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework/../repository/local/mylogger/mylogger_2.9.1/1.0-SNAPSHOT/docs/mylogger_2.9.1-javadoc.jar
[info] 	published ivy to /home/steve/development/play/play-2.0/framework/../repository/local/mylogger/mylogger_2.9.1/1.0-SNAPSHOT/ivys/ivy.xml
[success] Total time: 4 s, completed Mar 19, 2012 8:57:28 PM

If you take a look in $PLAY_HOME/repository/local, you’ll now see a directory called mylogger. Since we didn’t give an organisation name, the organisation is taken to be the same name as the module itself. Go into mylogger, and you’ll see the artifact – mylogger_2.9.1. The 2.9.1 part of the filename comes from Play itself, and is (appears to be) a versioning thing. If anyone knows more about this, please comment and let me know.

Inside mylogger_2.9.1, we have the module version, which in this case is 1.0-SNAPSHOT, and this in turn contains jar files, source jars, Maven and Iyy info, etc.

Where does all this information come from? It’s based on the project/Build.scala file. In here, you can give the name of the module, the organisation, the version, and various other pieces of information. For now, we’ll keep things as they are, but this extremely important file will be updated as we get deeper into some issues.

4. Providing a sample

You can write the best, most incredibly useful module in the world, but without a sample application to a) show it works, and b) show HOW it works, you’re going to have trouble convincing people of that. This is why we changed the directory structure back when we first created the module. Open another terminal, and go to the mylogger/samples diretory – it’s time to show what mylogger can do.

4.1 A sample application is…a Play application

Since we’re writing a Play module, it makes sense to provide a Play application as the sample. Now we’re in mylogger/samples, using “play new mylogger-sample” to create the sample application. Again, choose option 2 to make a simple Java application.

4.2 Declaring dependencies

In order to use mylogger, we must declare a dependency for it in mylogger-sample/project/Build.scala. Open this file, and change

val appDependencies = Seq(
      // Add your project dependencies here,
    )

to

val appDependencies = Seq(
      "mylogger" % "mylogger_2.9.1" % "1.0-SNAPSHOT"
    )

You can see this matches the repository path of mylogger/mylogger_2.9.1/1.0-SNAPSHOT.

In a brazen act of laziness, we’re also going to declare the local repository as the place to find our module. Change

val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
      // Add your own project settings here      
    )

to

  val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
    resolvers += "Local Play Repository" at "file://path/to/play-2.0/repository/local"
  )

(but change the path to be correct for your local installation)

In the mylogger/samples/mylogger-sample directory, start up the Play console using “play”. If you use the “dependencies” command, you’ll see that mylogger is now a dependency of the application.

IMPORTANT NOTE! Since we started the Play console after changing Build.scala, the changes were automatically picked up. If you change this file while the console is open, use “reload” to make sure the changes are used.

4.2 Using your module

In your new default Play application, we’re going to add a single line to controllers/Application.java to call MyLogger:

package controllers;

import play.mvc.Controller;
import play.mvc.Result;
import views.html.index;

public class Application extends Controller
{
    public static Result index()
    {
        MyLogger.log("Here's my log message");
        return ok(index.render("Your new application is ready."));
    }
}

Note that we don’t need to import MyLogger as it’s also in the controllers package.

“run” the application and go to http://localhost:9000. A brief time later, the page will render and in the console you’ll see

[info] play - Application started (Dev)
MyLogger: Here's my log message

Reload the page a few times, and you’ll see the log message appear every time.

5. Have another beer

Congratulations, you now have a module and a working sample. It doesn’t actually add much value to your sample app, but that’s something that will be addressed in part 2. In the meantime, head over the fridge and grab yourself another beer.

You can download the complete source code for this example here

Other parts to this tutorial series

Play 2, Akka, Websockets, Backbone.js and Leaflet – just having fun, really

A few weeks ago, I started playing around with Backbone.js. At the end of last week, I noticed something on Twitter about Leaflet. I’ve been a long-time devotee of the Play! framework, as you may be aware if you’ve ever read this blog before.

Play 2 was released yesterday. This seems like a perfect time to mix them all together, just for fun*

I originally looked at combining Backbone and Leaflet to create markers on a map, which was a fun and easy 20 minutes – it was pure client-side code, simple to do and unbelievably pointless. Unless the map markers could be shared across multiple users, it was ultimately useless. That’s when I decided to hijack and re-purpose Play 2′s websocket-chatroom sample application- I thought it would be nice to have the places you mark on your map pop up in real-time on the map that other people are looking at, and the chatroom code required minimal tweaking to do this.

At this point, I should apologise. I just got back from the gym, and I’m too tired to think coherently enough to write good blog prose. Luckily, we’re about to head into the technical details

On start-up, mapcrap acts like a tradional MVC app – it gets the existing map places from the database via a RESTful call, and displays them on the map. From this point on, everything is then driven by websocket interactions. When you create a place, instead of it being persisted via REST, the JSON of the place is sent over the websocket. The server-side app then persists the place and broadcasts it to every user’s websocket using Akka.

in.onMessage(new F.Callback()
{
    public void invoke(JsonNode event)
    {
        Place place = Json.fromJson(event,
                                    Place.class);
        place.createdOn = new Date();
        place.save();
        defaultMap.tell(new MapEvent(userId,
                                     place));
    }
});

The locally-added place isn’t added to the local collection of places directly – instead, it receives it through the broadcast. This is a lazy way of getting around Backbone collections not accepting duplicate models.

When the client receives a push message informing it that a new place has been added, it adds the place to the Backbone collection of places – in turn, the event listener on the collection triggers the addition of a popup to the map.

this.model.bind("add", function(place){
  var view =new PopupContentView({model:place});
  var latlng = new L.LatLng(place.get('latitude'), place.get('longitude'));
  var messagePopup = new L.Popup({autoPan:false, closeButton:false});
  messagePopup.setLatLng(latlng);
  messagePopup.setContent(view.render().el);
  self.options["map"].addLayer(messagePopup);
}, this);

Notes:

  • The easiest way to see this working is to open two browsers and point them both at http://localhost:9000
  • Left-click on the map to open a “create place” popup. If you’ve entered an avatar URL in the Avatar URL text box, this image will also be displayed in the pop-up
  • Enter a message, and click Create! – the pop-up will (or should, at least) appear on your map and the map in the other browser window
  • This doesn’t work in Internet Explorer, because it doesn’t support web sockets
  • If you want to try this on a network, change the URL in models.js from localhost to a hostname/IP address
  • This isn’t on Heroku because, the last I heard at, web sockets are not supported there

You can download the mapcrap – you’ll need Play 2.0 to run it.
Instructions:

  • Unzip it
  • cd into the directory
  • play
  • run
  • Point your browsers at http://localhost:9000

If you have any problems, please let me know!

* My parents are staying with me this week. My dad asked, “what is this good for?” about 2 hours ago. The explanation of the joy of coding and the satisfaction of writing something vaguely cool is still, sporadically, going on.

Play is seven-league boots

This blog has a lot of entries related to how-tos with the Play! framework, but one thing it’s missing is possibly an explanation of why I use Play so much.

It’s simple – I consider Play to be seven-league boots.

From Wikipedia (so it must be true):

Seven-league boots are an element in European folklore. The boots allow the wearer to take great strides—seven leagues each step—resulting in great speed. The boots are often presented by a magical character to the protagonist to aid in the completion of a significant task.

I couldn’t have said it better myself – great strides and great speed for significant tasks*.

* Also, Play comes from Zexenity, a French company, so it ticks the European box too

Play 2 modules – rewriting Deadbolt for the new generation of Play

Back in 2010, when I was young and full of beans, I wrote an authorization module called Deadbolt for the Play! framework in its 1.x incarnation. It was originally written to fulfil some needs I had for projects I was working on, but proved to be pretty popular with a wider audience. There’s no download counter at the Play module repository, unfortunately, so I have no idea how widely it’s used – but it is used, and that’s always nice to hear about.

Fast-forward to 2012, to when I’m old and full of gas, and Play is now at 2.0 RC3. It’s totally backwards-incompatible with the 1.x projects, which some people have complained about, but I personally applaud – as long as this doesn’t happen with every major release. It’s also totally backwards-incompatible with 1.x modules, which means that Deadbolt required some updating of its own.

Let’s get the negative issue out of the way before I get started on the nitty-gritty. In Play 1, you created a new module by typing “play new-module ” into your shell, and you were good to go. With Play 2 and its concept of modular applications, it seems the concept of modules has to some degree become blurred and there’s a lack of documentation to really address issues such as packaging, etc. It’s possible – or probable – that I’ve just missed the existing docs, so I’ll be following up on this with a future post that looks at creating a module from scratch.

And now, to the good bits.

The original Deadbolt was built in such a way that it had a few interfaces (it didn’t impose any persistence issues on you) and a few fairly monolithic classes that handled the authorization checks. You could apply static and dynamic checks with

@With(Deadbolt.class)
public class MyController extends Controller
{
    // static check - user must have the foo AND bars roles
    @Restrict({"foo", "bar"})
    public static void index() {...}

    // static check - user must have the foo OR bars role
    @Restrictions({@Restrict("foo"), @Restrict("bar")})
    public static void view() {...}

    // dynamic check - application-specific security check
    @RestrictedResource("foo")
    public static void edit() {...}
}

In the application, it was nice and unobtrusive – you add a few annotations (either at the view, controller or controller method level) and you have fine-grained authorization control over your application. Later additions let you give content type hints to make it easier to secure web services and ajax calls, or to unsecure or loosely secure elements.

In the actual implementation of Deadbolt however, there was a lot of monolithic code – the Deadbolt class itself covered all the dynamic and static checks, as well as the checks from the views. It worked well, but I was never particularly satisfied with the actual code that went into making it.

The re-write for Deadbolt 2 has taken – to my great joy and general happiness – a completely different approach thanks to the new architecture of Play 2. Each annotation – @Restrict, @Restrictions, @Dynamic, etc, – has an associated action which is invoked prior to the method. When mixing controller and method restrictions, the method restrictions are applied first which allows the more-specific restriction to apply to the resource. This behaviour was also present in the original Deadbolt, but it required a lot of framework-provided reflection and duplicate code. The result, to take a short example, is the @RoleHolderPresent annotation – this particular restriction will prevent access to anyone who isn’t logged into your application.

Here’s the annotation…

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
@Inherited
public @interface RoleHolderPresent
{
}

and here’s the action…

public class RoleHolderPresentAction extends AbstractDeadboltAction<RoleHolderPresent>
{
    public Result call(Http.Context ctx) throws Throwable
    {
        Result result;
        // here we check if a more specific action has already processed the call
        if (isActionUnauthorised(ctx))
        {
            result = onAccessFailure(getDeadboltHandler(configuration.handler()),
                                     configuration.content(),
                                     ctx);
        }
        else
        {
            // and here we perform the specific check for the annotation
            DeadboltHandler deadboltHandler = getDeadboltHandler(configuration.handler());
            RoleHolder roleHolder = getRoleHolder(ctx,
                                                  deadboltHandler);

            if (roleHolder != null)
            {
                markActionAsAuthorised(ctx);
                result = delegate.call(ctx);
            }
            else
            {
                markActionAsUnauthorised(ctx);
                result = onAccessFailure(deadboltHandler,
                                         configuration.content(),
                                         ctx);
            }
        }

        return result;
    }
}

For comparison, the equivalent of RoleHolderPresent was a member of a 481-line class.

The result is a much cleaner, less repetitive implementation. What duplication there is comes as a result of Java annotations not being able to implement interfaces, which is a reasonable trade-off. The result of the cleaner code – apart from the increased ease of maintenance, etc, it that it’s easier to see how to extend and improve the feature set. I for one would rather work with five twenty-line classes than one of one hundred lines.

One thing that’s missing at the moment is the Scala API. Play 2 supports Java and Scala as first-class citizens, and I want to take advantage of this to widen the potential user base of Deadbolt.

The new architecture of Play 2 is – to my mind – the result of a carefully thought out evolution of the framework, and that’s why I support the lack of backwards compatibility.

Deadbolt-2 on github: https://github.com/schaloner/deadbolt-2