Cloud Foundry Now Supports Play!

May 31, 2012 Jennifer Hickey

featured-cf-genericCloud Foundry now supports Play 2.0 as a first-class framework. Play is a lightweight, stateless, web-friendly framework for Java and Scala. Developers can leverage this event-driven non-blocking IO architecture to build highly scalable applications. Play 1.0 applications were previously deployable to Cloud Foundry as WAR files. Play 2.0, which doesn’t have built-in support for WAR files, can now be deployed to CloudFoundry.com and take advantage of being a fully supported framework that includes auto-reconfiguration, simplified service connections, and automatic database management. Play developers, welcome to Cloud Foundry!

Getting Started with Play 2.0

First, we will need to install or update the Cloud Foundry command line tool, VMC, to the latest version by using the following command:

gem install vmc

We can verify that we have the right version using:

vmc -v

which should show the version to be 0.3.18 or higher. Now let’s get started with the Java zentasks sample found in the Play 2.0 distribution. We’ll run the “play dist” command which will compile our code, retrieve all the required dependencies and create a self-contained binary that can be uploaded to Cloud Foundry.

dev$: cd play-2.0.1/samples/java/zentasks
zentasks$: play clean dist
[info] Loading project definition from /Users/jencompgeek/development/resources/play-2.0.1/samples/java/zentasks/project
[info] Set current project to zentask (in build file:/Users/jencompgeek/development/resources/play-2.0.1/samples/java/zentasks/)
[success] Total time: 0 s, completed May 15, 2012 2:27:29 PM
[info] Updating {file:/Users/jencompgeek/development/resources/play-2.0.1/samples/java/zentasks/}zentask...
[info] Done updating.
[info] Compiling 10 Scala sources and 9 Java sources to /Users/jencompgeek/development/resources/play-2.0.1/samples/java/zentasks/target/scala-2.9.1/classes...
[warn] Note: Some input files use unchecked or unsafe operations.
[warn] Note: Recompile with -Xlint:unchecked for details.
[info] Packaging /Users/jencompgeek/development/resources/play-2.0.1/samples/java/zentasks/target/scala-2.9.1/zentask_2.9.1-1.0.jar ...
[info] Done packaging.

Your application is ready in /Users/jencompgeek/development/resources/play-2.0.1/samples/java/zentasks/dist/zentask-1.0.zip

Now we can deploy the application to Cloud Foundry with the VMC push command:

zentasks$: vmc push --path=dist/zentask-1.0.zip
Application Name: zentasks
Detected a Play Framework Application, is this correct? [Yn]:
Application Deployed URL [zentasks.cloudfoundry.com]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [256M]:
How many instances? [1]:
Create services to bind to 'zentasks'? [yN]: y
1: mongodb
2: mysql
3: postgresql
4: rabbitmq
5: redis
What kind of service?: 3
Specify the name of the service [postgresql-38199]: tasks-db
Create another? [yN]:
Would you like to save this configuration? [yN]: y
Manifest written to manifest.yml.
Creating Application: OK
Creating Service [tasks-db]: OK
Binding Service [tasks-db]: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (186K): OK
Push Status: OK
Staging Application 'zentasks': OK
Starting Application 'zentasks': OK

Looks like zentasks deployed successfully. Let’s check the logs:

zentasks$: vmc logs zentasks
====> logs/stdout.log <====

Auto-reconfiguring default
Enabling JPA auto-reconfiguration
Play server process ID is 13269
[warn] play - Plugin [play.db.jpa.JPAPlugin] is disabled
[info] play - database [default] connected at jdbc:postgresql://172.31.244.70:5432/dd2c9bc5b72134998adcfe4dcfa6660f4
[info] play - Application started (Prod)
[info] play - Listening for HTTP on port 59907...

Our Play 2.0 application is up and running on Cloud Foundry in 2 simple steps, no modification required!

Like most Play applications, zentasks contains database evolutions. Cloud Foundry automatically applied these evolutions to the database on application start. But how was the app able to make use of the PostgreSQL service we provisioned and bound to the application during deployment? If we look at the application.conf file, we see that the application is configured to use an in-memory database:

