Cloud Foundry Blog

Password Policy in Cloud Foundry

It’s a well-known fact that most users choose weak passwords. Choosing a strong password is actually much harder than it might seem at first. Huge wordlists constructed from previously leaked password databases are readily availably online and we consistently pick passwords which are at or near the top of those lists.

In a worst-case (but increasingly common) scenario, where the actual database of hashed passwords is stolen, a half-decent cracking program will be able to spit out these weak passwords almost instantly, leading to large numbers of accounts being compromised. This is especially true for simple unsalted password hashes, which companies have been found to be using in some of the recent scandals, despite it being acknowledged as very poor practice for many years. Cloud Foundry stores passwords using bcrypt, which is deliberately designed to hinder password-cracking, but even so, weak passwords are still vulnerable.

So what can be done to help people choose stronger passwords which are not easily cracked? Some sites have complicated and annoying password policies which force you to include a combination of numbers, symbols and different-case letters in your password, despite the fact that this usually just makes your password hard to remember without actually making it stronger (as depicted in the famous XKCD “correct horse battery staple” cartoon).

Most users are familiar with the use of password-strength meters. In Cloud Foundry we plan to use a meter not just as a guideline for choosing a good password, but also to define the system policy. So rather than saying “you must satisfy these X annoying rules”, we simply say “you must get this score or higher on the meter”.

