Within our organization we are evaluating Cloud based technologies and one of the nagging questions that came up in my mind was, "just how portable are applications in the Cloud?"

With this in mind, I set out to port a REST API that was built to support our Mobile Service Offering from Node.js over to Java based technologies the source code for which can be found here.

The API is used to "spot" one of our founder's longitude and latitude as he traverses the city and report out those locations. It has two simple operations:

  1. GET: Depending upon a the query parameter called "count" it either returns the number of times he was spotted or the actual coordinates and times where he was spotted.

  2. PUT: This operation creates a record in the database of the longitude and latitude where he was spotted.

In my main day to day work, I use JAX-RS and Jersey, but I thought it would be fun to experiment with Scala based REST providers so I landed on the following technology stack:

  1. Spray.io: This is a light-weight framework that allows you to built REST api's and it supports JSON out of the gate.

  2. Slick: This is the ORM technology that I choose to allow me to interact with the database.

  3. Typesafe Config: I decided I didn't want to go through the hassle of configure a JNDI datasource especially for local testing so I needed a mechanism to be able to configure this. The library provides a nice way to do so.

  4. SBT: This is the standard build tool for Scala applications.

  5. MySQL: This is the most widely popular Open Source Database and its the one most readily supported by most of the Cloud providers.

  6. The source code for this POC can be found here.

The Cloud providers I decided to attempt this on were as follows:

  1. Amazon Web Services Elastic Beanstalk

  2. Microsoft Windows Azure Infrastructure Services

  3. RedHat's OpenShift

I won't go into a ton of detail on setting these up because all the providers have fairly well documented steps to follow, but here are some quick highlights for each

  1. Beanstalk: This was the simplest one as all I had to do was name my application, determine the region, select Tomcat for my application server, select the RDS type [MySQL], upload my application and I was off and running.

  2. OpenShift: This again was fairly straight forward as well, I created a Tomcat cartridge and associated a MySQL one with it. The only trick with deploying things to OpenShift is that they use Git along with Maven builds, so I had to follow these instructions to deploy a pre-built WAR file.

  3. Windows Azure Infrastructure Services: This was the hardest of the three to setup because there is not a pre-built environment for Java deployment and MySQL. For this environment, I went with Ubuntu as the operating system and then used these instructions to install Tomcat and these instructions on how to install MySQL.

A couple of notes on challenges I encountered:

  1. The first challenge I had was around creating the database tables I needed. The initial version of Slick that I was using didn't support that out of the box for MySQL, but once I upgraded to the 2.x stream I followed this post on how to conditionally create the tables.

  2. I attempted to deploy it on Google's App Engine but could not because Akka uses threads and App Engine does not allow such things.

  3. I had to externalize the DB config and fortunately Typesafe's config project supports conditional configuration as each provider has their own set of variables that define the connection to the DB or in the case of Azure IaaS its roll your own. For reference, AWS's variables can be found here and Open Shifts can be found here.

  4. The technology I used for the REST Endpoints does not work well in an environment where you have a root context other than "/". This is because its routing mechanism assuming that as the base and when deployed under a name that is not the case. They do have a mechanism to handle this but, I had to slightly modify the config and code to account for this. Which made things slightly less portable as it couldn't switch it with a code/config change. See this post for some details

  5. OpenShift was the most challenging if only because their environment variables are confusing at best and a critical one was missing. See my post on their boards for more details.

So the question is, "was my application portable across these providers?" The answer was a resounding "yes" provided the application is designed in such a way that it isn't tied to the Cloud providers' products.