db.default.driver=org.h2.Driver db.default.url="jdbc:h2:mem:play"

Cloud Foundry actually used a mechanism called auto-reconfiguration to automatically connect the Play application to the relational database service. If a single database configuration is found in the Play configuration (for example, “default” from above) and a single database service instance is bound to the application, Cloud Foundry will automatically override the connection properties in the configuration to point to the PostgreSQL or MySQL service bound to the application. This is a great way to get simple apps up and running quickly. However, it is quite possible that your application will contain SQL that is specific to the type of database you are using. For example, several of the samples that come with Play make use of sequences in evolution scripts. This, of course, works with the in-memory database and will also work on PostgreSQL, but it will not work on MySQL. In these cases, or if your app needs to bind to multiple services, you may choose to avoid auto-reconfiguration and explicitly specify the service connection properties.

Connecting to Cloud Foundry Services

As always, Cloud Foundry provides all of your service connection information to your application in JSON format through the

VCAP_SERVICES environment variable. However, connection information is also available as series of properties you can use in your Play configuration. Here is an example of connecting to a PostgreSQL service named “tasks-db” from within an application.conf file:

db.default.driver=${?cloud.services.tasks-db.connection.driver}
db.default.url=${?cloud.services.tasks-db.connection.url}
db.default.password=${?cloud.services.tasks-db.connection.password}
db.default.user=${?cloud.services.tasks-db.connection.username}

This information is available for all types of services, including NoSQL and messaging services. Also, if there is only a single service of a type (e.g. postgresql), you can refer to that service only by type instead of specifically by name, as exemplified below:

db.default.driver=${?cloud.services.postgresql.connection.driver}
db.default.url=${?cloud.services.postgresql.connection.url}
db.default.password=${?cloud.services.postgresql.connection.password}
db.default.user=${?cloud.services.postgresql.connection.username}

We recommend keeping these properties in a separate file (for example “cloud.conf”) and then including them only when building a distribution for Cloud Foundry. You can specify an alternative config file to “play dist” by using “-Dconfig.file”.

Opting Out of Auto-Reconfiguration

There may be situations in which you would like to opt out of auto-reconfiguration. For example, you may have an in-memory database that should not be bound to a Cloud Foundry service. If you use the properties referenced above, you will automatically be opted-out. To explicitly opt out, include a file named ”

cloudfoundry.properties” in your application’s conf directory, and add the entry “autoconfig=false“.

Debugging Your Play Application

If you are using a local Cloud Foundry setup, you can remotely debug your Play applications. Simply use the flag “--debug” when doing a “vmc push” or “vmc start“. You can then run “vmc instances” to get the debug host and port information:

zentasks$: vmc instances
+-------+---------+--------------------+-----------------+------------+
| Index | State   | Start Time         | Debug IP        | Debug Port |
+-------+---------+--------------------+-----------------+------------+
| 0     | RUNNING | 05/15/2012 05:50PM | 192.168.193.193 | 59845      |
+-------+---------+--------------------+-----------------+------------+

Just use the displayed debug IP and port in the remote debugger in your favorite IDE and start debugging!

Conclusion

We look forward to seeing your Play applications on Cloud Foundry. Please feel free to send us feedback or submit a pull request to help us improve our support for the Play Framework. Now get started building those apps!

– Jennifer Hickey The Cloud Foundry Team
Don’t have a Cloud Foundry account yet? Sign up for free today

About the Author

Biography

Previous
From Disruption to Insight at the Data Science Summit 2012
From Disruption to Insight at the Data Science Summit 2012

2012 is proving to be the year of Big Data, demanding the attention of executives, thought leaders, academi...

Next
Urban Dictionary: Recent Infrastructure Changes for Rails at Scale
Urban Dictionary: Recent Infrastructure Changes for Rails at Scale

Urban Dictionary is a Ruby on Rails application and the 109th most visited site in the country according to...