Cloud Foundry Blog

Want to Contribute to Cloud Foundry? Come on in!

Cloud Foundry is an Open Platform-as-a-Service, and an Open Source project. It has attracted phenomenal interest from the community - including partners, companies using the code internally, and those individual developers with a passion for getting involved. You can find the source code on Github. Community contributions are what help to make the platform so extensible. We are always happy when we receive a Github pull request to offer new functionality or fixes! We also appreciate bug reports submitted through Github Issues.

Looking at the Cloud Foundry project as a whole though… where should you start?

As you might imagine, there are a lot of moving parts in a PaaS. At Pivotal, we have teams working on the backend (the main runtime environment for Cloud Foundry, also known as ‘vcap’); the frontend (the tools and APIs for deploying apps, such as the ‘cf’ gem); services (database, message queues, and related resources); and Cloud Foundry BOSH, the installer and deployment tool, which has different plugins targeting infrastructures like AWS, OpenStack and vSphere. In the future, we would love to see even more Cloud Provider Interfaces (CPIs) for BOSH to allow Cloud Foundry to be deployed onto additional clouds.

One of the best ways to get involved with the community and the codebase is to start with the Github repositories and the mailing lists. If you are not sure where particular functionality resides within the project as a whole, and you’ve had a good look at Github already, then we have a number of mailing lists where you can ask for help. vcap-dev is for those working on the PaaS itself; bosh-users is for those who want to understand how to use BOSH to deploy Cloud Foundry; and bosh-dev is for the elite hackers (like Dr Nic Williams!) who want to help us make BOSH even more awesome. If you participate in the mailing lists you will also be able to keep up with what others are working on, and learn who some of the leading developers on the project are. If you want to get an idea of the general direction of development, you’ll find that in our roadmap.

Once you are up-and-running with Cloud Foundry, or if you know to which part of the project  you want to contribute, then consider the size of an initial contribution. If you are new to the project you might want to start with something small (some Open Source projects call these kind of small changes to smooth out any rough edges “paper cuts”). If you have something larger, we are always keen to work with you to understand how we can integrate your code. Before sending a pull request, take a look at our OSS contribution information in the project readme, which includes details on the Contributor License Agreement for individuals and corporations.

We thought it would be good to highlight a recent pull request which was a superb example of a major addition to the project. Recently we received a contribution via a detailed Github pull request, adding Oracle support to some of the major components inside Cloud Foundry: the User Account and Authentication service (UAA) and the Cloud Controller. Originally, these components were built to use Postgres as a backend, and more recently MySQL support was added. Since many enterprises already use Oracle as their main relational data store, it is great to give them this additional storage option.

Taking a look at the specific request for the Cloud Controller, we were really struck by a few things. The first one is that the pull request itself is very detailed, and walks through the various changes required in order to replace the database with Oracle.

This pull request is a lot to digest. If you want you can review the single feature PR that lead to this PR for some more concise context into some of the decisions I made in creating this PR. Here is a summary of the more notable changes I had to make and some context for why I made those changes:

This level of detail is not always required with every patch, of course, but for something this extensive it was very welcome. Another aspect of this patch is that was was made of up several individual changes (things like tweaks to the database schema, differences between Oracle datatypes and those used by other databases, etc), and they were broken down into separate commits which made it easier to consume. It also helped that this set of changes was extensively discussed on the vcap-dev mailing list before this larger pull request was submitted, so the engineering team were aware of some of the other impacts it would have.

Although the resulting pull request was detailed and clear, it has taken a few days to make all of the changes, as the core code was still being worked on. This was actually one of the rarer cases where we had to do more work to get the patches integrated – and that shows how willing we are to work with contributions. Smaller changes are extremely welcome too, and often much quicker to digest. Don’t be put off by this larger example – come and start hacking with us!

We hope this post highlights some of the things that help to make it smoother to contribute to the project. To recap:

  1. review the contribution guidelines and complete the CLA;
  2. if you want to submit a major code change, discuss it on the relevant mailing list beforehand;
  3. think about how the pull request is structured, and submit changes in separate consumable commits (rather than as one monolithic change) where appropriate;
  4. the patch should be well-tested, should include tests if possible, and should pass our Travis CI process;
  5. the changes should be clearly documented in the request, especially when the updates are more extensive than correcting a few typos.

The past few months have seen the Cloud Foundry Open Source community grow hugely, and mailing list activity continues to be at an all-time high – so we’re really looking forward to continuing to work with other developers to make the platform even more awesome! Thanks for being on this journey with us.

Andy Piper @andypiper

Developer Advocate, Cloud Foundry

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Scaling Real-time Apps on Cloud Foundry Using Node.js and Redis

Common applications being built on Node.js like social networking and chat require real-time scaling capabilities across multiple instances. Developers need to deal with sticky sessions, scale-up, scale-down, instance crash/restart, and more. Cloud Foundry PaaS provides a ready platform to achieve this quickly.

The following blog post will walk you through deploying and managing real-time applications on Cloud Foundry using common Node.js examples and Redis key-value store capabilities.


Chat App

The main objective here is to build a simple chat app while tackling the scale requirements. Specifically, we will be building a simple Express, Socket.io and Redis-based Chat app that meets the following objectives:

  1. Chat server should run with multiple instances.
  2. The user login should be saved in a session.
    • User should be logged back in upon browser refresh
    • Socket.io should get user information from the session before sending chat messages.
    • Socket.io should only connect if user is already logged in.
  3. If the server instance that the user is connected to gets restarted, goes down or is scaled down while the user is chatting, the user should be reconnected to an available instance and recover the session.