Obviously, the question then arises as to what makes a good “score”. The code we use is based on the calculations from Dan Wheeler’s zxcvbn project (https://github.com/lowe/zxcvbn), which uses a combination of common password dictionaries and checking for patterns such as dates, keyboard sequences (hence the project name) and other typical “bad” password choices. The dropbox tech blog about the project gives an excellent overview of the algorithms used and the rationale for choosing this approach. It’s not perfect – finding a weak password with a reasonable score isn’t too difficult, particularly if you consider languages other than English, but it’s definitely a good start and something we hope to improve on in future releases.

The main difference is that while the original project is a browser-based Javascript library, we will be using a server-side implementation both to provide feedback and to actually enforce a particular policy. The port of the zxcvbn library, as well as a sample application (both in Scala), are available on github. The sample application is also running on Cloud Foundry at https://szxcvbn.cloudfoundry.com/password.html. You can either use the ajax-enabled UI or directly submit requests to it and get a JSON response. Here’s an example using curl

$ curl -H "Accept: application/json" -d password=correcthorsebatterystaple https://szxcvbn.cloudfoundry.com/

which returns

{"score":8,"crack_time_s":2.0372004064749978E9,"match_sequence":[{"start":0,"end":6,"token":"correct","dictName":"english","matchedWord":"correct","rank":1525},{"start":7,"end":11,"token":"horse","dictName":"passwords","matchedWord":"horse","rank":494},{"start":12,"end":18,"token":"battery","dictName":"english","matchedWord":"battery","rank":3845},{"start":19,"end":24,"token":"staple","dictName":"english","matchedWord":"staple","rank":14066}],"crack_time":"63.38 years","entropy":45.21165314373938}

In our production implementation, the interface will only return the score plus the server’s required score (to allow the UI to tell the user how close they are to providing a strong enough password). The sample application is more verbose, providing information on how it has analyzed the supplied password string.

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

How to Integrate an Application with Cloud Foundry using OAuth2

This article explains how to use Cloud Foundry APIs from a user application using the built in identity management solution in the User Account and Authentication Service (UAA). The UAA acts (amongst other things) as an OAuth 2.0 Authorization Server, granting access tokens to Client applications for them to use when accessing Resource Servers in the platform, such as the Cloud Controller. This article describes the responsibilities of a Client application and the mechanics of setting one up. It uses a simple example Client application (available on github), and recasts it into various forms to help developers with different language and tool preferences to get to grips with the topic (Ruby, Java, Grails).

Quick Introduction to OAuth2

In a typical OAuth2 scenario (as developed in the sample application) OAuth2 is a protocol with 4 main participants:

  1. Client application, often a web application
  2. Resource Owner, usually a User
  3. Resource Server (another web application or web service)
  4. Authorization Server

The User tells an Authorization Server that he trusts the Client to access the Resource Server on his behalf. In OAuth2 terms we are going to see a sample Client application in which the Authorization Server grants a bearer token to the Client using an Authorization Code flow. This scenario is composed of 4 steps:

  1. Client redirects User to Authorization Server /oauth/authorize to authorize a token grant
  2. Authorization Server authenticates the User and obtains his approval, redirecting back to the Client with a one-time Authorization Code
  3. Client contacts the Authorization Server directly at /oauth/token, exchanging the Authorization Code for an Access Token
  4. Client presents the Access Token in a request to Resource Server

Responsibilities of a Client Application

A Client application has these responsibilities:

  1. Register with the UAA and get a client id and secret
  2. Do not collect User credentials – delegate to the Login Server
  3. Send a unique state parameter with each request to the /oauth/authorize endpoint, and check it later in a callback
  4. Keep the Access Token and any associated Refresh Token a secret
  5. Watch out for access denied responses from the Resource Server and take appropriate action
  6. Use the Login server if there is one
  7. Don’t log the User out of Cloud Foundry unless they explicitly ask for it

Register With the UAA

A Client application must have a pre-existing relationship with the UAA. This is a standard OAuth2 feature, and is necessary to ensure that the platform can control access and give Users peace of mind that there is some control over the access to their data and applications.

When a Client registers with the UAA the owner or developer of the Client provides a redirect URI (or list of them) where it will accept callbacks from the UAA, and in return will get an id and a secret, and a list of scopes that it is allowed to access on behalf of a user. The sample application is registered in the local UAA by default with these properties:

{
  "client_id": "app",
  "client_secret": "appclientsecret",
  "scope": ["cloud_controller.read", 
    "cloud_controller.write",
    "openid", ...],
  "redirect_uri": ["http://localhost"]
}

The scope values allow the client to operate the Cloud Controller (read and write) and to get the user’s profile data (“openid”). These are similar to the scopes granted to vmc in production. Note that if you were to register a client with the UAA on cloudfoundry.com you would expect the scopes would be limited by default (e.g. we would not normally expect Client applications to be able to change user’s passwords).

The redirect URI in the example above is actually not the value you will see in a local UAA by default: there it would be an empty list. An empty redirect URI in the client registration allows a client to request a redirect to any address, so this would not be allowed in production. In production a redirect is required to prevent an attack by a bad guy who might want to steal authorization codes or access tokens (see the earlier CSRF article for details of the attacks).

Client registrations on cloudfoundry.com are available on a case-by-case basis only at the moment, so please contact the Support Team (support@cloudfoundry.com) for help if you would like to try this in the real system. The Identity Team are also working on some features to automate client registration and open it up to more users, so keep an eye out on the cloudfoundry.org and cloudfoundry.com blog sites for news.

Authentication

When a Client registers with the UAA it will get an id and a secret which must be used any time a Client needs to authenticate itself with the platform. Principally this will be at the OAuth2 token endpoint /oauth/token, when exchanging an authorization code for an access token. The token endpoint requires a Client to send the id and secret in a standard HTTP Basic header, e.g.

POST /oauth/token HTTP/1.1
Authorization: Basic YXBwOmFwcGNsaWVudHNlY3JldA==

{
  access_token: FUYGKRWFG.jhdfgair7fylzshjg.o98q47tgh.fljgh,
  expires_in: 43200,
  client_id: app,
  scope: openid,cloud_controller.read
}    

State Parameter

As protection against Cross Site Request Forgery (CSRF), the OAuth2 spec allows for a state parameter to be sent in the authorization request, and if it is there the Authorization Server sends it back in the callback that contains the authorization code. It is the Client’s responsibility to generate a value for the state and to assert that it issued that particular value when it comes back. The value of the state parameter should be unique (e.g. random), and not easily generated by an attacker. The Client can implement the state in one of two ways, either by storing the value in between the two requests as a key in a user session, or by encoding some information in it that can be verified when it sees it again (e.g. a unique id in a special format encrypted with a secret that only the Client knows).

When the callback comes to the Client application with an authorization code in the query parameters, the Client extracts the state parameter and verifies that it generated the value. If it cannot verify this then it should not proceed: an unrecognised state value can be a sign of a CSRF attack and it should be rejected.

In most cases Client applications will use a library to manage the authorization and token grant, and the library will take care of the state for you. It is the browser that actually sends both requests, the first to the Authorization Server, and the second to the Client application, so in principle a user session is available and that is normally the easiest way to implement the state check. Many of the libraries (e.g. omniauth-oauth2 as used in the Ruby sample, and Spring Security OAuth in the Java sample) do this for you. Some do not (e.g. Scribe as used in the Grails sample), in which case you should take care to add that feature to your application; i.e. it is not recommended to use the Grails sample as it is.

Using the Access Token

Once you have a token, your Client application can send it in a request header to protected resources on the platform. E.g. getting the current user’s profile information from the UAA:

GET /userinfo HTTP/1.1
Authorization: Bearer eYFDLKJHLKJ.DYOGFKHDLJDF.uIOFDUF

HTTP/1.1 200 OK
{
  "user_id":"ec5797e2-24dd-44c9-9e92-f03d0ef9d11e",
  "user_name":"marissa",
  "given_name":"Marissa",
  "family_name":"Bloggs",
  "name":"Marissa Bloggs",
  "email":"marissa@test.org"
}

Note that Cloud Foundry, unlike some older OAuth2 providers (e.g. Facebook), in general does not accept an access token as a request or form parameter. You must use the Authorization header, as recommended in the OAuth2 specification.

Responding to Unauthenticated or Access Denied Errors

If your access token is expired or invalid, you should see an HTTP 401 UNAUTHORIZED response from a protected resource. For example:

GET /userinfo HTTP/1.1
Authorization: Bearer GARBAGE

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="UAA/oauth", error="invalid_token", error_description="Invalid access token: GARBAGE"

{
  "error":"invalid_token",
  "error_description":"Invalid access token: "
}

The error response will tell the Client the difference between an expired or invalid token. In either case you can ask for a new one, and if the problem was an expiry then you might also have a refresh token that you can exchange for a new access token without needing to get the user’s approval again (the refresh token would have been granted at the same time as the original access token and it is the Client’s responsibility to hold on to it).

Or if the token has insufficient scope to access the resource you asked for, you should see an HTTP 403 FORBIDDEN. For example:

GET /Users HTTP/1.1
Authorization: Bearer eYFDLKJHLKJ.DYOGFKHDLJDF.uIOFDUF

HTTP/1.1 403 FORBIDDEN
WWW-Authenticate: Bearer error="insufficient_scope", error_description="Insufficient scope for this resource", scope="scim.read"
{
  "error":"insufficient_scope",
  "error_description":"Insufficient scope for this resource","scope":"scim.read"
}

In both cases there was a JSON body, and a WWW-Authenticate header to tell you what went wrong, and a little bit about how you can fix it. The fact that a Bearer token is required is indicated, and in the case of the scope issue, also the required scope that you are missing. Your client or user may not have permission to acquire a token with that scope, in which case there is nothing you can do, but in other cases the information is useful and you may be able to get another token that does what you need.

The example responses above are from UAA resources (i.e. APIs provided by the UAA itself). At the time of writing the 401 and 403 responses from the Cloud Controller may not resemble precisely the examples above, but they should be similar.

Requesting Scope for an Access Token

In the sample applications the tokens are all acquired without specifying a scope explicitly, so they have the default scopes allowed to the Client and User. This is always an option, but in general it is good practice for clients to only ask for tokens with a specific scope that allows them to do as much as they need but no more – e.g. do not ask for cloud_controller.write if you only need cloud_controller.read. This allows the UAA to alert the user specifically to what your application wants to do, and in turn they can make a better decision about whether or not to allow it. A user is more likely to grant permission for a third party application to read data than write it, for instance.

The Login Server

The Login server is a UI for the UAA in cloudfoundry.com whose features, design and implementation will be covered in a separate article. For the purposes of this article it suffices to say that a Client application should us the Login server if it is available for the OAuth2 /oauth/authorize endpoint. This ensures that applications authenticating with Cloud Foundry have a uniform user experience including seamless single sign on (SSO).

Logout

A Client application can have user sessions of its own (the sample implementations all do) and so it makes sense for it to have a logout feature. The Login Server (or UAA if there is none) has a logout endpoint as well (/logout.do), and if a Client application wants to it can provide a link to that endpoint, and specify a redirect to itself so that the User lands back in a familiar place after being logged out (see the sample application code for examples, e.g. /logout.do?redirect=http://myapp.cloudfoundry.com/loggedout). If the User clicks that link then he will clear his session with all Cloud Foundry applications, which might not be something he wanted to do. A Client application can and should present Users with the option to logout of Cloud Foundry, once they have logged out of the local session, but the User should be made aware of what they are doing if they follow that link.

The Sample Client Applications

The sample applications accompanying this article are designed to be as simple as possible – the minimum needed to get an interaction between a user and the Cloud Controller, mediated by a UAA bearer token. More complicated functionality should be easy to add, and there are libraries to help do that which we haven’t used in the samples just to keep them simple.

The roles played in the system are

  • Authorization Server = UAA
  • Resource Server = Cloud Controller (or a locally deployed fake)
  • Client = the sample application

All the implementations of the sample have the same features:

  • an authentication filter that only allows valid Cloud Foundry users to use the rest of the application
  • a home page that lists the properties of the currently authenticated user
  • an /apps page that lists the currently deployed applications of the current user in Cloud Foundry
  • a /logout link that clears the local session in the Client itself and then gives the user the option to also logout from Cloud Foundry

The authentication filter is responsible for acquiring an access token from the UAA and storing it in a local session, so it can be re-used without having to ask the UAA on every request (optional, but recommended). The filter also uses the token to build a representation of the User (so we can say “Hello” on the home page). It does this simply by sending it to the /userinfo endpoint on the UAA (a similar feature is available from virtually all OAuth2 providers, e.g. the /me endpoint at Facebook). In a real Client application the user data could be omitted if all you care about is the access token, or it could be used more extensively, e.g. to correlate with a local user database and assign additional, application-specific roles and permissions.

The /apps endpoint also uses the access token. It sends it to the /apps endpoint on the Cloud Controller, gets back a list of the user’s deployed applications, and then renders it. Obviously you could do more than that with the token to build out a richer application, and depending on the runtime or framework you are using there are tools available from Cloud Foundry to help you do that. So, for example, if your application is running on the JVM you can use the Cloud Foundry Java Client to interact with the Cloud Controller in a more convenient way than directly through the JSON endpoints. Similarly, if your application is in Ruby, then there is a Cloud Foundry Ruby Gem that you can use to do similar things.

In all cases you should inject the access token in the appropriate place in the library API and not have to collect user credentials, even though the libraries still support that (for a limited time).

Deploying the Sample

The samples can all be deployed locally for testing purposes, and the UAA instance defaults to one at http://localhost:8080/uaa. They also all default to using a fake Cloud Controller which is the API sample from the UAA repo. The fake Cloud Controller and the UAA can both be launched from the command line using Maven (see instructions in the UAA README):

$ git clone git@github.com:cloudfoundry/uaa.git
$ cd uaa
$ mvn install
$ cd samples/api
$ mvn tomcat:run -P integration

The samples also all work with the real UAA and the real Cloud Controller, but you need a client registration to make that work. If you have a real Cloud Foundry client you should use login.cloudfoundry.com for authentication and user approvals (this is the holder of the single-sign-on state for the platform) and uaa.cloudfoundry.com for the machine endpoints (principally /userinfo in this use case).

Appendix: Sample Implementation Details

The sample applications are in Github under an umbrella project. You can clone them using git:

$ git clone https://github.com/cfid/uaa-samples.git

or you can download the source code from the download link on the github website.

Ruby

The Ruby sample is written in sinatra which has a nice DSL for declaring web endpoints and filters. It uses omniauth-oauth2 to handle the OAuth2 Authorization Code flow and rest-client to access the Resource Servers. There is only one file app.rb and you can launch it from a command line like this (assuming you have Ruby 1.9.2 and bundle on your PATH):

$ bundle # do this once
$ ruby app.rb
...
>> Listening on 0.0.0.0:4567, CTRL+C to stop

The application is now running on http://localhost:4567.

Omniauth works by providing strategy implementations for specific token providers, and there isn’t a UAA strategy available officially yet, so the application adapts an existing abstract “oauth2″ strategy. This strategy provides an endpoint at /auth/oauth2 which is where the redirect and callback to the UAA is handled for you. The main thing the application has to do is tell this endpoint the client credentials and also how to send them to the token endpoint on the UAA. The default behaviour of omniauth-oauth2 strategy follows an older specification than the one implemented by the UAA, so we have to do a bit of work to get the client_options and token_params in the form required. (Since the existing abstract strategy doesn’t match the UAA very well we think it might be better to implement an UAA strategy using the [UAA gem][UAAGEM]. We are exploring this possibility on the Cloud Foundry Identity Team, and we need to decide on the implementation before we publish an omniauth strategy for general use.)

The application responds to environment variables for picking up settings of the remote URLs etc:

  • UAA_LOGIN_SERVER = location of the Cloud Foundry Login Server where the Authorization endpoint lives. Defaults to the value of UAA_TOKEN_SERVER, but should be set to https://login.cloudfoundry.com in production.
  • UAA_TOKEN_SERVER = location of the UAA. Defaults to http://localhost:8080/uaa. In production use https://uaa.cloudfoundry.com.
  • CLOUD_CONTROLLER_SERVER = the Cloud Controller root URL. Defaults to http://localhost:8080/api. In production use https://api.cloudfoundry.com.
  • CLIENT_ID = the id in the Client registration. Defaults to app.
  • CLIENT_SECRET = the secret in the Client registration. Defaults to appclientsecret.

Grails

Grails is an opinionated web development and developer productivity tool that uses Groovy, Spring and a set of its own DSLs and conventions. Because of it’s heavy use of convention over configuration it is possible to build quite rich applications with relatively little code.

All the application logic is in HomeController.groovy and there is some configuration in Config.groovy and some properties files with names like application-*.;properties. To launch the application you can import it into a Grails aware IDE (like Spring Tool Suite), or run it on the command line (with Grails 2.1.1):

$ grails -Dgrails.server.port.http=9080 RunApp

The application shows up on [http://localhost:9080/grapps]. Here we show the application being launched on port 9080 so as not to clash with a UAA that you might be running locally. You could also run the UAA, API and Client applications all in the same container on port 8080 (e.g. by building war files and deploying them, or in the IDE with drag and drop).

The sample uses the Grails Scribe plugin to handle the Authorization Code flow. Scribe is quite rich, but too old to support well the most up to date versions of the OAuth2 specification, so we had to do quite a lot of work to make it work with the UAA. Once it is configured it works though and the rest of the Grails community seems to like the Scribe plugin for other OAuth providers like Facebook and Google.

The application responds to environment variables for picking up settings of the remote URLs etc:

  • UAA_PROFILE = a short name for the profile, which is converted into a properties file name to pick up the URL information needed. Default value is default, and properties files are provided for cloud and vcap profiles.
  • CLIENT_ID = the id in the Client registration. Defaults to app.
  • CLIENT_SECRET = the secret in the Client registration. Defaults to appclientsecret.

Java and Spring

The Spring sample uses Spring Security OAuth on the client side (as opposed to the server which is what the UAA is). The filter for authentication is a combination of a standard filter from Spring Security OAuth, and one from the UAA common JAR (a library used to build the UAA, but also useful for building Clients and Resource Servers).

The application logic is in TreeController.java, which uses a RestOperations to access the Cloud Controller API resources. The rest of the features are provided by Spring Security and are configured in the main Spring configuration file at WEB-INF/spring-servlet.xml. The main aspect of that which is important is the filter that handles authentication with the UAA:

<http ...>
    <intercept-url pattern="/**" access="hasRole(&#39;uaa.user&#39;)" />
    ...
    <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
    <custom-filter ref="socialClientFilter" before="FILTER_SECURITY_INTERCEPTOR" />
</http>

With those filters in place the servlet request is automatically populated with a Principal object containing the user’s profile. Spring injects it into the HomeController so that the information can be displayed to the user in home.jsp. The oauth2ClientFilter is responsible for setting up the access token in a context that can be used by the RestOperations (which is an OAuth2RestTemplate) in HomeController.

To launch the application drop it into the same container as the UAA and API running locally (e.g. drag and drop in the IDE). Or run it on the command line separately using

$ mvn tomcat7:run -Dmaven.tomcat.port=9080

The application responds to environment variables for picking up settings of the remote URLs etc:

  • UAA_PROFILE = a short name for the profile, which is converted into a properties file name to pick up the URL information needed. Default value is empty, and properties files are provided for cloud and vcap profiles.
  • CLIENT_ID = the id in the Client registration. Defaults to app.
  • CLIENT_SECRET = the secret in the Client registration. Defaults to appclientsecret.
Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Using the New Scripted JavaScript Editor for Node.js Development

This week VMware released the Scripted code editor on GitHub: https://github.com/scripted-editor/scripted.

Scripted, a JavaScript editor from VMware, is a general purpose code editor intended to be very lightweight with an initial focus on giving a great JavaScript editing experience– particularly around content assist and awareness of module systems. It is a browser-based editor that runs locally on a developer’s machine with a Node.js instance serving the editor code and performing the editor operations. The only pre-req for running Scripted is that you have a recent version of Node.js installed. Scripted is implemented in 100% JavaScript, HTML and CSS. If you are interested in more background on Scripted, you can read more about it on the SpringSource.org blog.

Features

  • Fast startup, lightweight
  • Syntax highlighting for JavaScript, HTML and CSS
  • Errors and warnings:
    • JSLint is integrated to provide error/warning markers on JavaScript code
    • AMD and CommonJS module resolution: There is basic resolution where unresolved references will be marked as errors
  • Content assist:
    • Basic content assist for HTML, CSS
    • For JavaScript, content assist is driven by a type inferencing engine which is aware of AMD/CommonJS module dependencies and also uses JSDoc comments to help it understand the code
  • Hovers: Hovering over a JavaScript identifier will bring up the inferred type signature
  • Navigation: Press F8 on an identifier (that the inferencer has recognized) and the editor will navigate to the declaration. This also works on module identifiers (e.g., in define() clauses)
  • Formatting: JSbeautify is integrated
  • Sidepanel: Alongside the main editor, a sidepanel can be opened. Currently this can be used to host a second editor
  • Key binding to external command: Key bindings in the editor can invoke external commands (less, mvn, etc.)

There is much more detail on these features in the wiki documentation.

For Node.js Development

As listed in the features above, Scripted understands the CommonJS module system, as employed by Node.js apps. Understanding modules means two key things:

  • References to non-existent modules can be reported at editing time.
  • Knowing the module, we can look inside and from the contents offer appropriate content assist where the module is being used.

The following screenshot shows Scripted being used on a Node.js module and in this case an invalid module reference is being reported:

In that same piece of code, here we can see that because we recognized the module, content assist is correctly proposing the two methods from the users module, called getUser(id) and getUserCount():

The keen eyed amongst you will notice that in the content assist proposals the return value of getUser(id) was shown as a Person. This was inferred by using JSDoc that was attached to the definition of getUser(id) in the users module:

Knowing the return value then enables smart content assist at the location where the return value of the function is referenced.

For an integrated experience with Cloud Foundry, you can use the key binding configurations for Scripted to cause a vmc operation to execute from the editor. Configuration of Scripted is done through a .scripted file at the root of the project, a bit like a .virc file for vi. This file is a JSON format document, and the supported configuration options are covered in the documentation (see the section on configuration here). Using the exec-keys config option, it is possible to connect a key binding to invocation of a command. Here is some vmc related configuration:

{
    "exec": {
        "onKeys": {
            "ctrl+shift+alt+p": {
                "name": "vmc push scriptedapp",
                "cmd": "vmc push -n scriptedapp --runtime node08 --path .",
                "timeout":60000
            },
            "ctrl+shift+alt+u": {
                "name": "vmc update scriptedapp",
                "cmd": "vmc update -n scriptedapp",
                "timeout":60000
            }
        }
    }
}

In this next screenshot you can see:

  • On the right the help panel is open and the new key bindings are listed for our vmc operations.
  • The command output currently goes to the JS console (this will be improved!). The console here is showing the command has been invoked and the push was successful.

Want To Try It Out?

If you wish to try it out for yourself, arm yourself with a copy of Node.js then jump onto the Scripted GitHub page for instructions on how to get started.

Future Plans

Over the next few months we are going to focus on a few things:

  • Even smarter content assist and improved navigation options.
  • More side panel contents. This is something I haven’t focused on in this article but it is shown in the video available on the project homepage. The side panel is intended to host information relevant to the task you are trying to achieve in the main editor. This might be code, documentation, search results or a preview. Watch the video to see the side panel in action.
  • A plugin system for extending Scripted. Plugins, like Scripted itself, will be 100% JavaScript, HTML and CSS.
  • Debugging integration. Exploring integration with tools like Chrome Dev Tools and Node.js inspector.

We open-sourced Scripted to accelerate adoption and collect feedback. If you want to help us shape the editor, please join in the discussion. There is a scripted-dev Google Group for discussing it and a jira issuetracker for logging bugs, enhancement requests and voting on existing issues to ensure they are prioritized appropriately. If you want to start hacking on the codebase yourself we are definitely open to submissions–see the GitHub page for more information. The codebase is very new at the moment so there isn’t really a steep learning curve.

Please try it out! https://github.com/scripted-editor/scripted.

Andy Clement

Andy Clement is a staff engineer in the SpringSource division of VMware, based in the languages and tools lab in Vancouver. He has more than ten years experience in Enterprise Application Development and now spends his time building tools for languages like AspectJ, Groovy and JavaScript and frameworks like Grails. He currently oversees the Groovy Grails Tool Suite deliverable, a variant of the Spring Tool Suite with a focus on Groovy and Grails.

 

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Securing RESTful Web Services with OAuth2

As an active committer on Spring Security OAuth and the Cloud Foundry UAA, one of the questions I get asked the most is: “When and why would I use OAuth2?” The answer, as often with such questions, is “it depends.” However, I must admit, there are some features of OAuth2 that make it compelling in a wide variety of situations, especially in systems composed of many lightweight web services. This article guides you through updating a system to be secured with OAuth2 and the decision points for choosing to build such a system.

There is a strong trend at the moment towards distributed systems with lightweight architectures based on plain text web services (usually JSON). In this article we concentrate on these services and the systems they are part of, and look at some options for their basic security needs. An example of such a system is the open platform as a service, Cloud Foundry, in which the UAA acts as an OAuth2 provider. Using Cloud Foundry as an example also indicates that the trend in lightweight services is driven by a related trend towards cloud-based platforms for application deployment, both in the Internet at large and in the enterprise.

I recently published a blog post that provides an overview of the UAA: Introducing the UAA and Security for Cloud Foundry. The remainder of this article is about securing REST services in with OAuth generically and not necessarily specifically to the Cloud Foundry UAA, but I will use the UAA as an example to illustrate how it works.

What is a Lightweight Service?

The kind of service that is building the new architectures typically has some or all of these features:

  • HTTP transport. Cheap and easy to deploy, and supported by all cloud platforms.
  • Text-based message content, usually JSON. The emphasis is on readability and sometimes providing easy support to front-end browser and mobile developers.
  • Small, compact messages, and quick responses. Although there is a strong parallel trend of services with streaming responses for “push” data, those are generally not implemented the same way, and HTTP is not the best transport in those cases.
  • REST-ful, or at least inspired by the REST architectural style.
  • Some degree of statelessness, either ‘share-nothing,’ or very careful use of server-side state, to enable horizontal scalability.
  • Interoperability. The consumers of the service might be a dynamic population, completely unknown or unknowable at design time, using a variety of platforms and languages.

No two people or organizations will agree on what to call these services. So, although we need a working definition, it isn’t important what the precise details are. Roy Fielding’s academic work on REST is very influential, but religious wars are fought (and never won) on what it should mean in practice. To avoid being drawn into that, I will be deliberately inclusive and just refer to the services as lightweight services over HTTP, or just “lightweight services.”

What Are the Security Requirements for a Lightweight Service?

It is possible, but unlikely, that a service might be so lightweight that it doesn’t require any security, for example if it is purely informational. If security is required, it will be for the usual reasons, i.e., identity and permission; knowing who is asking for a resource, and calculating if they are permitted to use it. Identity and permission are often known as “authentication” and “authorization” (especially in Spring Security), but using those terms would cause confusion later because “authorization” is part of the OAuth2 domain language and means something different there. “Authorization” is also the name of a standard HTTP header, which is also a bit different as it is more about transporting of data than calculating permission.

So the basic requirements are identity and permissions, and the choices all come down to these nuts and bolts questions:

  • how are identity and permission information conveyed to a service?
  • how is this information decoded and interpreted?
  • what data is needed to make the access decision (user accounts, roles, ACLs, etc.)?
  • how is the data managed, who is responsible for storing and retrieving it?

The rest of this article deals with those questions using a couple of example approaches, including OAuth2, but does not attempt to be a complete description of available features and implementations even in that case.

HTTP Basic Authentication

For a simple system based on shared secrets (e.g., username and password for user accounts), HTTP Basic is something of a lowest common denominator. It is supported on practically all servers natively out of the box and there is ubiquitous support on the client side in all languages. Most, if not all clients, even interpret the authority section of a URL as data to be used for Basic authentication.

As a client, the only thing you need to do for Basic authentication is to include an Authorization header in an HTTP request, composed of the username and password, separated by a colon and then Base64 encoded. E.g., in Ruby (1.9) using RestClient:

require 'restclient'
require 'base64'
auth = "Basic " + Base64::strict_encode64("#{username}:#{password}") 
response = RestClient.get("https://myhost/resource",:authorization=>auth)

On a command line with curl you could do this:

$ curl "https://$username:$password@myhost/resource"

This looks, and is, extremely simple to implement. The only difficulty is in where you get the credentials from (the username and password). If your client is a web application, which is very common for these lightweight services, you might collect the credentials from a user in a simple HTML form.

As long as you ensure that all requests are protected by a secure socket layer, Basic authentication is fine for systems where all the participants can easily share secrets securely. If there is only one resource server (a lightweight service, or a user facing application) this isn’t difficult because the data only needs to be accessed by one component and can even be managed in config files if they are static. For example, the UAA uses Basic authentication for endpoints that are intended to be accessed only by other components in the platform kernel (i.e., machine clients). Some of those endpoints (e.g. /varz) have a password stored in a config file, and some (e.g. /oauth/token) use a database backend to store credentials. For explanations of what those endpoints do in the UAA see the introductory blog or the UAA docs.

User or Client Roles and Permissions

For very simple use cases, authentication is the only form of permission needed. If you can authenticate you can access the resource, otherwise not. But often it is not enough and the service has to be able to make a decision based on finer-grained information about the authenticated party. A simple example of such a decision is role-based access, which is very common, and is also supported out of the box by many server platforms. For instance, the service has a resource that it wants to be available only to users in the ADMIN role. When an authenticated request arrives, the service has to map the authentication to some account data and extract the role assignments. It then checks if the ADMIN role is present and if so grants access, otherwise not.

For role-based access to make sense you need to be able to categorize user accounts. In other words. there have to be at least two classes of users (e.g., USER and ADMIN, which implies at least two users), and someone has to manage the assignments of accounts to roles. This is a good deal more complicated than simple shared password data, but as long as the account data is static it can still be managed in a config file, or in a database otherwise. Crucially, this is still easy to do, as long as the system stays simple and can manage its own account data, or get access to an external system where the data is managed for it.

More complicated access decisions involving different and more detailed fine-grained business data are also possible (even common), but those use cases are beyond the scope fof this article. It’s time to start looking at other things and get down to the OAuth2 discussion.

OAuth2 and Centralized Identity Management

As a system grows and the number of components that need access to authentication services and to user account data increases, or the user account data is changing frequently or growing rapidly, the simple approaches to security will start to become a maintenance problem. What is needed is a centralized approach to identity management, and a service for the whole system that can provide and manage that data in a secure way. This is where standards like OAuth2 come into play. They introduce a new layer in the architecture, and some extra complexity that can be hard to get to grips with at first, but the benefits will be worth it in many cases.

Quick Introduction to OAuth2

OAuth2 is a protocol enabling a Client application, often a web application, to act on behalf of a User, but with the User’s permission. The actions a Client is allowed to perform are carried out by a Resource Server (another web application or web service), and the User approves the actions by telling an Authorization Server that he trusts the Client to do what it is asking. Clients can also act as themselves (not on behalf of a User) if they are permitted to do so by the Authorization Server.

The most common way for a Client to present itself to a Resource Server is using a bearer token, as covered in the core OAuth2 specification. The token is obtained from the Authorization Server, with the User’s approval if necessary, and stored by the Client. Then when it needs to access a Resource Server the Client sends a special HTTP header in the form:

Authorization: Bearer <TOKEN_VALUE>

The token value is opaque to a client, but can be decoded by a Resource Server so it can check that the Client and User have permission to access the requested resource.

Common examples of Authorization Servers on the Internet are Facebook, Google, and Cloud Foundry all of which also provide Resource Servers (the Graph API in the case of Facebook, the Google APIs in the case of Google, and the Cloud Controller in the case of Cloud Foundry).

OAuth2 and the Lightweight Service

OAuth2 is, at its heart, an authentication protocol for lightweight services, which are Resource Servers in the domain language of the specification. A Client application that wants to access a protected resource sends an authorization header, a bit like in the Basic authentication case. E.g., in Ruby:

auth = "Bearer #{token}"
response = RestClient.get("https://myhost/resource",:authorization=>auth)

or on the command line:

$ curl -H "Authorization: Bearer $TOKEN" https://myhost/resource

As with the Basic authentication, the mechanics are extremely simple, and that is one thing that makes OAuth2 bearer tokens attractive for clients of lightweight services.

The token is opaque to the Client, but the Resource Server can decode it into some finer grained information about the Client and the level of access that the token represents. It then uses this information to make an access decision. This is not the only feature of OAuth2, but on its own makes OAuth2 a lot more powerful than simple Basic authentication: The token itself carries more information than a Basic header.

A typical minimal set of information in a token would be the Client ID, a target Resource ID and a set of approved scopes (more on those later). Normally the Resource Server has an ID, and it should check that it matches the one in the token in order to prevent token misuse. Beyond that, it is entirely up to the Resource Server what to do with the decoded token data. If the Resource Server is able to coordinate with the Authorization Server, it can arrange for specific fine-grained data to be encoded in the token, relating to the access decision it wants to make. For example the Authorization Server might include role assignments that are recognized by the Resource Server. Tokens could, and do, also contain other information, like a unique identifier for the current user (if there is one).

The UAA stores group assignments in its native user data, and those show up in the access tokens as scopes. The scope values themselves in the UAA are period-separated, but it is up to the Resource Server to interpret them any way it needs. For example, a Resource Server calling itself ‘dashboard’ might change its access decision based on whether it finds a scope ‘dashboard.user’ or ‘dashboard.admin’, and those are the names of groups in the user accounts. These semantics are not part of any standard specification, but OAuth2 leaves them up to implementations to interpret according to their need, so the UAA takes advantage of that.

The Role of the Client Application

For a Client, obtaining a token makes things slightly complicated, and in this case it is usually not enough just to know a username and password. Also, one of the key reasons for OAuth2 to exist is so that Client applications do not need to collect user credentials (as they did with Basic authentication). Here is where the learning curve for OAuth2 gets steeper.

The Client has to obtain an access token, and to do that it has to be pre-registered with the Authorization Server, and it has to authenticate itself at the token endpoint. The UAA uses Basic authentication for this endpoint, as suggested by the OAuth2 specification. If a Client is not acting on behalf of a User, the Authorization Server might allow it to obtain tokens in its own right, directly from the token endpoint. If a client with id “myclient” has been registered with the relevant authorized grant type you could obtain a token like this:

$ curl "https://myclient:mysecret@uaa.cloudfoundry.com" -d grant_type=client_credentials -d client_id=myclient

The result would be JSON containing an access token and some meta data, for example:

{ 
  access_token: FUYGKRWFG.jhdfgair7fylzshjg.o98q47tgh.fljgh,
  expires_in: 43200,
  client_id: myclient,
  scope: uaa.admin 
}

(This is not a valid token, nor is it a valid client id for the UAA on cloudfoundry.com, just dummy data for illustration purposes.)

The example so far has been for a Client authenticating and obtaining an access token in its own right, which the specification calls the Client Credentials Grant Type. Another grant type is Authorization Code. This is the most common and one that allows the Client to delegate the authentication of Users. Application providers then need to educate Users that they should never enter their credentials in any other application than the Authorization Server (or its trusted delegates), so that a malicious Client application has less chance of tricking a User into revealing his credentials. This use case is one of the main reasons to use OAuth2 and a big driver of the OAuth2 specification itself.

The Authorization Code token grant proceeds in four steps:

Sequence diagram, auth-code-flow, with an already authenticated user (steps 2-4):

  1. Authorization Server authenticates the User any way necessary. This step is required but is specific to the Authorization Server implementation and not part of the OAuth2 specification (e.g., it is different for Google and Cloud Foundry).
  2. Client starts the authorization flow and obtains approval from the Authorization Server to act on the User’s behalf. The approval is required, but the details are not specified in the OAuth2 specification.
  3. At this point, if successful, the Authorization Server issues an authorization code (opaque one-time token). This step, and the next one, are described in detail in the OAuth2 specification.
  4. Client exchanges the authorization code for an access token.

Because there are multiple steps here and normally the first two would require a short conversation with the User, the Authorization Server has to direct the flow through the use of HTTP redirects (status code 302 and a Location header). The Client specifically asks for a redirect to itself in order to obtain the authorization code at step 3. One of the security threats in OAuth2 is a malicious Client stealing tokens by asking for an arbitrary redirect, so Authorization Servers protect against this by requiring Clients to register one or more redirect URIs.

The Authorization Server is so called because it provides an interface for users to confirm that they authorize the Client to act on their behalf (step 2 above). The specification wisely leaves the details entirely up to the implementation, so how the authorization (a.k.a approval) is obtained is unspecified. The UAA, and the Spring Security Oauth2 project that it builds on, provide a simple form-based interface in the general case, but also allow auto-approval of certain clients (e.g., if they are deemed by the Authorization Server owners to be part of the platform).

Client Registration and Scopes

The OAuth2 specification mentions Client registration explicitly and it is an important part of the protection against various security threats. It is also the first point of contact for most application developers with OAuth2, e.g., it’s a pre-condition if you want to look at Google calendar data, or manage the applications deployed on Cloud Foundry. There are some core elements of a Client registration required by the specification (an identifier and a secret if the Client is trusted), and several that are recommended (legal scope values, and registered redirect URIs). Authorization Servers often require additional information, describing the application and the owner of the registration.

The scope values are the hardest to understand for a newbie because they are arbitrary strings and don’t necessarily mean anything to the Client at first. Fortunately for the User, the Authorization Server can usually find a default set of scopes from somewhere, and usually knows how to render the values in a way that a User will understand (e.g., from Facebook, “do you allow this application (<URL>) to access your personal data, including email address and photos”). But for a hapless Client owner it can be quite hard to discover the valid scope values and get them registered. In the end, the Client might have to send a speculative request and look at the response from the Resource Server: The specification recommends that valid scope values are included in the HTTP 403 response as part of the WWW-Authenticate header.

You can find out (some of) the valid Google API scopes in the OAuth2 playground–they are mostly URLs starting with “https://www.googleapis.com” (but some are not, maybe the older ones). The API docs themselves (i.e., the Resource Servers) are very thin on scope documentation.

In the case of the UAA there is a UAA Security Model document that lists the known scope values as used by the UAA itself and the Resource Servers that it knows about in the Cloud Foundry platform (e.g., the Cloud Controller). In theory, though, and this is quite a powerful feature of OAuth2, there is nothing to stop a Client registering any value as a scope, and a Resource Server that is completely unknown to the Authorization Server can accept that value. To protect against malicious clients, the UAA extracts a resource ID dynamically from a scope value (scope up to the last period is a resource ID) and includes it in the access token as the “aud” (audience) field. We hope that eventually this will provide an opportunity for the platform to be used as a general purpose OAuth2 provider for all applications, not just those that belong to or consume the platform.

The UAA on cloudfoundry.com at present is only accepting Client registration by a manual process through the Product Management group in Cloud Foundry, but if you would like to deploy a Client using, or a Resource Server accepting, cloudfoundry.com bearer tokens, feel free to contact us.

Authentication and the Authorization Server

OAuth2 on its own does not provide an authentication protocol for the Users of the Authorization Server. It strongly suggests that Client applications should use Basic authentication for accessing the token endpoint, but it says nothing about the authentication of Users when their approval is needed for a token grant (only that they must be authenticated). This is a good thing because it makes authentication completely orthogonal to the approval process, and Authorization Servers are free to implement the authentication any way they choose.

Out of the box, the UAA supports form-based authentication backed by a database of user accounts. But because authentication is not part of the OAuth2 specification, it is easy to modify to support other authentication mechanisms or data sources. For example, with a few lines of configuration you could switch from form-based authentication to Open ID authentication with Google or Yahoo, or to an enterprise directory service (e.g., Active Directory or OpenLDAP) for the data store.

The authentication logic in the UAA can also be extracted out into a completely separate server component, so it can be independently developed and styled. There is a sample login server which allows authentication either with Open ID (Google, Yahoo, etc.) or using an HTML form and a password in the UAA database. Modifying it to support a SAML IDP such as VMWare Horizon or an AD back end for the user account data is trivial because both are well supported by the underlying Spring Security stack.

Alternatives

We have seen that there is a trade-off between the complexity of OAuth2 and a simpler system based purely on shared secrets and a shared user account database. There are other alternatives that are equally or more complex than OAuth2, the main example being SAML. SAML and OAuth2 share a lot of aims, but the implementation is different, and the touch points for developers are very different. SAML is extremely rich and has many features and offshoots that users find indispensable, and it is by default very secure. It is also hard to set up and configure, and often leads to very large amounts of XML being sent with each HTTP message (often so much that it would dwarf the average JSON payload). This last point is probably the thing that puts people off SAML for the sort of lightweight services discussed here, but there is no reason, in principle, why it could not be used.

In environments where SAML is already well established there are also ways to combine it with OAuth2. For example, the specifications allow for a SAML grant in which a client exchanges a SAML assertion for an OAuth2 token, which can then be used as if it came from any other source.

Another alternative to OAuth2 is to write your own system with the same or a subset of features. Many systems have been forced to adopt this approach just because the specifications have been rather long in gestation. There’s nothing intrinsically wrong with doing it yourself, especially if your needs are simple, but many people feel that with security especially there is value in using a standard protocol. Security is very high profile these days and any mistake you make with a non-standard implementation is going to reflect badly if (or rather when) things go wrong.

In Conclusion

So what’s the punchline? Why would you use OAuth2 to secure a lightweight service? It certainly isn’t the simplest approach you could possibly adopt, so you have to be aware of the benefits that would lead you to accept the extra complexity. OAuth2 is well suited to lightweight services in medium to large distributed systems, where User and Client account data need to be centralized, and where you need some control over the expiry and validity of access tokens. The fine-grained information that can be packed into an access token (and which is derived from the centrally managed account data) provides significant benefits over a simple protocol like HTTP Basic authentication. Fortunately, the complexity can also be hidden by client libraries (e.g., Spring Security OAuth2 for Java, or the UAA Gem or Signet for Ruby, or JSO for JQuery). In addition, since OAuth2 is a commonly used standard these days, he number and quality of client libraries is increasing steadily. To put things round the other way, I wouldn’t bother with my own OAuth2 provider if my system only had one or two Resource Servers, or if Client applications never had to act on behalf of a User. I would consider using something simple like Basic authentication, and when I needed more I might switch to someone else’s OAuth2 provider (e.g., Cloud Foundry) if it supported the features I needed.

Naturally, this short article is not going to answer all the questions that arise about OAuth2 and identity management. If you want more information, join the community: check out the source code of the UAA and hang out on the Spring Security OAuth Forum or the Cloud Foundry Developers Group.

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Polishing Cloud Foundry’s Ruby Gem Support

The Cloud Foundry team has released new features to improve management of Ruby gems in apps running on CloudFoundry.com. These features include support for using Git URLs in Gemfiles, handling of the BUNDLE_WITHOUT environment variable, and platform specification to control the gem installation process. With these improvements, it is now easier than ever to get your existing Ruby projects up and running on CloudFoundry.com.

History

In 2003, RubyGems was launched as Ruby’s package manager. Six years later, Rubyists began using Bundler–a means for managing and installing gem dependencies in the context of an application. The combination of these two technologies has given developers the ability to run Ruby applications without having to worry about the specific gem version, gem source, or the platform that is available on the server.

In this blog, we will review the changes in the Cloud Foundry code that provide better support for gems. We will discuss using Git URLs as a gem source, how you can use BUNDLE_WITHOUT to manage gem groups, and how Cloud Foundry installs only the platform specific gems that make sense.

Using Git URLs as a Gems Source

Most of the time, developers use default “rubygems” source to fetch gems from the official Ruby Gems repository. Alternatively, Bundler supports Git source URLs in order to associate a gem name and version with a certain Git repository. In this latter scenario, Bundler will automatically clone the latest version of a gem and install it. As of today, CloudFoundry.com fully supports using these Git URLs.

How does it work?

In the same way that Bundler installs gems from a Git source URL, resolving Git branches and references, Cloud Foundry locates Git dependencies in the Gemfile.lock, fetches the source code, and checks out the specified revision. Next, Cloud Foundry will find all of the gemspecs, build the gems and inject them into the application exactly where Bundler expects to see them. When the application gets started via “bundle exec,” Bundler picks up all installed dependencies as usual.

To optimize the staging process, CloudFoundry.com also caches fetched Git sources. For example, if you reference the Rails Git URL, CloudFoundry.com clones the repository and caches it in the local filesystem, so the next request for Rails will use the cache. If a requested revision is missing from the cache, there is no need to clone from scratch because only the missing objects will get downloaded from the original repo.

Example

Let’s take a look at the application padrino shortener-demo. This demo is using the latest version of Padrino (a Sinatra-based web framework). As we can see in application Gemfile, gem padrino is requested to be provided from GitHub:

...
gem 'padrino', :git => 'git://github.com/padrino/padrino-framework.git'
...

The padrino gem Git revision was locked in Gemfile.lock.

...
GIT
remote: git://github.com/padrino/padrino-framework.git
revision: 17c748f8173185e57f9254829f53ee34327fa90d
specs:
padrino (0.10.1)
...

As we push this application, we provide the MongoDB service.

$ vmc push shortener
Would you like to deploy from the current directory? [Yn]:
Detected a Rack Application, is this correct? [Yn]:
Application Deployed URL [shortener.cloudfoundry.com]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [128M]:
How many instances? [1]:
Bind existing services to 'shortener'? [yN]:
Create services to bind to 'shortener'? [yN]: y
1: mongodb
2: mysql
3: postgresql
4: rabbitmq
5: redis
What kind of service?: 1
Specify the name of the service [mongodb-9e641]: mongodb-shortener
Create another? [yN]:
Would you like to save this configuration? [yN]:
Creating Application: OK
Creating Service [mongodb-shortener]: OK
Binding Service [mongodb-shortener]: OK
Uploading Application:
Checking for available resources: OK
Processing resources: OK
Packing application: OK
Uploading (38K): OK
Push Status: OK
Staging Application 'shortener': OK
Starting Application 'shortener': OK

Now, if we check application logs, we can see that padrino was provided to the application among other gems:

$ vmc logs shortener
====> /logs/staging.log 3.2.3 <====
….
Need to fetch mongo-1.3.1.gem from RubyGems
Adding mongo-1.3.1.gem to app...
Need to fetch bson-1.3.1.gem from RubyGems
Adding bson-1.3.1.gem to app...
Need to fetch tzinfo-0.3.29.gem from RubyGems
Adding tzinfo-0.3.29.gem to app...
Need to fetch padrino-0.10.1.gem from Git source
Adding padrino-0.10.1.gem to app...
Need to fetch http_router-0.10.2.gem from RubyGems
Adding http_router-0.10.2.gem to app...
Need to fetch rack-1.3.2.gem from RubyGems
Adding rack-1.3.2.gem to app...
...

And now we can generate a shortened URL and track its visitors.


There may be situations where using the official published gem versions is not enough, such as using the current HEAD of the project, or specific branch, tag or fork. Cloud Foundry supports Git URLs in Gemfile, so it’s easy to point to a Git repo with the exact version of the library you need, and it will be downloaded and packaged as a part of your Cloud Foundry app.

Using BUNDLE_WITHOUT to Manage Gem Groups

Gemfiles support the grouping of gems so that a test server, for example, can get a different group of gems than a production one. The second feature we are announcing is that Cloud Foundry allows developers to take advantage of these groups by using the BUNDLE_WITHOUT environment variable, just as you would locally. Setting BUNDLE_WITHOUT causes Cloud Foundry to skip installation of gems in excluded groups.

Example

BUNDLE_WITHOUT is particularly useful for Rails applications, where there are typically “assets” and “development” gem groups containing gems that are not needed when the app runs in production.

Let’s take a look at an example. Spacely is a Rails 3.2 application that provides image upload via drag and drop. The Gemfile contains several gems in a group called “assets.”

...
group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer', :platform => :ruby

  gem 'uglifier', '>= 1.0.3'
end
...

Let’s push the application to CloudFoundry.com without the gems in the “assets” group. We need to run “bundle install” first to generate a Gemfile.lock, which Cloud Foundry requires. Spacely includes a VMC manifest.yml file, so we can easily push the app without the full interaction. Notice that we push the app with the “–no-start” flag, so we can set the BUNDLE_WITHOUT environment variable before starting the application. We will make this step easier in the new version of VMC by enhancing the manifest support.

$ bundle install
$ vmc push --no-start
Would you like to deploy from the current directory? [Yn]: 
Pushing application 'spacely'...
Creating Application: OK
Creating Service [spaceltdb]: OK
Binding Service [spaceltdb]: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (6M): OK   
Push Status: OK

Now let’s set BUNDLE_WITHOUT and start the application:

$ vmc env-add spacely BUNDLE_WITHOUT=assets
Adding Environment Variable [BUNDLE_WITHOUT=assets]: OK
$ vmc start spacely
Staging Application 'spacely’: OK                                               
Starting Application 'spacely': OK

Now, if we check application logs, we can see that gems such as “sass-rails” are not installed.

$ vmc logs spacely
====> /logs/staging.log <====
….
Adding carrierwave-0.6.1.gem to app...
Adding activesupport-3.2.6.gem to app...
Adding i18n-0.6.0.gem to app...
Adding multi_json-1.3.6.gem to app...
Adding activemodel-3.2.6.gem to app...
Adding builder-3.0.0.gem to app...
Adding fog-1.5.0.gem to app...
...

Cloud Foundry also supports the exclusion of multiple groups. For example, if Spacely included a “test” group, we could have excluded gems in both assets and tests with “vmc env-add spacely BUNDLE_WITHOUT=assets:tests”.

Excluding Gems by Platform

Bundler allows developers to use the “platforms” method in Gemfiles to specify that a gem be used on particular platforms. This is the final piece of polish for gems that we are adding today. Cloud Foundry will skip the installation of gems on irrelevant platforms, as it should.

The following Gemfile specifies that the rb-inotify gem should be used in non-Windows environments, while three other gems are for Windows only. When this app is deployed to CloudFoundry.com, only the rb-inotify gem will be installed.

# Unix Rubies (OSX, Linux)
platform :ruby do
  gem 'rb-inotify'
end

# Windows Rubies (RubyInstaller)
platforms :mswin, :mingw do
  gem 'eventmachine-win32'
  gem 'win32-changenotify'
  gem 'win32-event'
end

The “platforms” designation can also be used to selectively install gems based on Ruby versions. For example, certain gems can be excluded when switching between Ruby 1.8 and Ruby 1.9.

Support for Windows Gemfiles

When a Gemfile.lock is generated on a Windows machine, it often contains gems with Windows-specific versions. This results in versions of gems such as mysql2, thin, and pg containing “-x86-mingw32.”

For example, a Gemfile that contains the following:

gem ‘sinatra’
gem ‘mysql2’
gem ‘json’

When you run “bundle install” with the above Gemfile on a Windows machine, it would result in the following Gemfile.lock:

GEM
  remote: http://rubygems.org/
  specs:
    json (1.7.3)
    mysql2 (0.3.11-x86-mingw32)
    rack (1.4.1)
    rack-protection (1.2.0)
      rack
    sinatra (1.3.2)
      rack (~> 1.3, >= 1.3.6)
      rack-protection (~> 1.2)
      tilt (~> 1.3, >= 1.3.3)
    tilt (1.3.3)

PLATFORMS
  x86-mingw32

DEPENDENCIES
  json
  mysql2
  sinatra

Notice the “-x86-mingw32” in mysql2′s version number. Previously this would cause a failure on deployment, as Cloud Foundry would attempt to install the Windows-specific gem. However, now Cloud Foundry will install the Ubuntu-friendly version of these gems without requiring any modification to Gemfile.lock. Developers can seamlessly migrate their app between local Windows machines and CloudFoundry.com.

Conclusion

The ability to use Git URLs as a dependency source and specify which gem groups should be installed depending on the platform provides greater flexibility for Ruby developers. The work we have done to enhance gem and bundler support is part of our commitment to providing a Platform as a Service that meets real needs of Rubyists building and deploying applications in the cloud. Follow us on Twitter at @cloudfoundry and let us know how these new features are working for you!

- Jennifer Hickey and Maria Shaldibina
The Cloud Foundry Team

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Experimental Clojure Support in Cloud Foundry

We have been working on making it easier to deploy Clojure apps to Cloud Foundry [1]. Clojure is a functional language that runs on the JVM that allows rapid prototyping of applications while offering great support for integration with Java libraries. Many interesting projects–for example, Twitter’s own realtime processing framework Storm–are written in Clojure.

To help to run Clojure apps in Cloud Foundry, we have written a library called claude that you can use to easily access the different services offered by Cloud Foundry, like MongoDB or RabbitMQ.

Now let’s see how you can start deploying your Clojure apps to Cloud Foundry.

Deploying Your Clojure Apps to Cloud Foundry

We assume that you are using leiningen for your Clojure projects.

First you will add the latest version of claude into your project dependencies:

[claude "0.2.1-SNAPSHOT"] Then run lein deps to obtain the project dependencies.

Once you have your project set up then you need to declare your project main function:

:main clojure-demo.server

See this project project.clj file for more details.

Then on your main namespace you need to add a :gen-class like in this example:

(ns clojure-demo.server
  (:gen-class)
  (:require [noir.server :as server]
            [claude.core :as cf]))

If you are creating a web app then another tweak you need to perform is to inform your app of the port in which it has to run. You can obtain the port from the VMC_APP_PORT environment variable. Here’s an example:

(defn -main [& m]
  (let [mode (if (cf/cloudfoundry?) :prod :dev)
        port (Integer. (get (System/getenv) "VMC_APP_PORT" "8080"))]
    (server/start port {:mode mode
                        :ns 'clojure-demo})))

Also, as you can see in that code snippet, we are using the claude.core/cloudfoundry? helper to see if we are running in the cloud. In that case, we can set the web app environment to :prod.

So far we have a basic Clojure project that can be run from a .jar file. Let’s create that jar file and deploy it to Cloud Foundry. We asume that you are already logged into Cloud Foundry using vmc. Run the following commands inside your Clojure project folder:

mkdir cf
lein uberjar
cp target/clojure-demo-0.1.0-SNAPSHOT-standalone.jar cf/
cd cf

There we created a new folder to hold our app .jar file. Now we are ready to deploy it. In this case, I will bind one instance of each service provided by Cloud Foundry. Therefore, you will see a lot of output in the following transcript. Let’s start with vmc push:

vmc push
Would you like to deploy from the current directory? [Yn]: Y
Application Name: clojure-demo
Detected a Standalone Application, is this correct? [Yn]: Y
1: java
2: java7
3: node
4: node06
5: node08
6: ruby18
7: ruby19
Select Runtime


: java7
Selected java7
Start Command: java $JAVA_OPTS -cp clojure-demo-0.1.0-SNAPSHOT-standalone.jar clojure_demo.server

Up to here we told vmc that we are deploying a standalone application, that the runtime is java7 and we provided our startup command. Make sure to change the application name on your own deployment.

Let’s continue our deployment:

Application Deployed URL [None]: ${name}.${target-base}
Memory reservation (128M, 256M, 512M, 1G, 2G) [512M]: 512
How many instances? [1]: 1

If we are deploying a web application, then we need to provide the URL for our app. In our case we let vmc build the URL based on our application name. In this case it will be under http://clojure-demo.cloudfoundry.com. Keep in mind that you only need a URL if you are deploying a web app.

Now let’s create and bind one instance of each service type to our app:

Bind existing services to 'clojure-demo'? [yN]: N
Create services to bind to 'clojure-demo'? [yN]: y
1: blob
2: mongodb
3: mysql
4: postgresql
5: rabbitmq
6: redis
What kind of service?: 1
Specify the name of the service [blob-9dcdc]:
Create another? [yN]: y
1: blob
2: mongodb
3: mysql
4: postgresql
5: rabbitmq
6: redis
What kind of service?: 2
Specify the name of the service [mongodb-cb862]:
Create another? [yN]: y
1: blob
2: mongodb
3: mysql
4: postgresql
5: rabbitmq
6: redis
What kind of service?: 3
Specify the name of the service [mysql-2358b]:
Create another? [yN]: y
1: blob
2: mongodb
3: mysql
4: postgresql
5: rabbitmq
6: redis
What kind of service?: 4
Specify the name of the service [postgresql-de020]:
Create another? [yN]: y
1: blob
2: mongodb
3: mysql
4: postgresql
5: rabbitmq
6: redis
What kind of service?: 5
Specify the name of the service [rabbitmq-3422d]:
Create another? [yN]: y
1: blob
2: mongodb
3: mysql
4: postgresql
5: rabbitmq
6: redis
What kind of service?: 6
Specify the name of the service [redis-29cde]:
Create another? [yN]: N

Note that we did this for our example’s sake. Your app might not need as many services or you might choose to not use any of them. It’s all up to you.

Now we probably want to save this configuration inside a manyfest.yml file so we don’t need to type all that again the next time we deploy our app from scratch.

Would you like to save this configuration? [yN]: y
Manifest written to manifest.yml.

Now vmc will stage your app and it will start it automatically:

Creating Application: OK
Creating Service [mongodb-cb862]: OK
Binding Service [mongodb-cb862]: OK
Creating Service [mysql-2358b]: OK
Binding Service [mysql-2358b]: OK
Creating Service [postgresql-de020]: OK
Binding Service [postgresql-de020]: OK
Creating Service [blob-9dcdc]: OK
Binding Service [blob-9dcdc]: OK
Creating Service [rabbitmq-3422d]: OK
Binding Service [rabbitmq-3422d]: OK
Creating Service [redis-29cde]: OK
Binding Service [redis-29cde]: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (5M): OK
Push Status: OK
Staging Application 'clojure-demo': OK
Starting Application 'clojure-demo': OK

You can access a demo app here.

While this seems to be a little long, in fact we detailed every single step to get you up and running. To recap this is what we need did:

  • Add the claude dependency to your project.
  • Add a (:gen-class) to your main namespace. This is a Clojure/Java requirement
  • Generate your uberjar.
  • Deploy your app providing a start up command

And that’s it! Now create a free account at Cloud Foundry and let’s see your awesome Clojure apps deployed to Cloud Foundry!

1 *NOTE: At the time of this writing Clojure is unofficially supported at Cloud Foundry. *

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Cloud Foundry Visits India

Cloud Foundry Open Tour developer events are designed to help technologists behind the industry’s leading open Platform as a Service to meet and exchange ideas. Last week, we visited India with a huge success–about 1,100 developers attended a series of Cloud Foundry sessions and a hackathon. Developers learned about the open source Cloud Foundry Platform as a Service and how it supports multiple services, frameworks and IaaS layers.

The Cloud Foundry Open Tour is not only a developer event for professional developers; it also attracts students who ended up building some great apps in the hackathon. There were a few professors from technology schools trying to understand how Cloud Foundry fits into the larger cloud ecosystem. We also saw a healthy media presence and coverage before, during and after the event.

We were really impressed by the dedication the developers showed by arriving at 9:00 a.m. and staying on until 10:00 pm in Bangalore and Pune. The enthusiasm was also evident in the overwhelming number of requests to participate in the morning sessions and evening hackathon, even after the seats had sold out.

The five session speakers, who came from various geographies including the US, Singapore and India, deserve a big thank you. From VMware were Chris Richardson, Josh Long, Raja Rao and Rajdeep Dua. Guest speakers included Hugues Malphettes, Senior Software Architect at Intalio, and industry spokeserson Janakiram MSV.

What We Covered

Morning Sessions
We started the morning sessions with keynote delivered by Niranjan Maka and Chris Richardson. Niranjan covered the VMware product strategy and portfolio, and the concept of the software-defined data center. Chris’s talk focused on the history of Cloud Foundry and various aspects of open source PaaS. This was following by a very well-received Node.js session by Raja Rao. Josh covered the Spring framework and Spring integration with Cloud Foundry.

Chris came back on stage to do his architecture session on decomposing apps for scalability. After lunch, Hugues from Intalio showcased Intalio|Create, which is an innovative way of building business applications. It is built using Cloud Foundry and can be deployed on public as well as private clouds. Rajdeep had a session on the Play Framework and its support in Cloud Foundry. The morning session was wrapped up with Janakiram’s talk on deploying .NET applications on Iron Foundry. Developers responded very favorably to the choice of frameworks available with Cloud Foundry.

We wrapped up the morning session and doing an iPhone 4S raffle for the attendees.

Evening Hackathon
The evening hackathon started with an hour-long boot camp on how to get started with Cloud Foundry using vmc and the Spring Source Tool Suite (STS). This was run in a similar manner in Bangalore and Pune.

Participants pushed over 185 Hello World apps to win t-shirts. This was significant because just a few hours back these same developers were totally new to Cloud Foundry and now they were pushing their applications.

Boot camp was followed by a two-hour hackathon where developers formed teams,  hacked over their ideas and published a total of 19 apps to cloudfoundry.com.

Hackathon Winners

The winner in Bangalore was a group of students from P.E.S. Institute of Technology who built a GRE test helper app. This app sends an SMS to a number for an English word. Then the app talks to a Word Link service and returns English word’s definition.

Winners in Pune built an online exam results portal using Ruby on Rails. Another runner-up built a social sentiment analysis service using Spring MVC, Neo4j and Twitter4J. Another winner built a chat application.

Quotes from Bloggers and Attendees

A developer conference’s pulse can be gauged from what audience has to say or write about it.
Cloudstory.in: “The best thing of the event was the Hackathon that was scheduled in the evening. In both the cities the developers stayed till late evening to deploy live applications on cloudfoundry.com and appfog.com. It was exciting to see hundreds of developers coding away in their favorite language and deploying the application on a platform that they experienced only a few hours ago. That only shows how simple it is to get started on Cloud Foundry.”
One of the developer attendees said: “Just wanted to send a THANK YOU and tell you how much I enjoyed the Cloud Foundry Pune Open Tour 2012. You people did a great job in putting it all together and I especially enjoyed my first ever hackathon. It was indeed great experience.”

Presentation Slides

Slides for the talks can be found at the following links:

The Open Tour Continues

It was a great experience interacting with developers in Pune and Bangalore, helping them learn about Cloud Foundry. Since the Cloud Foundry Open Tour 2012 is a global series of one day developer events, stay tuned for more announcements on new dates and locations.

Rajdeep Dua, the Cloud Foundry Developer Relations Team

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Cloud Foundry Integration for Eclipse Now Supports Standalone Java Applications and Java 7

A new release of Cloud Foundry Integration for Eclipse is available which features the ability to publish standalone Java applications to CloudFoundry.com using either Java 6 or Java 7. Java 7 is also now supported for Grails, Java Web and Spring applications. Standalone applications can only be published to Cloud Foundry instances that support standalone applications such as CloudFoundry.com.

The new integration (version 1.2.0)  allows users to publish standalone Java applications from within Eclipse Indigo JEE or SpringSource Tool Suite (STS) version 2.9.0 or higher.

The previous Cloud Foundry plugin (1.1.0) introduced tunneling support for data services, and further improvements to service tunneling are also available as part of 1.2.0.

Follow the documented instructions to install the Cloud Foundry Integration for Eclipse. If you had previously installed Cloud Foundry plugin 1.0.0 or 1.1.0 in Eclipse or STS, the update will be automatically detected or you can manually check for updates in the IDE. Note that updates for older Cloud Foundry plugins prior to 1.0.0 are not supported. Old versions prior to 1.0.0 must first be uninstalled before installing 1.2.0.

Enabling Standalone Support

Java projects in Eclipse can now be published to CloudFoundry.com by enabling Cloud Foundry standalone support on the Java project, and then dragging and dropping them like any other supported application type (Grails, Spring) into either a Cloud Foundry server instance in the Servers view or into the Applications section in the server editor.

To make your Java project publishable to CloudFoundry.com, simply select it in either the Project or Package Explorer, right-click and choose Configure -> Enable as Cloud Foundry Standalone App.

To remove the configuration, select  Configure -> Disable as Cloud Foundry Standalone App.

A Java standalone application can be published in just a few simple steps:

1. Right-click on the Java project and enable standalone support.

2. Drag and drop the application into either the Servers view or server editor for a CloudFoundry.com server.

3. Complete the Application wizard that opens, much like publishing any other supported application type.

Configuring a Standalone Java Application

Once a standalone Java application is dragged and dropped into either a CloudFoundry.com server instance in the Servers view, or the server’s editor, an Application wizard is opened allowing a user to configure the application details like the application name and runtime type.

Both Java 6 and Java 7 are supported for standalone applications and a user can select either one from the “Runtime” widget shown above.

In many cases, the standalone support will automatically detect a Java type with a main method, and the application can be deployed from the first page of the wizard. If no main method type was detected, or if a user wants to change the automatically resolved type, clicking “Next” will display a page where the Java start command can be set.

Unlike other supported applications like Grails or Spring, URLs are optional for standalone Java applications. However, a start command is required.

A user has the option of specifying the start command in one of two ways:

1. Java: A JVM Java start command with recommended default options set to “$JAVA_OPTS -cp lib/*:.” and a Java type with a main method. The lib folder for the class path option need not exist in the Java project. It is automatically created remotely in the Cloud Foundry server and it is where all jar project dependencies, excluding the JRE dependency, are published.

2. Other: A full user-defined start command, which may include the name of a script file.

For the first option, a user can use the built in Java content assist in the Main Type text widget to select a Java type.

Alternately, the Browse button can be clicked to open a Java type browse dialogue.

If selecting Other, the full start command can be specified, like a script file as seen below.

Once published, the standalone application can be managed from the Cloud Foundry server editor like other application type, including starting, stopping, restarting and update restarting, and removing the application, as well as changing the number of application instances and memory settings. In addition, the published resources can be browsed by clicking on Remote Systems View in the server editor.

Java Application Dependencies

All standalone dependencies, with the exception of the JRE dependency, are automatically resolved and published to a remote “lib” folder relatively to the application folder in the Cloud Foundry server. The lib folder need not exist in the Java application before publishing it.

For example, for a Java Maven project, all Maven dependencies are published to the remote lib directory relative to the application.

The Cloud Foundry standalone support determines what application resources to publish to the cloud server based on the configuration defined in the project’s Java Build Path. Any resources that the application requires, including Java source output or target folders, binaries, and XML and script files, need to be listed in the project’s Java Build Path. The Java Build Path can be accessed by right-clicking on the Java project and selecting Build Path -> Configure Build Path…

In addition, the standalone support automatically skips any test source folders, even when listed in the project’s Java Build Path. Output targets for sources folders containing the pattern “src/test” are skipped.

Java 7 Support for Other Application Types

In addition to supporting Java 7 for standalone applications, Cloud Foundry Integration for Eclipse and STS now supports Java 7 for Grails, Spring, Java Web and Lift for CloudFoundry.com. For other cloud servers, Java 6 is still the default runtime type. Java 7 is only shown if the server supports it.

Cloud Foundry Integration for Eclipse 1.2.0 can be installed or updated from the official update site:

http://dist.springsource.com/release/TOOLS/cloudfoundry/

- The Cloud Foundry Team

Don’t have a Cloud Foundry account yet? Signup for free today

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

How We Built AppFog Using Cloud Foundry

The value proposition of using the cloud is that “things will be easy this way.” Building and operating large scale clouds, however, is rarely easy. As Mark Lucovsky said in his recent interview, “Who said large scale distributed systems are simple?” While solutions like Cloud Foundry make building core cloud technology less daunting, it’s still not easy.

In this guest blog, Lucas Carlson, Founder and CEO of AppFog, illustrates the story of how AppFog was built using Cloud Foundry open PaaS technology and what they learned along the way.

Core Cloud Technology is Hard

Running a simple Cloud Foundry-based service is not very hard. Check out Micro Cloud FoundryTM.

Building one that is suitable for production and enterprise workloads is fairly hard.

Building a Cloud Foundry-based service with one API end-point to run in 6+ different availability zones on 4+ independent infrastructure vendors and that is suitable for production and enterprise workloads, at scale and in general availability? Now that is really hard.

Hitting the Ground Running with Cloud Foundry

As you can imagine, ever since AppFog announced GA, people have been asking how we did it. How did we figure out how to scale up a public cloud offering for Cloud Foundry that delivers one interoperable interface across multiple clouds, multiple availability zones and multiple vendors?

First: The Cloud Foundry codebase is really very good. In choosing to build using Cloud Foundry we eliminated a number of the potential serious challenges and major time sinks likely with this sort of project.

Second: The leverage that we were able to gain from the additional tools, code and services from within the Cloud Foundry ecosystem dramatically accelerated our development.

Third: Having a non-Cloud Foundry-based public PaaS already in GA and already at scale was a massive boost for us. We had the operational experience in-house needed to pull off a great PaaS.

AppFog’s ops experience was invaluable for us. Although PaaS is closely tied to the NoOps movement, NoOps doesn’t mean no ops, it only means no ops for the developer. As anyone who has run Cloud Foundry knows, a lot of ops is necessary and essential to running PaaS.

And most importantly, we had a vibrant community of tens of thousands of developers (the users of PHP Fog) that we could consult to help us define, test, and evolve AppFog through private beta to Public Beta and now to GA.

We Listened and Delivered

It was this community that helped us figure out what AppFog at GA would need to be, how it would need to work, and what our pricing would be. This was what devs asked us for:

  • The ability to easily scale apps across dozens or hundreds of load-balanced instances, even on the free plan
  • Must run apps on the fastest servers available in the infrastructure (yes, we mean, for example, M2.4XL)
  • Must be able to run apps across multiple infrastructures (Rackspace, HP, AWS, Azure–and with no price difference)
  • Must simplify pricing. No more weird packages and bundles and names. Make it simple and affordable and most of all make it fair.
  • True interoperability in the cloud, including single-click, zero-code migrations between cloud vendors, eliminating all traces of vendor lock-in
  • Target of 30-second deployments to AWS, Rackspace, HP, Azure, etc.
  • Support for any and all languages in the Cloud Foundry codebase
  • Support for any and all relational and NoSQL data stores**

This is a daunting list. But it’s what devs wanted.

So let’s get into the nitty gritty… how did we actually do this?

How We Built a PaaS Around Cloud Foundry

This is a complex story. Fortunately, a few months ago, Jeremy Voorhis gave a talk at QCon in London describing how AppFog built a commercial system by using the Cloud Foundry OSS bits alongside our own set of custom extensions and enhancements. This is far and away the best place to start for understanding the Cloud Foundry-to-AppFog evolution. The slides for the talk can be found here and the video here.

We won’t go over everything in Jeremy’s hour-long talk here, but we’d like to cover some of the main points.

First, Jeremy clears up some of the confusion surrounding the signifier “Cloud Foundry.” On one hand, CloudFoundry.com is a hosted PaaS offering from VMware that runs on the vSphere virtualization platform based on the open source project found on CloudFoundry.org. VMware also has open sourced the tooling it uses to manage CloudFoundry.com–Cloud Foundry BOSH–and exposes the exact BOSH releases used live in production on their hosted service.

We do not run on the hosted VMware service but instead we are built from the same open source Cloud Foundry project. This open source distributed system enabling teams to manage and deploy apps and services over their lifecycle in the cloud is the core of the AppFog service.

AppFog is unique within the current Cloud Foundry ecosystem because we have built an infrastructure-agnostic Cloud Foundry service.

The beauty of Cloud Foundry is that it can, in principle, be implemented in conjunction with infrastructure offerings ranging from an OpenStack-based IaaS like Rackspace or HP to AWSJoyentCitrix, and beyond. This inherent multi-cloud portability is why the Cloud Foundry project was so inspiring to us.

For us, the ability to deploy and redeploy across infrastructures within the lifecycle of an application is the key to building a next-generation PaaS. It also, we think, fulfills the underlying mission of PaaS to: (a) sharpen product team focus in development; (b) produce a shorter feedback loop within app lifecycles, and; (c) provide the possibility of near-instant horizontal scalability.

Cloud Foundry’s Role in the Evolution of Cloud Computing

Even for those who are familiar with the space of cloud computing in general, it’s important to review historical context. For us at AppFog, Cloud Foundry has provided some of the crucial building blocks to assembling the first next-generation PaaS. But what do we mean by that?

First, it’s important to get some background. PaaS in its initial forms was enabled by a number of historical breakthroughs such as:

  • The rise of data centers via companies like Rackspace in the 1990s
  • The emergence of server virtualization via VMware in the early ‘00s
  • The introduction of APIs to virtualized resources via AWS in the mid ‘00s
  • The more recent rise of the DevOps paradigm with their associated and derived tools like Puppet and Chef.

But this trajectory really began coming to fruition in just the past two years. Tools like Cloud Foundry and OpenStack have emerged that enable full application lifecycle management. What this means is that the “platform” in “platform as a service” can now encompass all aspects of the application lifecycle outside of development. Jeremy refers to this as “NoOps” in the talk. What it means is emphatically not that no one does Ops work anymore. Instead, it means that responsibility for Ops work is passed on to the platform layer and remains there for most if not all of the app’s lifecycle.

Without a comprehensive tool like Cloud Foundry, we never would have been able to overcome the gap between (a) first-generation PaaS platforms, which we were essentially little more than gateways for (unwieldy) infrastructure management, and (b) next-generation PaaS like AppFog, which provide a far more comprehensive set of user benefits.

AppFog’s Modifications of Cloud Foundry

AppFog began as an effort to bring a great user interface and multi-cloud experience to the hosted Cloud Foundry ecosystem. We saw a number of stumbling blocks standing between the Cloud Foundry codebase and a full-fledged PaaS offering. The current Cloudfoundry.org project has CLI and various IDE integrations, but our vision included the full user experience, including fast sign-up, a web console, pre-built example applications that became what we call Jumpstarts, add-ons, and more.

While some Cloud Foundry users are indeed quite comfortable operating the system from the command line, Eclipse or the Spring Tool Suite (just as many AppFog users do), we also wanted to provide users with an elegant and intuitive console from which they could manage all of their apps. An example of the AppFog console is below:

The creators of the system wanted Cloud Foundry to remain agnostic toward the UX side of things and didn’t want to make its UX implementation overly opinionated. We know that simplicity and intuitiveness are not ends in themselves, and that it’s all too easy to produce an elegant UX on top of a subpar underlying system. But there’s also a lot to be said for seeking to accommodate the needs of as many end users as possible and we believe that we’ve done that. Here are some of the many innovations that we introduced on top of and below Cloud Foundry:
  • Varnish-based caching tier used to achieve significant speed gains
  • Single-click clone from one CF-based infrastructure to another for true workload portability
  • A Cloud Foundry API compatibility layer to auto-route requests to completely autonomous CF instances running in totally different parts of the planet
  • Deep cross-datacenter nagios integration so we know about problems before they affect you

In addition, Cloud Foundry enabled AppFog to create a deeply holistic, self-communicating architecture. It has also enabled us to design AppFog as a system that

assumes that failure happens and provides a set of protocols for handling failure, be it at the infrastructure level or elsewhere.

Carrying Cloud Foundry Forward

Building a full-fledged, commercial grade PaaS that spans multiple clouds, across multiple clouds, connecting it all together with a state of the art end-user experience is an immense undertaking even when starting with the base CloudFoundry.org system. It takes a dedicated team with a great deal of developer empathy, a team willing to step into the customers shoes and think like they think. But we think that the result has been more than worth the effort. We were very fortunate to have a core system like Cloud Foundry available to us. We’ve given back in many ways, including adding initial

PHP runtime support to the project, and continue to give back as we optimize Cloud Foundry to run well in public clouds. We are incredibly excited about AppFog going GA. We are even more excited about the thousands and thousands of developers who have already signed up and deployed thousands and thousands of apps. We believe that the success of AppFog demonstrates not just the power of PaaS, but also the strength of the Cloud Foundry codebase and the power of its open source ecosystem and community. This is a win not just for AppFog, but for everyone invested in the success of Cloud Foundry.

About the Author: Lucas Carlson is an entrepreneur and professional programmer who specializes in the development of web applications at scale. Lucas is the Founder and CEO at the leading cross-cloud PaaS company AppFog. He has authored over a dozen Ruby libraries and contributed to a range of significant Rails products including Rails and RedCloth. Lucas founded, ran and judged the popular Ruby on Rails contest Rails Day and has been a well-received speaker at many major programming conferences. Lucas was the first engineer at MOG and was responsible for development and technical direction for that seminal music streaming service. Lucas lives in Portland, Oregon, and loves statistics and Go.

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Build a Real Time Activity Stream on Cloud Foundry with Node.js, Redis and MongoDB 2.0 – Part III

In Part II of this series, we covered the architecture needed for persisting the Activity Streams to MongoDB and fanning it out in real-time to all the clients using Redis PubSub.

Since then, some exciting new Node.js features for Cloud Foundry were launched. In addition, the MongoDB version on Cloud Foundry has been upgraded to 2.0.

In this blog post we will cover how to:

  • Use Mongoose-Auth to store basic user information, including information from Facebook, Twitter, and Github, and how we made this module with native dependencies work on Cloud Foundry
  • Use Mongo GridFS and ImageMagick to store user uploaded photos and profile pictures
  • Perform powerful stream filtering, thanks to new capabilities exposed in MongoDB 2.0
  • Update the UX of the app to become a real-time stream client using Bootstrap, Backbone.js and Jade.

Offering SSO and Persisting Users

The requirement for this boilerplate Activity Streams App was to allow users to log in with Facebook, Twitter, or Github, and to persist this user data in the database.

I am sure many of you are familiar with how to store user information in a database and perhaps even in MongoDB. What some of you may not have tried is storing third party user information like the one we obtain when users log in with Facebook, Twitter or Github. In a relational database, you would probably store this information across multiple records in multiple tables (e.g., users, services, accounts, or auth). However, with MongoDB you can use embedded documents and store all this information in a single document, thus reducing the complexity of the operation. I found that this was very easy to do using @bnoguchi’s mongoose-auth which decorates the Mongoose User Schema with the third party services fields.

My previous version of the app was using another popular module from Brian called everyauth which handled SSO very well, but it did not persist the user info. It was fairly straightforward to upgrade from everyauth to mongoose-auth.

First, I updated a helper module I created called activity-streams-mongoose to offer a User Schema and made it possible to extend all schemas. Then I loaded mongoose-auth and decorated that schema with the specifics needed. You can see the exact code changes in this diff. The key part in the upgrade was to normalize the user data as it was saved. I did this by leveraging the pre-save callback MongooseJS offers.

Here is a snippet of the code:

var streamLib = require('activity-streams-mongoose')({
  mongoUrl: app.siteConf.mongoUrl,
  redis: app.siteConf.redisOptions,
  defaultActor: defaultAvatar
});

var authentication = new require('./authentication.js')(streamLib, app.siteConf);

// Moved normalization to only be done on pre save
streamLib.types.UserSchema.pre('save', function (next) {
  var user = this;
  var svcUrl = null;
  if (user.fb && user.fb.id) {
    user.displayName = "FB: " + user.fb.name.full;
    asmsDB.ActivityObject.findOne().where('url', facebookHash.url).exec(function(err, doc){
      if (err) throw err;
      user.author = doc._id;
      // Need to fetch the users image...
      https.get({
        'host': 'graph.facebook.com'
        , 'path': '/me/picture?access_token='+ user.fb.accessToken
      }, function(response) {
        user.image = {url: response.headers.location};
        next();
      }).on('error', function(e) {
        next();
      });
    })
  } else  {
    if (user.github && user.github.id) {
      user.displayName = "GitHub: " + user.github.name;
      var avatar = 'http://1.gravatar.com/avatar/'+ user.github.gravatarId + '?s=48'
      user.image = {url: avatar};
      svcUrl = githubHash.url;
    } else if (user.twit && user.twit.id) {
      user.displayName = "Twitter: " + user.twit.name;
      user.image = {url: user.twit.profileImageUrl};
      svcUrl = twitterHash.url;
    }

    if(!user.actor) {
      asmsDB.ActivityObject.findOne().where('url', svcUrl).exec(function(err, doc){
        user.author = doc;
        next();
      });
    } else {
      next();
    }
  }
  });

var asmsDB = new streamLib.DB(streamLib.db, streamLib.types);
streamLib.asmsDB = asmsDB;

MongoDB 2.0 and Cloud Foundry

For those of you not familiar with MongoDB 2.0, one neat feature is that it supports Multi-location Documents. I was also able to add a location property to the core Activity Object in the activity-streams-mongoose module which can be used with the Activities, Activity Objects and User collections to allow performing Geo Queries.

var LocationHash = {
  displayName: {type: String},
  position: {
    latitude: Number,
    longitude: Number
  }
};

var ActivityObjectHash = {
  id: {type: String},
  image: {type: MediaLinkHash, default: null},
  icon: {type: MediaLinkHash, default: null},
  displayName: {type: String},
  summary: {type: String},
  content: {type: String},
  url: {type:String},
  published: {type: Date, default: null},
  objectType: {type: String},
  updated: {type: Date, default: null},
  location: LocationHash,
  fullImage : {type: MediaLinkHash, default: null},
  thumbnail : {type: MediaLinkHash, default: null},
  author : {type: ObjectId, ref: "activityObject"},
  attachments : [{type: ObjectId, ref: 'activityObject'}],
  upstreamDuplicates : [{type: String, default: null}],
  downstreamDuplicates : [{type: String, default: null}]
};

Another interesting geo feature in MongoDB 2.0 is polygonal search. This means that you can search whether a given object is in a specified area by providing the area points. For example, this can be helpful when you want to see if certain objects, like houses, are in a certain zip code.

Working with Node.js Modules with Native Dependencies

Mongoose-Auth requires a module bcrypt which has a native dependency (it gets compiled locally when you do a Node Package Manager (npm) install and the binary placed in the mode_modules directory). If you are working from a Mac or Windows and deploying to the cloud you can run into issues by including your node_modules folder. Luckily, now there is support in Cloud Foundry for excluding the node_modules folder and having Cloud Foundry fetch and build the npm modules server-side.

$ npm shrinkwrap
$ echo "{ignoreNodeModules: true}" > cloudfoundry.json
$ vmc update

For more info you can read this blog post from Maria and/or watch this helpful video from Raja.

My recommendation is that when you start a new Node.js App make sure to add the cloudfoundry.json file with skip node_modules folder set to true so all the native dependencies are built directly on Cloud Foundry. Also don’t forget to run npm shrinkwrap if you change package.json.

User Uploaded Photos with ImageMagick and Mongo GridFS

One of the most engaging objects to show in a web app like this
Activity Stream boilerplate app are photos. Apps like Instagram and Pinterest have taken photo sharing to a whole new level and have completely redesigned the UX of photo feeds. We wanted to help developers build Activity Stream apps with rich photo sharing and thus needed a library to help us manipulate images and a place to store all these images. Since we were already using MongoDB, I decided to leverage Mongo GridFS to store the images.

I had previously worked storing photos in GridFS but it was from Ruby. It was a little bit more challenging to find the right tools in Node.js. I found a lot of npm modules which seemed to handle it for me, but found that they were either unfinished or loaded several additional components which were incompatible. I really wanted to keep it simple so I ended up following the documentation on the official Node.js Mongo DB driver and creating a few routes to handle creating photos and viewing photos.

Here is how I ingested the photos into Mongo GridFS:

var im = require('imagemagick');
var Guid = require('guid');
var siteConf = require('./lib/getConfig');
var lib = new require('./lib/asms-client.js')(app, cf).streamLib;

function ingestPhoto(req, res, next){
  if (req.files.image) {
    im.identify(req.files.image.path, function(err, features){
      if (features && features.width) {
        var guid = Guid.create();
        // Concatenating name to guid guarantees that we always have
        // unique file names
        var fileId = guid + '/' + req.files.image.name;
        // The GridStore class is the equivalent of a File class but has the
        // added benefit of allowing you to store metadata
        var gs = lib.GridStore(lib.realMongoDB, fileId, "w", {
          content_type : req.files.image.type,
          // metadata is optional
          metadata : {
            author: req.session.user._id,
            public : false,
            filename: req.files.image.name,
            path: req.files.image.path,
            width: features.width,
            height: features.height,
            format: features.format,
            size_kb: req.files.image.size / 1024 | 0
          }
        });
         // This command copies the file from the file system(temp dir)
         // to GridFS.
         // GridFS supports any file size by breaking it into chunks
         // behind the scenes
        gs.writeFile(req.files.image.path, function(err, doc){
          if (err) {
            next(err);
          } else {
            if (! req.photosUploaded) {
              req.photosUploaded = {};
            }
            // I have another express route to serve the photos by fileId
            var url = siteConf.uri + "/photos/" + fileId;
            // Add the results of the upload to the chain
            req.photosUploaded['original'] = {url : url, metadata: gs.metadata};
            req.nextSizeIndex = 0;
            next();
          }
        });
      } else {
        if (err) throw err;
        throw(new Error("Cannot get width for photo"));
      }
    });
  } else {
    next(new Error("Could not find the file"));
  }
};

The above snippet shows how I used ImageMagick to get the photo dimensions. ImageMagick is an amazing open source software suite for manipulating images and there is an easy to use ImageMagick node module to expose its functionality.

An open source project backed by years of continual development, ImageMagick supports about 100 image formats and can perform impressive operations such as creating images from scratch; changing colors; stretching, rotating, and overlaying images; and overlaying text on images.

ImageMagick.org

And this snippet shows how to produce a new image of smaller size:

var im = require('imagemagick');
var Guid = require('guid');

function reducePhoto(req, res, next){
    var photoIngested = req.photosUploaded['original'];
    if (photoIngested) {
        var sizeName = sizes[req.nextSizeIndex].name;
        var destPath = photoIngested.metadata.path + '-' + sizeName ;
        var nameParts = photoIngested.metadata.filename.split('.');
        var newName = nameParts[0] + '-' + sizeName + '.' + nameParts[1];
        var width = sizes[req.nextSizeIndex].width;

        im.resize({
          srcPath: photoIngested.metadata.path,
          dstPath: destPath,
          width:   width
        }, function(err, stdout, stderr){
          if (err) {
              next(err);
          } else {
            console.log("The photo was resized to " + width + "px wide");
            var guid = Guid.create();
            var fileId = guid + '/' + newName;
            var ratio = photoIngested.metadata.width / width;
            var height = photoIngested.metadata.height / ratio;
            var gs = asmsClient.streamLib.GridStore(asmsClient.streamLib.realMongoDB, fileId, "w", {
                  content_type : req.files.image.type,
                  metadata : {
                      author: req.session.user._id,
                      public : false,
                      filename: newName,
                      width: width,
                      height: height,
                      path: destPath
                  }
              });
              gs.writeFile(destPath, function(err, doc){
                  if (err) {
                    next(err);
                  } else {
                      var url = siteConf.uri + "/photos/" + fileId;
                      req.photosUploaded[sizeName] = {url : url, metadata: gs.metadata};
                      req.nextSizeIndex = req.nextSizeIndex + 1;
                      next();
                  }
              });
          }
        });
    }
};

The only gotcha on Cloud Foundry was that it did not set for us the environment variable TMP which is used by the formidable module to offer a temp directory where the files are first uploaded. Once I set it using env-add the problem was solved.

bash-3.2$ vmc files asms app/tmp

   36272c476f10ecbf0e3a99481a8d365b         50.6K

All apps on Cloud Foundry have permissions to write files to its own directory or a subdirectory. Set the environment variable TMP to a subdir if you are working with express/formidable to have it handle form uploads.

More Powerful Queries with MongoDB
Part of the beauty of the ActivityStrea.ms format is that it provides a lot of metadata about each activity which can then be searched, aggregated and pivoted to draw interesting conclusions about certain topics and trends.

Examples of these fields are: Hashtags or Topics, Verb, Object Types, Actor Types and Location.

The first step to allowing users to analyze the stream data is providing them with a map of their universe. This means allowing them to see all the possible values for each field. For example, if we are talking about hashtags, then we would show our users that the population has used so far ten hashtags. We would then reveal the distribution in usage across everyone. Then we would provide our users with the ability to drill in by segmenting via actor type or location, for example. This could yield interesting results showing where certain topics are most popular.

var getDistinct = function (req, res, next, term, init){
  var key = 'used.' + term;
  req[key] = init ? init : [];
  var query = {streams: req.session.desiredStream};
  asmsDB.Activity.distinct(term, query, function(err, docs) {
    if (!err && docs) {
      _.each(docs, function(result){
        req[key].push(result);
      });
      next();
    } else {
      next(new Error('Failed to fetch distinct ' + term));
    }
  });
}

//..

function getDistinctVerbs(req, res, next){
  getDistinct(req, res, next, 'verb');
};

function getDistinctActors(req, res, next){
  getDistinct(req, res, next, 'actor');
};

function getDistinctObjects(req, res, next){
  getDistinct(req, res, next, 'object', ['none']);
};

function getDistinctObjectTypes(req, res, next){
  getDistinct(req, res, next, 'object.object.type', ['none']);
};

function getDistinctActorObjectTypes(req, res, next){
  getDistinct(req, res, next, 'actor.object.type', ['none']);
};

//...

app.get('/streams/:streamName', loadUser, getDistinctStreams, getDistinctVerbs, getDistinctObjects, getDistinctActors,
  getDistinctObjectTypes, getDistinctActorObjectTypes, getDistinctVerbs, getMetaData, function(req, res) {

    asmsClient.asmsDB.Activity.getStream(req.params.streamName, 20, function (err, docs) {
    var activities = [];
    if (!err && docs) {
      activities = docs;
    }
    req.streams[req.params.streamName].items = activities;
    var data = {
      currentUser: req.user,
      streams : req.streams,
      desiredStream : req.session.desiredStream,
      actorTypes: req.actorTypes,
      objectTypes : req.objectTypes,
      verbs: req.verbs,
      usedVerbs: req['used.verb'],
      usedObjects: req['used.object'],
      usedObjectTypes: req['used.object.type'],
      usedActorObjectTypes: req['used.actor.object.type'],
      usedActors: req['used.actor']
    };
    if (req.is('json')) {
      res.json(data);

    } else {
       res.render('index', data);
    }
  });

});

A Robust Activity Stream UX

The initial node-express-boilerplate app had some basic jQuery used to show plain text messages and users’ photos. In the new app, we have much richer messages and the ability to post and filter them. For this reason, we decided to use some of the great client-side open source tools available today.

After some consideration, we ended up using these three tools:

  1. Backbone.js: A lightweight client-side MVC framework
  2. Bootstrap: A set of CSS, HTML and Javascript components which help developers produce great looking apps, without needing to start from scratch
  3. Jade: A templating language with the help of ClientJade

Templating, Markup and CSS

If you are a web developer, you probably know that there are many choices in tools to render HTML dynamically. A good number of web developers prefer to use templating engines to render HTML because these help you produce more readable code. Using declarative programming, you can interpolate variables and directives in the HTML. The most popular templating engine for Node.js is Embedded JavaScript (EJS), which resembles ERB in Ruby. This is what the node-express-boilerplate project included. When I started working with Node.js, I found many more choices that were not present in the Ruby world such as: Mustache, Handlebars, Dust and Jade. In fact, LinkedIn wrote an excellent blog post discussing the many alternative choices for templating engines.

I ended up selecting Jade because I already liked HAML, which is very similar to Jade in its terseness. Both templating languages use indentation to understand the hierarchy of elements. Jade is even terser than HAML because it removes the need to put % in front of the HTML tags.

Another cool thing about Jade is that it already had support for server-side and client-side rendering via ClientJade. Here is how I broke out the views allowing easy extension of the object types.

I then compiled the Jade views into js for faster client-side rendering with ClientJade.

clientjade views/*.* > public/js/templates.js

Once this was done, I simply included templates.js in the list of files to be minified and used it like this from Backbone:

var ActivityCreateView = Backbone.View.extend({
    el: '#new_activity',
    initialize: function(){
        _.bindAll(this, 'newAct', 'render', 'changeType', 'includeLocation', 'sendMessage');

        this.trimForServer = App.helper.trimForServer;

        var streamName = this.$el.find('#streamName').val();
        var verb = this.trimForServer(this.$el.find('#verb-show'));
        var objectType = this.trimForServer(this.$el.find('#object-show'));

        this.newAct(streamName, verb, objectType);
        this.render();
    },
    events: {
        "click .type-select" : "changeType",
        "click #includeLocation" : "includeLocation",
        "click #send-message" : "sendMessage"
    },
    newAct : function(streamName, verb, objectType) {
        this.streamName = streamName;
        this.model = new Activity({
            object: {content: '', objectType: objectType, title: '', url: ''},
            verb: verb,
            streams: [streamName]
        });
    },
    render: function(){
      var actData = this.model.toJSON();
      this.$el.find("#specific-activity-input").html(jade.templates[actData.object.objectType]());

      return this; // for chainable calls, like .render().el
    },
    changeType : function(event) {
        console.log(event);
        var itemName = $(event.target).data("type-show");
        if (itemName) {
            $("#" + itemName)[0].innerHTML = event.target.text + "  ";
            var val = this.trimForServer(event.target.text);
            if (itemName == "verb-show") {
                this.model.set('verb', val);
            } else {
                var obj = this.model.get('object');
                obj.objectType = val;
                this.model.set('object', obj);
            }
        }
        this.render();
    },
    includeLocation : function(event) {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(App.helper.getLocation);
        } else {
            alert("Geo Location is not supported on your device");
        }
    },
    sendMessage : function() {
        console.log("In send message");

        var obj = this.model.get('object');
        obj.content = $("#msg").val();
        obj.url = $('#url').val();
        obj.title = $('#title').val();
        obj.objectType = this.trimForServer($('#object-show'));
        this.model.set('object', obj);

        var streamName = $('#streamName').val();
        this.model.set('streams', [streamName]);

        var verb = this.trimForServer($('#verb-show'));
        this.model.set('verb', verb);

        if (this.model.isValid()) {
            if (this.model.save()) {
                this.newAct(streamName, verb, obj.objectType);
                this.render();
            }
        }

    }

});

The original node-express-boilerplate app was using 960gs and jQuery. However, this activity streams boilerplate app is a bit more complex so I switched to using Twitter’s Bootstrap as the first step. This provided me a nice way to the nav bar, hero unit, modals, drop downs and so on. Also it was easy enough to go from using one grid system to another. For the moment the app is using the default grid system but it can easily be made to use Bootstrap’s Fluid Layout and Responsive Design enhancements.

Manipulating Data on the Client with Backbone.js

Instead of having a large number of individual jQuery handlers on HTML elements, Backbone.js helps you break your UX apart into components called Views which are more similar to Controllers when thinking of server-side MVC frameworks. These Backbone views can take Backbone models and templates and render them, as well as listen for events on the elements that comprise the view. You can see in the snippet above we have a Backbone view that works with a Backbone model for an Activity.
Backbone Models are pretty simple classes you create by detailing all the properties for the model and validation rules. Here is the code for the Activity Backbone Model which is also used to create the ActivityStreamView:

var Activity = Backbone.Model.extend({
    url : "/activities",
    // From activity-streams-mongoose/lib/activityMongoose.js
    defaults: {
        verb: 'post',
        object: null, //ActivityObject
        actor: null, //ActivityObject
        url: '',
        title: '',
        content: '',
        icon: null, // MediaLinkHash
        target: null, //ActivityObject
        published: Date.now,
        updated: Date.now,
        inReplyTo: null, //Activity
        provider: null, //ActivityObject
        generator: null, //ActivityObject
        streams: ['firehose'],
        likes: {},
        likes_count: 0,
        comments: [],
        comments_count: 0,
        userFriendlyDate: 'No idea when'
    },
    validate: function(attrs) {

    if (! attrs.object) {
        return "Object is missing"
    }
    if (!attrs.object.title) {
      return "Title is missing";
    }
  }
});

You can then easily instantiate passing a javascript bare object. In the example below, I took the output from socket.io when a message comes in, converted it to an object and added it to the Backbone collection associated with the Stream View:

var streamView = new ActivityStreamView();
App.socketIoClient.on('message', function(json) {
  var doc = JSON.parse(json);
    if (doc) {
      streamView.collection.add(new Activity(doc));
    }
});

Working with Backbone.js was very fun but it definitely takes some time to convert all your logic to using Backbone Views and Models. In this example, I only used Backbone.js for a subset of the app. Having Jade as my templating language and Node.js allowed me to share code between server and client. If you have a trivial application, you may not need to use Backbone.js and may be able to keep it simple with express and server side templates. In the case of this Activity Streams application, which syndicates in real time and offers the ability to react to any new item, it made sense to use Backbone.js. It also allowed me to provide the hooks for the next iteration of this app. After all, this is a boilerplate app.

Remember that it is very easy to push updates to your application on Cloud Foundry as you make progress doing:

bash-3.2$ vmc update

Updating application 'asms'...
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (380K): OK   
Push Status: OK
Stopping Application 'asms': OK
Staging Application 'asms': OK                                                  
Starting Application 'asms': OK

Conclusion

As a contributor to the ActivityStrea.ms specification, I find it necessary (and fun) to get my hands dirty building the apps which use open standards to see where there are limitations and what technologies can make it easier. Working with MongoDB proved to be the right choice, giving me the ability to do complex queries, aggregation and full modeling of my objects which are needed for quickly painting the stream. I am really happy that MongoDB 2.0 is now running on Cloud Foundry because a lot of the Object Document Mappers like Mongoid in Ruby only support 2.x. This is a very exciting time to be a developer, as things are moving very fast and there is ample opportunity to make a difference via open source.

Here is the final architecture of the app at a very high-level:

Activity Streams Boilerplate App Architecture

To try this application, you can visit it here. To get the full code, you can clone or fork it here.

–Monica Wilkinson

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email