Chat app’s Login page:

Chat app’s Chat page:

We will also cover:

  1. How to use Socket.io and Sticky Sessions
  2. How to use Redis as a session store
  3. How to use Redis as a pubsub service
  4. How to use sessions.sockets.io to get session info (like user info) from Express sessions
  5. How to configure Socket.io client and server to properly reconnect after one or more server instances goes down (i.e. has been restarted, scaled down or crashed)

Socket.io & Sticky Sessions

Socket.io is one of the earliest and most popular Node.js modules to help build real-time apps like chat, social networking etc. (Note: SockJS is another popular library similar to Socket.io).

When you run such a server in a cloud that has a load-balancer, reverse proxy, routers etc., it has to be configured to work properly, especially when you scale the server to use multiple instances.

One of the constraints Socket.io, SockJS and similar libraries have is that they need to continuously talk to the same instance of the server. They work perfectly well when there is only 1 instance of the server.

When you scale your app in a cloud environment, the load balancer (Nginx in the case of Cloud Foundry) will take over, and the requests will be sent to different instances causing Socket.io to break.

For such situations, load balancers have a feature called ‘sticky sessions’, also known as ‘session affinity’. The idea is that if this property is set, all the requests following the first load-balanced request will go to the same server instance.

In Cloud Foundry, cookie-based sticky sessions are enabled for apps that set the cookie jsessionid. Note that jsessionid is the cookie name commonly used to track sessions in Java/Spring applications. Cloud Foundry is simply adopting it as the sticky session cookie for all frameworks.

To make socket.io work, the apps just need to set a cookie with the name jsessionid.

/**
* Use cookieParser and session middleware together.
* By default Express/Connect app creates a cookie by name 'connect.sid'. But to scale Socket.io app,
* make sure to use cookie name 'jsessionid' (instead of connect.sid) use Cloud Foundry's 'Sticky Session' feature.
* W/o this, Socket.io won't work when you have more than 1 instance.
* If you are NOT running on Cloud Foundry, having cookie name 'jsessionid' doesn't hurt - it's just a cookie name.
*/
app.use(cookieParser);
app.use(express.session({store:sessionStore, key:'jsessionid', secret:'your secret here'}));

In the above diagram, when you open the app,

  1. Express sets a session cookie with name jsessionid.
  2. When socket.io connects, it uses that same cookie and hits the load balancer
  3. The load balancer always routes it to the same server that the cookie was set in.

Sending session info to Socket.io

Let’s imagine that the user is logging in via Twitter or Facebook, or a regular login screen. We are storing this information in a session after the user has logged in.

app.post('/login', function (req, res) {
    //store user info in session after login.
    req.session.user = req.body.user;
    ...
    ...
});

Once the user has logged in, we connect via socket.io to allow chatting. However, socket.io doesn’t know who the user is and if he or she is actually logged in before sending chat messages to others.

That’s where the sessions.sockets.io library comes in. It’s a very simple library that’s a wrapper around socket.io. All it does is grab session information during the handshake and then pass it to socket.io’s connection function.

//With just Socket.io..
io.sockets.on('connection', function (socket) {
    //do pubsub here
    ...
})

//But with sessions.sockets.io, you'll get session info

/*
 Use SessionSockets so that we can exchange (set/get) user data b/w sockets and http sessions
 Pass 'jsessionid' (custom) cookie name that we are using to make use of Sticky sessions.
 */
var SessionSockets = require('session.socket.io');
var sessionSockets = new SessionSockets(io, sessionStore, cookieParser, 'jsessionid');

sessionSockets.on('connection', function (err, socket, session) {

    //get info from session
    var user = session.user;

    //Close socket if user is not logged in
    if (!user)
        socket.close();

    //do pubsub
    socket.emit('chat', {user: user, msg: 'logged in'});
    ...
});


Redis as a session store

So far so good, but Express stores these sessions in MemoryStore (by default). MemoryStore is simply a Javascript object – it will be in memory as long as the server is up. If the server goes down, all the session information of all users will be lost!

We need a place to store this outside of our server, but it should also be very fast to retrieve. That’s where Redis as a session store come in.

Let’s configure our app to use Redis as a session store as below.

/*
 Use Redis for Session Store. Redis will keep all Express sessions in it.
 */
var redis = require('redis');
var RedisStore = require('connect-redis')(express);
var rClient = redis.createClient();
var sessionStore = new RedisStore({client:rClient});


  //And pass sessionStore to Express's 'session' middleware's 'store' value.
     ...
     ...
app.use(express.session({store: sessionStore, key: 'jsessionid', secret: 'your secret here'}));
     ...

With the above configuration, sessions will now be stored in Redis. Also, if one of the server instances goes down, the session will still be available for other instances to pick up.

Socket.io as pub-sub server

So far our sessions are taken care of with the above setup, but if we are using socket.io’s default pub-sub mechanism, it will work only for 1 sever instance. i.e. if user1 and user2 are on server instance #1, they can both chat with each other. If they are on different server instances, they cannot do so.

sessionSockets.on('connection', function (err, socket, session) {
    socket.on('chat', function (data) {
        socket.emit('chat', data); //send back to browser
        socket.broadcast.emit('chat', data); // send to others
    });

    socket.on('join', function (data) {
        socket.emit('chat', {msg: 'user joined'});
        socket.broadcast.emit('chat', {msg: 'user joined'});
    });
}

Redis as a PubSub service

In order to send chat messages to users across servers we will update our server to use Redis as a PubSub service (along with session store). Redis natively supports pub-sub operations. All we need to do is to create a publisher, a subscriber, and a channel.

//We will use Redis to do pub-sub

/*
 Create two Redis connections. A 'pub' for publishing and a 'sub' for subscribing.
 Subscribe 'sub' connection to 'chat' channel.
 */
var sub = redis.createClient();
var pub = redis.createClient();
sub.subscribe('chat');


sessionSockets.on('connection', function (err, socket, session) {
    socket.on('chat', function (data) {
        pub.publish('chat', data);
   });

    socket.on('join', function (data) {
        pub.publish('chat', {msg: 'user joined'});
    });

    /*
     Use Redis' 'sub' (subscriber) client to listen to any message from Redis to server.
     When a message arrives, send it back to browser using socket.io
     */
    sub.on('message', function (channel, message) {
        socket.emit(channel, message);
    });
}

The app architecture will now look like this:


Handling server scale-down / crashes / restarts

The app will work fine as long as all the server instances are running. What happens if the server is restarted or scaled down or one of the instances crash? How do we handle that?

Let’s first understand what happens in that situation.

The code below simply connects a browser to server and listens to various socket.io events.

/*
  Connect to socket.io on the server (***BEFORE FIX***).
  */
 var host = window.location.host.split(':')[0];
 var socket = io.connect('http://' + host);

 socket.on('connect', function () {
     console.log('connected');
 });
 socket.on('connecting', function () {
     console.log('connecting');
 });
 socket.on('disconnect', function () {
     console.log('disconnect');
 });
 socket.on('connect_failed', function () {
     console.log('connect_failed');
 });
 socket.on('error', function (err) {
     console.log('error: ' + err);
 });
 socket.on('reconnect_failed', function () {
     console.log('reconnect_failed');
 });
 socket.on('reconnect', function () {
     console.log('reconnected ');
 });
 socket.on('reconnecting', function () {
     console.log('reconnecting');
 });

While the user is chatting, if we restart the app on localhost or on a single host, socket.io attempts to reconnect multiple times (based on configuration) to see if it can connect. If the server comes up with in that time, it will reconnect. So we see the below logs:

If we restart the server (say using vmc restart redispubsub) and the user is chatting on the same app that’s running on Cloud Foundry AND with multiple instances, we will see the following log:

You can see that in the above logs, after the server comes back up, socket.io client (running in the browser) isn’t able to connect to socket.io server (running on Node.js in the server).

This is because, once the server is restarted on Cloud Foundry, instances are brought up as if they are brand-new server instances with different IP addresses and different ports and so jsessionid is no-longer valid. That in turn causes the load balancer to load balance socket.io’s reconnection requests (i.e. they are sent to different server instances) causing the socket.io server not to properly handshake and consequently to throw client not handshaken errors!

OK, let’s fix that reconnection issue

First, we will disable socket.io’s default “reconnect” feature, and then implement our own reconnection feature.

In our custom reconnection function, when the server goes down, we’ll make a dummy HTTP-get call to index.html every 4-5 seconds. If the call succeeds, we know that the (Express) server has already set jsessionid in the response. So, then we’ll call socket.io’s reconnect function. This time because jsessionid is set, socket.io’s handshake will succeed and the user can continue to chat without interruption.

/*
 Connect to socket.io on the server (*** FIX ***).
 */
var host = window.location.host.split(':')[0];

//Disable Socket.io's default "reconnect" feature
var socket = io.connect('http://' + host, {reconnect: false, 'try multiple transports': false});
var intervalID;
var reconnectCount = 0;
...
...
socket.on('disconnect', function () {
    console.log('disconnect');

    //Retry reconnecting every 4 seconds
    intervalID = setInterval(tryReconnect, 4000);
});
...
...


/*
 Implement our own reconnection feature.
 When the server goes down we make a dummy HTTP-get call to index.html every 4-5 seconds.
 If the call succeeds, we know that (Express) server sets ***jsessionid*** , so only then we try socket.io reconnect.
 */
var tryReconnect = function () {
    ++reconnectCount;
    if (reconnectCount == 5) {
        clearInterval(intervalID);
    }
    console.log('Making a dummy http call to set jsessionid (before we do socket.io reconnect)');
    $.ajax('/')
        .success(function () {
            console.log("http request succeeded");
            //reconnect the socket AFTER we got jsessionid set
            socket.socket.reconnect();
            clearInterval(intervalID);
        }).error(function (err) {
            console.log("http request failed (probably server not up yet)");
        });
};

In addition, since the jsessionid is invalidated by the load balancer, we can’t create a session with the same jsessionid or else the sticky session will be ignored by the load balancer. So on the server, when the dummy HTTP request comes in, we will regenerate the session to remove the old session and sessionid and ensure everything is afresh before we serve the response.

//Instead of..
exports.index = function (req, res) {
    res.render('index', { title: 'RedisPubSubApp', user: req.session.user});
};

//Use this..
exports.index = function (req, res) {
    //Save user from previous session (if it exists)
    var user = req.session.user;

    //Regenerate new session & store user from previous session (if it exists)
    req.session.regenerate(function (err) {
        req.session.user = user;
        res.render('index', { title: 'RedisPubSubApp', user: req.session.user});
    });
};


Running / Testing it on Cloud Foundry

  • Clone the app to redispubsub folder
  • cd redispubsub
  • npm install and follow the below instructions to push the app to Cloud Foundry
[~/success/git/redispubsub]
> vmc push redispubsub
Instances> 4       <----- Run 4 instances of the server

1: node
2: other
Framework> node

1: node
2: node06
3: node08
4: other
Runtime> 3  <---- Choose Node.js 0.8v

1: 64M
2: 128M
3: 256M
4: 512M
Memory Limit> 64M

Creating redispubsub... OK

1: redispubsub.cloudfoundry.com
2: none
URL> redispubsub.cloudfoundry.com  <--- URL of the app (choose something unique)

Updating redispubsub... OK

Create services for application?> y

1: blob 0.51
2: mongodb 2.0
3: mysql 5.1
4: postgresql 9.0
5: rabbitmq 2.4
6: redis 2.6
7: redis 2.4
8: redis 2.2
What kind?> 6 <----- Select & Add Redis v2.6 service

Name?> redis-e9771 <-- This is just a random name for Redis service

Creating service redis-e9771... OK
Binding redis-e9771 to redispubsub... OK
Create another service?> n

Bind other services to application?> n

Save configuration?> n

Uploading redispubsub... OK
Starting redispubsub... OK
Checking redispubsub... OK

  • Once the server is up, open up multiple browsers and go to <appname>.cloudfoundry.com
  • Start chatting

Test 1

  • Refresh the browser
  • You should automatically be logged in

Test 2

  • Open up JS debugger (in Chrome, do cmd + alt +j)
  • Restart the server by running vmc restart <appname>
  • Once the server restarts, Socket.io should automatically reconnect
  • You should be able to chat after the reconnection

That’s it for this time. Stay tuned for my next blog where I will discuss how RabbitMQ can be leveraged in scalable apps built on Cloud Foundry. The content of this blog has also been covered in a video. Feel free to get in touch with us for questions on the material.

General Notes

  • Get the code right away – Github location: https://github.com/rajaraodv/redispubsub.
  • Deploy right away – if you don’t already have a Cloud Foundry account, sign up for it here.
  • Check out Cloud Foundry getting started here and install the vmc Ruby command line tool to push apps.

  • To install the latest alpha or beta vmc tool run: sudo gem install vmc --pre.

Credits

Front end UI: https://github.com/steffenwt/nodejs-pub-sub-chat-demo

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Cloud Foundry Now Supports Rails Assets Pipeline

Rails version 3.1 introduced the assets pipeline as a way to properly organize and serve static assets. We are adding assets pipeline support for Rails applications deployed on  CloudFoundry.com.

Assets pipeline includes compression, ERB evaluation, Javascript and CSS processing using Rails 3.1 Sprockets library.

In development mode, assets precompilation is not required – Rails turns on live compilation if it can’t find precompiled assets. In production mode, live compilation is disabled by default.

One of the ways to make this work on Cloud Foundry is to bundle assets with your application before you push. Now CloudFoundry.com also provides assets precompilation as one of the steps of application pre-processing.

Bundle assets locally

Rails provides a rake task to compile and bundle assets with your app. You can prepare them locally for production by running:

RAILS_ENV=production bundle exec rake assets:precompile

This task discovers all the assets included in the application, pre-compiles them and saves compiled versions in public/assets directory by default as well as manifest.yml which contains the list of compiled assets with their digest.

Assets compilation on Cloud Foundry

In order to run this in CloudFoundry.com we had to implement some additional pre-processing when the application is staged. First, Cloud Foundry assumes that assets were compiled locally via an assets manifest. If the assets manifest is not found, Cloud Foundry runs the “assets:precompile” rake task during staging. Later, when the application is being run on the DEA (the container for Cloud Foundry apps) we have all the assets. These can be statically served with the digest and other magic that Rails adds to these files.

Live compilation

One potential problem can occur during application initialization. The precompile rake task runs a complete initialization of the Rails application. This might trigger some of the initialization procedures and require service connections and environment checks that are unavailable during staging. You can turn this off by adding a configuration option in application.rb:

config.assets.initialize_on_precompile = false

If the assets:precompile task fails, Cloud Foundry makes use of live compilation mode which is the alternative to assets precompilation. In this mode assets are compiled when they are loaded for the first time. This is done by injecting a plugin to Rails application that forces live compilation process.

Rails.application.config.assets.compile = true

Example

Let’s create a simple Rails application that makes use of CoffeeScript.

rails new coffee-app
cd coffee-app
rails generate controller Hello index

Let’s add some CoffeeScript to app/assets/javascripts/hello.js.coffee file:

name = "CoffeeScript"
alert "Hello from #{ name }!"

If we start our application with “rails server” and browse,

http://localhost:3000/hello/index

we would see “Hello from CoffeeScript!”. This works in development mode without the need for assets precompilation. In production, Rails serves only precompiled static assets and does not fall back to assets pipeline which is disabled in production.rb:

config.assets.compile = false

With the support of assets precompilation we can push this application to CloudFoundry.com without any modifications.

vmc push coffee-app

If we go to http://coffee-app.cloudfoundry.com we would see our popup message as expected.

By taking advantage of these features, your Rails 3.1+ applications will properly precompile all your SASS, Coffee Script and ERB assets as intended.

- Maria Shaldibina
The Cloud Foundry Team

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Recent Changes in Node.js Modules Support

Since Cloud Foundry introduced npm support, we added several improvements that make deploying Node.js applications with dependencies easier, faster and more transparent to developers.

Easy development

When we introduced npm support in Node.js, in addition to generating “npm-shrinkwrap.json” file with locked down dependencies you were required to remove the “node_modules” folder. If this was too disruptive, you could create an “cloudfoundry.json” file with an “ignoreNodeModules” property set to ‘true’.

This wasn’t an obvious solution. So we decided to change it. Detection of native modules is now done automatically by analyzing module contents. To lock down module versions, you can simply use the “npm shrinkwrap” command and your application is ready to be pushed with or without bundled modules. With this change, we have deprecated ignoreNodeModules property.

If you want to store your application in a git repository without node modules, the next time someone clones it, he/she can just push it to CloudFoundry.com without any modifications.

Fast deployment

In addition to  npm, we also improved our cache system. There are two levels of caching now — fetched and compiled modules. All modules that have been fetched from the npm registry are cached locally and pulled from that cache from that point on. If a module contains native code, it gets compiled on Cloud Foundry and the compiled version gets cached as well.

Based on the information from npm-shrinkwrap.json, Cloud Foundry checks if the module has been provided with the application itself. If it is there, and contains native code, it rebuilds it as needed. If the module hasn’t been provided with the app, Cloud Foundry checks the local cache for the given module, and if it needs compilation, provides the cached version.

As module contents can be modified by users, we are using hash of module files as a cache key.

Local modules

There may be situations when you need to customize an existing node module or move a part of your application as a reusable module. In this case, you would want your local module to be used without any modifications and be rebuilt, should it contain native code.

With automatic detection of native code – such modules will be rebuilt on Cloud Foundry and cached, based on their contents for your next push.

More informative logging

In addition to these node improvements, you can now see a detailed log of what’s going on in log files. You can get log messages by running:

vmc logs application-name

We can see if npm support is enabled (npm-shrinkwrap.json was provided) and which node version we are using:

Installing dependencies. Node version 0.6.8

For each node module we can see its installation status:

Installing express@2.5.11 from local path

In case of a failure we can see an error message and/or npm error output.:

Failed installing bcrypt@0.5.0: Node version requirement >= 0.6.0 is not compatible with the current node version 0.4.12

Node-gyp

Modules using node-gyp for the installation process are now supported on CloudFoundry.com for node08 runtime. For node06 and node04 runtimes, Cloud Foundry falls back to node-waf if the module provides the wscript file.

Git URLs

Another recent improvement is that we also support git URLs in npm-shrinkwrap.json. They can be specified in “from” or “version” fields according to npm requirements and both methods are supported. We have a separate cache for git modules and they also get compiled on Cloud Foundry if they have native extensions.

Example

In the previous blog post on auto-reconfiguration we used a Node app, “calipso”,  and performed additional steps for npm support. Let’s see how pushing calipso works now.

First, we clone calipso source from github:

$ git clone git://github.com/cliftonc/calipso.git

Then, we install node modules and lock them down.

$ npm install
$ npm shrinkwrap

Now, we can push our application.

$ vmc push calipso-app --runtime=node08

As we push we add mongodb service and set memory to 256M.

Would you like to deploy from the current directory? [Yn]:
Detected a Node.js Application, is this correct? [Yn]:
Application Deployed URL [calipso-app.cloudfoundry.com]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [64M]: 256M
How many instances? [1]:
Bind existing services to 'calipso-app'? [yN]:
Create services to bind to 'calipso-app'? [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-62f4d]:
Create another? [yN]:
Would you like to save this configuration? [yN]:
Creating Application: OK
Creating Service [mongodb-62f4d]: OK
Binding Service [mongodb-62f4d]: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (82K): OK
Push Status: OK
Staging Application 'calipso-app': OK
Starting Application 'calipso-app': OK

That’s it! We didn’t need to configure our application at all. In addition,  notice that staging process was faster and the preparation was effortless. When we look at the logs we can see how everything went. Try it and see how easy it is to manage your dependencies in Node.js applications now.

- Maria Shaldibina
The Cloud Foundry Team

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Preserving Cloud Application Portability – Introducing Cloud Foundry Core

The Cloud Foundry team is happy to announce Cloud Foundry Core  -  a program designed to preserve cloud application portability.

In the cloud computing world, preserving a choice of clouds is critical. The risks of being locked into a single cloud are substantial. Pricing, reliability, geographic location and compliance can all vary between clouds. Business requirements will evolve over time, necessitating the ability to move between clouds, whether public to private, private to public or between public cloud providers.

Cloud Foundry Core provides a baseline of common capabilities and an open mechanism to instantly validate application portability.

Cloud Foundry Core defines specific versions for application services and runtimes and introduces a system of current, next, and deprecated to provide access to feature innovation, enhanced performance and greater stability as applications continue to evolve.

AppFogTier 3Uhuru SoftwareMicro Cloud Foundry™ and CloudFoundry.com are now Core compatible as part of their commitment to preserving cloud portability.

-Dekel Tankel
The Cloud Foundry Team

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

New Release of Micro Cloud Foundry

We are excited to announce a new version of Micro Cloud Foundry™ with a new set of features. Among those new features is a new process to streamline frequent updates so that we can maintain compatibility between Micro Cloud Foundry and any Cloud Foundry-based clouds, including CloudFoundry.com.

If you don’t have a Cloud Foundry
account yet, sign up here.

Micro Cloud Foundry is a complete version of the Cloud Foundry open PaaS, but it runs in a single virtual machine on a developer’s computer. Micro Cloud Foundry exemplifies how a multi-cloud approach to PaaS can help developers easily develop and test their applications locally and deploy to any Cloud Foundry-based clouds with no code or configuration changes.

Download the new Micro Cloud Foundry here.

In this blog, we will review notable new features and focus on how we will be releasing Micro Cloud Foundry going forward.

What’s New

We have a new Micro Cloud Foundry for you to download. Since the release of the last version (1.2), there have been many new features that have been implemented for Cloud Foundry. Now these features have been made available on Micro Cloud Foundry. Let’s review some of them:

  • Standalone apps support: This feature enables a new class of apps including background apps such as Resque workers, apps with bring-your-own-container, and Spring background tasks.
  • Enhanced Ruby support: While Cloud Foundry always offered auto-reconfiguration for relational databases for Ruby apps, we’ve since extended it to all service types, enabling many more applications to deploy to Cloud Foundry without changing a single line of code. We now also offer improved support for Rails 3.1 and 3.2 apps, Rack as a supported framework, the ability to run JRuby apps, and apps that specify git URLs in their Gemfiles along with numerous small improvements to make a much wider range of applications work well in Cloud Foundry.
  • Enhanced Java support: Java 7 support, which enables applications such as vert.x and containers that need NIO such as Netty.
  • Enhanced Scala support: We now offer explicit support for Play 2.0. You can also deploy apps using a Scala framework such as Unfiltered that requires Jetty and Blue Eyes that additionally requires the NIO support in Java 7.
  • Enhanced Node support: We took a comprehensive look at our Node.js support and made a series of improvements to make Node.js apps shine. We now offer NPM support, bringing it up to par with the Gemfile support for Ruby apps including support for packages specified as git URLs. We also offer auto-reconfiguration of all services for node.js apps.

Download the new Micro Cloud Foundry from the download site. While there, you may notice a few changes, especially the availability of multiple versions and curiously new version names. Let us explain what they mean.

Going Forward

One of the ways developers use Micro Cloud Foundry is to deploy applications during development, where Micro Cloud Foundry is used as proving ground. Rather than installing a web server (Tomcat, etc.), runtimes (Java, Ruby, etc.), and services (Postgres, MongoDB, etc.), you can do a single download of Micro Cloud Foundry, boot it up, and deploy your applications using ‘vmc push’. You can run Java and Node.js apps in debug mode, take advantage of JVM hotswap to obviate the need to restart apps after changes, use a shell to access applications and services in the Micro Cloud Foundry VM, and so on. And you could do all this without even being connected to the network thanks to the offline capability of Micro Cloud Foundry (allowing you to develop apps for the cloud while flying through the clouds!).  Once you have your app working, you can push it to CloudFoundry.com, your own in-house Cloud Foundry cloud, or one of Cloud Foundry’s multi-cloud partners.

For all of this flow to really work, it is imperative that Micro Cloud Foundry has the same functionality as CloudFoundry.com. This means we must continually update Micro Cloud Foundry to keep up with all the new improvements in the core code. Our manual process of building and testing the Micro Cloud Foundry VM simply wouldn’t be up to the task. So we took a hard look at how to make this a better process, starting with this release.

This is how we will proceed:

  • Frequent releases: We will now release Micro Cloud Foundry whenever a change is pushed to CloudFoundry.com (subject to passing automated testing). If you track the cf-release repository, you will see it tagged with a release version such as v116, v114, and so on. Micro Cloud Foundry versions will match the same tags (along with a timestamp) so you can tell if you need to update Micro Cloud Foundry in order to catch up with changes in CloudFoundry.com. Since the launch over a year ago, we have been updating CloudFoundry.com about twice a week so you can expect a new Micro Cloud Foundry release at the same frequency. Later, we will consider releasing even more frequently for those who want to stay on the bleeding edge.
  • Automated building and testing: In the earlier releases, while we had scripts that would build Micro Cloud Foundry, there was some manual process involved. We also had a QA team testing Micro Cloud Foundry. This was in part necessitated by the requirement to run on multiple platforms (Fusion or Workstation for Mac, Windows, and Linux). Given our desire to update Micro Cloud Foundry bits at the same frequency as CloudFoundry.com, automated building and testing becomes an obvious requirement. We have already automated building Micro Cloud Foundry and doing a basic verification. Over the coming months, we will automate most, if not all, aspects of building, testing, and distributing Micro Cloud Foundry. Of course, Micro Cloud Foundry like the rest of Cloud Foundry, is an open source project, so you can definitely pitch in.
  • Improved user interface: Automated testing requires that the tests be able to configure Micro Cloud Foundry. When we decided to automate building and testing, we realized that while there is a way to do this through the command interface (by directing terminal input and output), it is difficult to make this work in a robust manner. Independent of this, we have been pondering a web interface that will provide an experience similar to a home network router. In a few weeks, we will provide a REST interface to Micro Cloud Foundry along with a web interface replacing the terminal interaction.

We hope you will like what Micro Cloud Foundry has in store. You can follow our frequent releases on the Micro Cloud Foundry site.

-Ramnivas Laddad and Matt Boedicker
The Cloud Foundry Team

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

Administer Cloud Foundry with Mobile Apps

One of the neat things about Cloud Foundry is that, because the code is open source, it’s easy to see how the administration tools (such as the command line-based vmc) work. The Cloud Controller component has a REST API, which provides the ability to query and modify the Cloud Foundry environment. That means it is relatively straightforward to build a management user interface tailored to the platform you are using, or to the requirements and needs of a specific set of users.

To illustrate this, I made a really brief video which I tend to use when I’m speaking about the Cloud Foundry platform and ecosystem. What you see here are two iOS apps - CF Mobile Admin (App Store link) and the AppFog app (App Store Link) – which have the ability to connect to Cloud Foundry instances, list deployed apps, modify instances, stop or start applications and query detailed information about the available resources. These kinds of tools are useful if you don’t have vmc handy, and are obviously great for mobile usage. Note that both of these tools are provided by third parties, and not by the Cloud Foundry development team.

Several developers have asked me if there are equivalent apps for Android or Windows Phone. If there are, I haven’t found them yet. One other example of a custom third-party-provided administration UI–in this case, a desktop-based one–is the Microsoft Management Console (MMC) snap-in, Uhuru Cloud Manager, that Uhuru Software provides as a tool alongside its own PaaS offering. There’s clearly an opportunity to build user interfaces and tools to target platforms such as Android and Windows Phone, or indeed your choice of mobile or desktop OS.

If you come up with anything of your own, do let us know by commenting here on the blog, or by talking to us on Twitter: @cloudfoundry or via the hashtag #cloudfoundry.

Andy Piper, Cloud Foundry Team

Sign up for Cloud Foundry today to try out these mobile administration tools

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Redis in Action with Cloud Foundry

Redis is a popular open source, advanced key-value store project sponsored by VMware. It has been a Cloud Foundry core service from day one and is widely adopted by developers who love its performance and flexibility. In the following guest post we introduce Dr. Josiah L. Carlson who discusses his upcoming book Redis in Action and  describes how Redis is continuing to change the lives of developers.

Guest blog by Dr. Josiah L. Carlson, a well-known contributor on the Redis mailing list

Over the last several years, a wide variety of non-relational databases have been created to offer varying balances of performance, reliability, and non-relational data models. In late March of 2009, Redis arrived in the open source world and has since been adopted by developers at an increasing rate, driven by a combination of performance, flexibility and a data model that programmers are already familiar with: standard data structures.

To support the growing need for operational simplicity, VMware introduced Cloud Foundry as a way to reduce the effort and overhead required to install and configure a carefully chosen variety of services, languages and frameworks. Not surprisingly (at least to those of us in the community), Redis made the cut at launch, and Cloud Foundry has made a previously easy setup procedure even easier. Assuming you already have the open source vmc tools installed and already have an app set up and configured, installing Redis for use in Cloud Foundry is as easy as:

$ vmc create-service redis --bind <app>

Once you have Redis installed, using it from one of the supported Cloud Foundry languages is only slightly different than if you were hosting your own infrastructure, primarily due to configuration. There are a few articles that discuss the configuration and use of Redis with Cloud Foundry with Ruby, Java/Spring, and Node.js.

Why Redis?

Whenever I talk to an engineer who isn’t familiar with Redis, the first question I am asked is “why Redis?” On the one hand, the answer is very simple: It makes our jobs as engineers easier by addressing problems we need to solve better, in many cases, than relational databases, document databases, or plain key-value databases. By combining five different and familiar data structures stored 100 percent in memory (but also written to disk in one of two ways), Redis offers performance and data access features that are top-notch. An increasing number of engineers, myself included, owe their success in no small part to the use of Redis as a production service.

My history with Redis

I got my start using Redis from a friend and manager who assigned a bug tracker ticket to me, mentioning that I might want to take a look at Redis to handle an internal search over some client data. Nothing too extraordinary, and it was something that Lucene could easily handle out of the box. But there was something about Redis that caught my attention. Because it was only my second task since joining the company, it was reasonable to take a little time to explore a new technology. Around two weeks later, we deployed a new internal search engine that was built using Redis hashes to store sortable data and Redis sets to store search terms. A series of set intersections followed by a sort call actually executed the search, which filtered and sorted over some 60,000 records in 50 milliseconds, or around 200 times faster than what our previous system managed. (I have previously written about a more web-page specific type of search on my blog.)

After arriving at such easy and quick success developing and deploying applications with Redis, I joined the mailing list with a few feature requests. Ultimately, only one of my requested features made it in, but in the Redis community I found a wide variety of problems posted by other developers, and I couldn’t resist offering advice on possible solutions. The breadth of problems posted to the list, along with my own experiences developing over a dozen Redis-backed tools and systems for my now past and current employers, combine to fill the pages of Redis in Action with real problems and their solutions. These are solutions that you can use today on a variety of problems with some of the most popular programming languages.

While Redis in Action is not yet complete, you can find four chapters available today through Manning’s Early Access Program, with at least one additional chapter to be released in June, and one to two chapters every month until it is done. Python source code is included in the book but translations to Ruby, Java and Node.js will be available before the printed edition is available.

Use the code 12ria39 for a 39 percent discount when you pre-order Redis in Action at: http://www.manning.com/carlson.

Dr. Josiah L. Carlson is well known as an active and helpful contributor on the Redis mailing list. He has given talks about real-world uses of Redis, including building a self-service ad network, prioritizing task queues, web spiders, a Twitter analytics platform, real-time search engines and more.

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

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Cloudfuji Accelerates Delivery of Its Open Source Application Store with Cloud Foundry

Unlike most Platform as a Service offerings today, the open and extensible nature of Cloud Foundry means developers will not be locked into a single cloud or remain beholden to the feature set delivered based on a vendor’s timeline. This month, in our series of guest blogs by application developers, we are featuring the story of Cloudfuji, a modern business application store that uses Cloud Foundry to keep itself nimble and focused on getting to market quickly.

Guest blog by Sean Grove, co-founder of Cloudfuji:

We built Cloudfuji, our modern business application store, on the principle that amazing apps should be 1) easy to make, 2) easy to find, and 3) seamlessly work together. We all have had the experience of data getting stuck in the silos of our individual departmental support systems. Lacking integration, we have been forced to manually copy and paste data from one app to another or using one-off API integrations between the apps. In that scenario, the process of simply finding, trying, provisioning and maintaining the best application can be a nightmare.

With Cloudfuji’s application store, end users can find and instantly launch high-quality open source business applications for bug tracking, agile projects, or CRM, to name a few, that are loosely coupled in a publish-subscribe model with a standardized event schema. This allows them to work not only with each other, but also with the outside world and proprietary legacy applications. This also brings enterprise-wide visibility into events such as real-time notifications on product, sales and marketing activities, regardless of which specific apps are being used. The app development pattern becomes one of small, focused tools that excel at their specific function, and allow other apps to handle anything else. This is the future of the application ecosystem.

The future has demanding technical requirements

 
Figure 1: Cloud Foundry and Cloudfoundry.com used in Stateless Binary Execution Engine
Figure 1: Cloud Foundry and CloudFoundry.com used in Stateless Binary Execution Engine

We use the Rails framework for our front end, which allows us to model our problem domain and iterate extremely quickly. Ruby is mainly used as a light layer for accessing more powerful services underneath such as Mailgun, Redis, RabbitMQ, and AWS S3. Once a user launches an app, we deploy it to the Binary Execution Environment (BEE).

Initially, we had built out our own LXC-based infrastructure, which was a Sisyphean and wasted effort in hindsight. We were continually reinvening a wheel called PaaS that was readily available in amazing forms right off the shelf. We tried a popular Ruby PaaS provider but faced challenges working with their closed platform as we had no influence over their release schedule.

When the open source Cloud Foundry project became available, we quickly got it running within two days without needing any support and had a provisioning system written for it within the week! Since then, we have scaled out our Cloud Foundry instance, built custom end-points to handle any deeper integration or visibility we need into the system and added CloudFoundry.com. The BEE is designed to be completely stateless and the data is decoupled from it. Because the BEE is not associated with data that an app relies on, we can replace it with a new one if the need arises, such as an outage in underlying infrastructure, and temporarily migrate the apps.

Why Cloud Foundry works for us

  • Time-to-market: Although our experience with other PaaS layers led us on a convoluted path, we were able to immediately piggyback on the great work already done on Cloud Foundry. This meant we could stop focusing effort into the lower layers of PaaS–custom kernels, LXC-based para-virtualization, resource management, node health, routing systems, system-level library compatibility and consistency. Time is the biggest killer for startups, and we could easily have stalled in the quagmire of rolling out our own systems. We consider it a bullet dodged.
  • Momentum: Having an open platform where the community can chip in means continuous improvement of the platform in faster cycles. When an open source project has the momentum of a whole community behind it, other projects simply cannot keep up. We’ve already benefited tremendously from work that wasn’t done by us, but by other extremely capable individuals. And in turn, when Cloudfuji needs a new feature, we have the choice of putting it out to the mailing list/community or rolling up our sleeves and writing it ourselves. And for all our respect for other platforms out there, none of them offer anything like this.
  • Target API-identical clouds with a single config setting: Getting a Cloud Foundry system for development in the cloud is a very simple exercise. Although we’re currently also running our own instance of Cloud Foundry, ultimately we expect to be able to offload more to the CloudFoundry.com service when it comes out of beta and can match our demanding needs. We expect that transition to happen almost seamlessly because of the design of both our system and of the Cloud Foundry project.
  • Flexibility to address changes to our business model: Finally, the ability to seamlessly run applications on multiple Cloud Foundry clouds, i.e., move from a public cloud to a private cloud, or vice versa, enables us to plan for a future offering where we can run a Cloudfuji appliance behind the firewall for parties that can’t use public clouds (for example, to meet local compliance needs or because of geographical location).

Taking the next steps

Applications should be easy to create and use. IT services should focus on their strengths and get end users the resources they need, when they need them. We live in a world where we get to take PaaS for granted and leverage great technology that is readily available. We all stand on the shoulders of giants, and we build more amazing products faster than ever before because of it. It’s a cycle we all need to embrace and increasingly reap the benefits from. Choose the open platforms that have strong leadership and excellent communities, and get behind them. It is amazing that we at Cloudfuji are building something of such scale and internal complexity, while staying lean and moving fast with the help of various communities. We couldn’t do all of that without Cloud Foundry.

-Sean Grove

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

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email