Cloud Connected

The Beauty of Cloud CMS Chaining

Chaining is a common technique that has been widely adopted by modern JavaScript libraries to chain method calls together.

The goal of chaining is to produce elegant and concise code that is easy to understand or maintain. For example, if you are a jQuery developer, you may produce similar code like this on daily basis.

$('#mydiv').empty().html('Hello Word!').css('font-size','10px');

However, most popular JavaScript libraries only support “static” chaining, e.g. DOM object manipulation. If the method to be chained makes Ajax calls, you will have to resort to callback which requires very strict and verbose syntax.

Again, let us take a look at a jQuery example that chains two serial Ajax calls.

$.ajax({
  url: 'service/endpoint1',
  success: function(data1) {
    // we have successfully made our first ajax call
    // and we are ready for our second ajax call
    $.ajax({
  	url: 'service/endpoint2',
  	success: function(data2) {
    	  // we have successfully chained two ajax calls 
  	},  	
  	error:function(error2) {
  	  // handle error from the second ajax call
  	}
    });    
  },
  error:function(error1) {
  	// handle error from the first ajax call
  }
});

The callback approach used by the above example looks clean and will do exactly what we expect. However the challenge is when we need to chain very large number of ajax calls the above code will grow significantly. With many levels of nesting, it will become very unpleasant to read or maintain and you will really miss the simplicity that chaining brings.

Before we introduce Cloud CMS chaining, let us look at another common use case of making parallel Ajax calls. It is easy to make concurrent Ajax calls but the challenge is to find out when all parallel calls finish and then execute the code that processes the returned results.

A simple and effective approach is to maintain a counter that tracks number of finished Ajax calls.

function processResults (result1, result2) {
// process returns from two parallel ajax calls } var count = 0, result1, result2; $.ajax({ url: 'service/endpoint1', success: function(data1) { result1 = data1; count ++; if (count == 2) { processResults (result1, result2); } }, error:function(error1) { // handle error from the first ajax call } }); $.ajax({ url: 'service/endpoint2', success: function(data2) { result2 = data2; count ++; if (count == 2) { processResults (result1, result2); } }, error:function(error2) { // handle error from the second ajax call } });

In the above example, we will make sure we get return from both Ajax calls before executing the processResults function. Just as the case for serial calls, you will definitely prefer chaining over using callbacks or explicitly managing the state of Ajax calls.

Now let us talk about the dynamic chaining that Cloud CMS introduces.

Cloud CMS is a content platform that help you build cloud-connected applications. When you build a Cloud CMS application, your application will interact with Cloud CMS platform through its REST APIs. In order to provide pleasant programming experience to developers, it is critical for Cloud CMS to have a driver that times or coordinates multiple REST/ajax calls in a very easy manner. That is why Cloud CMS provides a JavaScript Driver which comes with support for dynamic chaining.

The driver provides a Chain class that allow you to instantiate, extend or end a chain. A chain can carry an underlying proxied object which performs proxied Ajax calls to the REST services that Cloud CMS provides.

A chain can also be extended with a different proxied object if needed. The driver provides a list of “Chainable” classes that can be instantiated as the proxied objects for the chaining. For example, the Repository class will provide methods that deals with repository related or its sub-level objects related operations such as updating repository, creating new branch etc.

So when we make a call to

repository.readBranch('master');

it will make a proxied GET call to retrieve details of the master branch of the repository. 

The call will look like

http://localhost/proxy/repositories/aaa718b9bd29f76f443b/branches/master?metadata=true&full=true&cb=1338678288323

where aaa718b9bd29f76f443b is the repository id.

Please note that Cloud CMS JavaScript driver doesn’t reinvent the way to manage Ajax calls.

Under the hood, it still uses the callback approach to time the ajax calls and use the counter approach to keep track the parallel calls. It just provides utilities and simple APIs that shield developers away from dealing with those details.    

Let us start with a simple example that manage the life cycle of a simple chain which doesn’t deal with Ajax call.

 // Create a new chain
 Chain().then(function() {
  var data = 'Marry ';
   // Extend the chain
   this.subchain().then(function() {
     data += 'has a little ';
   }).then(function() {
      data += 'lamb.';
      // We should have "Marry has a little lamb." at the end the chain.
   });
 });

Now let us take a step further and try to use a chain with proxied objects to create a new node under the master branch of a given repository.

new Gitana({
   "clientId": "SOMEID",
   "clientSecret": "SOMESECRET"
}).authenticate({
   "username": "SOMEUSERNAME",
    "password": "SOMEPASSWORD"
 }).readRepository("SOMEREPOSITORYID").readBranch('master').createNode().then(function() {
    // we have successfully created a new node
});

In the above example, it first creates a new client with correct credentials. Once it is authenticated, it creates a new chain with a proxied Platform object. The Platform object will then be used to read the repository with the given ID.

The chain will then be extended and the underlying proxied object will be switched to a proxied Repository object populated from the previous ajax call response. It will keeps the chain going by reading the master branch (switching the proxied object to Branch) and then creating a new node under it (switching the proxied object to Node).        

If we want to extend the example to create three new nodes in serial, the example will look like

new Gitana({
   "clientId": "SOMEID",
   "clientSecret": "SOMESECRET"
}).authenticate({
   "username": "SOMEUSERNAME",
   "password": "SOMEPASSWORD"
}).readRepository("SOMEREPOSITORYID").readBranch('master').then(function() {
    this.createNode();
    this.createNode();
    this.createNode();
    this.then(function() {
     // we have successfully created three new nodes by making serial calls
    });
});

Now if we want to create new nodes in parallel, we can do something like this

new Gitana({
   "clientId": "SOMEID",
   "clientSecret": "SOMESECRET"
}).authenticate({
   "username": "SOMEUSERNAME",
   "password": "SOMEPASSWORD"
}).readRepository("SOMEREPOSITORYID").readBranch('master').then(function() {
   var f = function(){
      this.createNode();
   };
   this.then([f,f,f]).then(function() {
      // we have successfully created three new nodes by making parallel calls
   });	
});

As you can see from the above examples, the driver significantly simplifies the code with chaining. It makes the code easier to read and less error prone. It follows the human’s nature feeling of synchronous chaining while dealing with actual asynchronous ajax calls under the hood.   

Before we wrap up this blog, let us take a look a more complex example that does mix of serial ajax calls and parallel calls. It will also show how to manually switch the underlying proxied object by using subchain method.

new Gitana({
   "clientId": "SOMEID",
   "clientSecret": "SOMESECRET"
}).authenticate({
   "username": "SOMEUSERNAME",
   "password": "SOMEPASSWORD"
}).readRepository("SOMEREPOSITORYID").readBranch('master').then(function() {
   var node1, node2, node3;
   var f1 = function() {
      this.createNode().then(function() {
         node1 = this;
      });
   };
   var f2 = function() {
      this.createNode().then(function() {
         node2 = this;
      });
   };
   var f3 = function() {
      this.createNode().then(function() {
         node3 = this;
      });
   };            
   this.then([f1,f2,f3]).then(function() {
      // we have successfully created three new nodes by making parallel calls
 // we now associate node2 to node1 ( node1 ==> node2)
     this.subchain(node1).associate(node2).then(function() {
         // we have successfully associated node2 with node1
     });	
     // At this point, node2 has already been associated with node1
     // we then associate node2 to node3 ( node3 ==> node2)
    this.subchain(node2).associateOf(node3).then(function() {
        // we have successfully associated node2 with node3
	// The chain will end at this point.
    });                
  });	
});

For live chaining examples, please check out our online JavaScript Samples.

Introduction to Changeset Versioning

Cloud CMS provides you with content repositories that are powered by a “changeset” versioning model.  This a powerful versioning model that you won’t find in most conventional CMS products.  It’s one of the reasons why Cloud CMS is such a great platform for collaboration!

Document-level Versioning

A lot of legacy CMS products feature document-level versioning.  With document-level versioning, when you make a change to a document, the system simply increments a version counter.  You end up with multiple versions of your document.

It might look something like the following:

We all have or had an awesome grandparent who knew how to cook something good. For a recipe stored in a Microsoft Word file, the document-versioning model works pretty well!

Problems with Document-level Versioning

That said, there are some major drawbacks.

  1. Desktop Documents Only.  Document-level versioning is really only good for desktop documents (like Microsoft Office files) where everything (all of your nested images, fonts, etc) are contained within a single file.

    That’s why Dropbox uses file-level versioning.  It makes sense for people who work almost exclusively with desktop documents.
     
  2. No way to handle Sets of Changes.  If you’re working on mobile applications, web sites, or just about any non back-office projects, your content will be spread over multiple files.

    Think about a web site.  A web site might have hundreds or thousands of files - things like HTML, CSS, JS, image files and much more.  When you publish a web site, you really want to version the full set of files all at once so that you can push, pull and roll back updates to your web site.
     
  3. Bottlenecks.  If you’ve ever worked with Microsoft Sharepoint or any document-versioning CMS, then you’re aware of the bottlenecks that get introduced when two people want to work on something at the same time.  Either they both make changes (and you have to manually merge them together) or one person locks the file and the other person is sits on their hands.

    Most products that feature document-level versioning do so simply because it’s easy to implement.  However, it leaves your business users with the extremely limited tools for collaboration.  This makes collaboration frustrating as it cuts off people’s initiative, creativity and productivity.
     
  4. No ability to scale.  Okay, so let’s suppose now that you want to scale your content ingestion and production capabilities out to the broader world.  You might want to pull in content from Twitter, Facebook or Quora in real-time.  And let a broad community collaborate together…

    Nah, forget it.  With document-level versioning, that’d be like give everyone a phone and telling them to call each other.

    And then only giving them one phone line.

Changeset Versioning

Fortunately, this problem has been solved.  The solution comes out of the source control world and it is known as distributed “changeset versioning”.

If you’ve ever used Git, Mercurial or any modern source control software, then you’re already familiar with the concept.  It’s been around for awhile and has become extremely popular since it enables folks to work unimpeded, fully distributed and without any of the headaches of file locking and so forth.

It should be noted.  Cloud CMS is the only Content Management System to offer changeset versioning.  We’re it.  Why?  I suppose because it is hard to implement.  

And maybe because everyone else is busy chasing the desktop document problem.  However, if you’ve ever try to build a web or mobile app or tried consuming social content from Twitter, Facebook, LinkedIn, etc… well, then you know it’s all about JSON, XML, object relationships, lots of composite documents, highly concurrent writes and reads and so on!

Only your sales person will believe that a document-versioning system could be used for that purpose!

Changeset Versioning: The Basics

This article by no means intends to provide a Masters thesis on how changeset versioning works.  However, lets delve into the basics!

Let’s start with writing, editing and deleting content.  

When you write content into the Cloud CMS repository, your content gets stored on a “changeset”.  A changeset is a lot like a transparency (from the old transparency projector days).  This is a see-through sheet of plastic that you write on with one of those Sharpie pens.  The projector projects whatever you write up onto the screen.

The cool thing about transparencies is that you can layer them, one on top of the other.  What ends up getting projected is the composite of everything layered together.

So when you write content, the repository basically gets a new transparency and puts your content onto it.

If you make a change, it gets out another transparency, writes your change and layers it on top.

It also does this if you delete something.  It gets out a new transparency, masks (or covers up) your content so that it appears deleted.  

However, your content isn’t really deleted.  It is safe and tucked away somewhere in the stack of transparencies.  It’s just been hidden by the top-most transparency!

You can write as many things onto a changeset (transparency) as you want.  Cloud CMS manages the changesets for you, keeps them in a nice stack and lets you roll back changes if you make a mistake anywhere along the way.

Changeset Versioning: Branches and Merges

As noted, Cloud CMS manages your changesets for you.  The “stack” of changesets is known as a Branch.  As you add more changesets to the branch, the length of the branch gets longer (just like the stack of transparencies gets thicker).

A read operation simple pulls information out of the repository.  A write or a delete adds a new changeset.  Consider the branch shown below.  The reading operation just peeks at the branch looking down from the top.  The writing operation adds a new changeset.

With just a single branch, you can still get into the situation where two people want to change the same file at the same time.  Cloud CMS lets you lock the object and all that kind of thing if you want.  Or, you can create new branches so that everyone can work together at the same time and on the same things.

It kind of looks like this:

Here we have two workspaces.  Each workspace has its own branch which was stemmed off of the Master Branch at changeset V5.  The first user works on Branch A and the second user works on Branch B.  Both Branch A and Branch B have a common ancestor (changeset V5 in the Master Branch).

This allows both users to do whatever they want without stepping on each other’s toes. They can update documents, delete things and create new content.  At any time, they can push and pull changes between their workspace and any other workspace.  This gives them a way to preview what other people are working on and merge their work into their own branches.  They can also merge back to the Master Branch.

Cloud CMS provides an elegant merge algorithm that walks the changeset history tree from the common ancestor on up.  It uses a JSON differencing algorithm to allow for JSON property-level conflicts (as opposed to document level conflicts).  And it provides content model and scriptable policy validation for the merged result.

The result is a highly collaborative experience that encourages your users to experiment and take a shot at contributing without the worry of blocking others or screwing up the master content.

In a future blog, we’ll cover the details of how branching and merging works.  Our approach is one that did not seek to reinvent the wheel but rather ride on top of the wonderful innovation that has already occurred over the last decade within source control tools like Mercurial, Git and Bazaar.

Multitenancy for Creative Agencies and Consultancies

This month we’re going live with a 2.0 release of Cloud CMS, hosted in the cloud, which delivers on most of the multitenant features that our clients were asking for.

Multitenancy is a big word.  However, the concept is pretty simple.  I thought I’d write a blog post to give our audience an idea of what it means to us and to explain how this feature makes Cloud CMS the ideal content platform for small businesses, creative agencies and consultancies.

Platforms

When you sign up for Cloud CMS, you get your own platform.  You’ll get an email from us with all of the details about how to access your platform.  This includes a vanity URL which might be something like:

   https://mycompany.cloudcms.net

Logging in to your platform is basically as simple as just pointing a web browser to this URL.  We give you a command console that you can use to visually administer your console as well as deploy new HTML5/Javascript applications.  We can host these applications for you, or you can choose to deploy them to your own infrastructure.  

If you use our auto-deploy feature, we’ll mount them against your vanity URL.  For example, you might choose to create an instance of our HTML5 “kiosk” application for the upcoming CMS Expo in Chicago.  You can instantly deploy to a URL like this:

  https://mycompany.cloudcms.net/cmsexpo

You can do anything you want with your platform.  It’s yours.  When you sign up with Cloud CMS, you choose a subscription which gives you all the disk space and data transfer you need.  So you’re free to create, upload or deploy as many things as you want.  The platform is yours.  All of your data is secure.  Nothing is shared with anyone else (unless you invite them).

Example: Creative Agency and Three Applications

Suppose you are a creative agency.  You’re hip and snazzy.  You have a few talented front-end developers.  Maybe you produce videos and help companies manage their social presence alongside their applications and initiatives.

One of your customers wants to create three applications for the upcoming “State Fair”.  This is a multi-day indoor-outdoor event and so the customer would like to make available the following:

  • Two on-premise kiosks by the entry way that attendees can use to learn about the fair, sign up for events and provide their contact information for subscriptions to newsletters and access to product discounts.
  • A promotional web site for the web site that operates year-round.
  • An iPad app available through the Apple App Store that attendees can download to help navigate their fair while they’re on-premise.  As well as keep in touch after the event is over.

Cloud CMS helps you, the creative agency, create and deliver the infrastructure needed to support these applications.  What might you need?

  • Content Repositories - A content repository is where you manage the content that appears in your applications.  Things like articles, images and any textual or visual elements that you may want to change in real-time.  Content Repositories offer content modeling, collaboration, changeset versioning, workflow and full lifecycle management. 
  • Domains - A domain is where you store your users, groups and memberships.  As people sign up for your applications, you may want to create accounts and logically organize them.  This lets you automatically personalize content delivery based on what groups users belong to and things like that.
  • Directories - A directory stores the usernames and passwords for any accounts you create.  They also store access and refresh tokens for users who sign in so that they don’t have to sign in all over again each time.
  • Applications - Every application you deploy gets its own data store for managing things like registrations, email dispatches, click-backs, as well as application settings on a user, page and global level.
  • Warehouses - A warehouse is a location where real-time interaction data is stored.  As the State Fair attendees use your customer’s applications, warehouses capture what they’re clicking on (or touching) and utilize map-reduce algorithms to provide real-time insight for your marketing team’s lead generation efforts.

Finally, you need Stacks.  A stack is a logical arrangement of these data stores into something that you can manage on a per-customer or per-project basis.  Stacks let you manage team permissions across all data stores in a single place.  Cloud CMS lets you carve out stacks, archive them and also duplicate them so as to quicken the pace of building and deploying your next application.

Multitenancy

One of the things you’ll find in your platform is that you’re allowed to create Registrars. A Registrar is a data store that holds billing, subscription, plans and sub-tenants for your platform.  By default, your platform won’t have any Registrar instances but you’re free to create one (or more) if you want.

Why would you create a Registrar?  Well, imagine that your customer (the State Fair people) would like to manage their own content in real-time during the event as well as retain ownership of the data after the event is over.  They’d essentially like to have their own content platform that they can sign in to but which you, the creative agency, can help manage.

Cloud CMS lets you “whitelabel’ your platform for this situation.  Using a Registrar, you create a new tenant called for your State Fair customer.  This gives them their own platform along with their own vanity URL.  You can either use the default one:

  https://statefair.cloudcms.net

Or you might elect to set up your own DNS services (Apache conf) and have it be:

  https://statefair.creativeagency.com

It’s really up to you.  At any rate, the State Fair now has their own platform that is co-managed by you and the State Fair.  The Cloud CMS branding elements are removed and replaced by the branding elements of your own creative agency.

Registrars give you a way to define subscription plans and quotas for the State Fair.  You might wish to limit them to a certain amount of data storage or transfer, for example.  Or you might want to utilize the integrated billing features of Cloud CMS to have monthly credit-card transaction processing.

Basically, anything we can do, we make it available to you so that you can also use it for your tenants.

Multitenancy is a core feature of the Cloud CMS platform that lets creative agencies or consultancies whitelabel the platform their own clients.  It means that Cloud CMS gives you full control over the platform accessibility and experience.  Cloud CMS maintains the responsibility of maintaining the infrastructure and software, from platform upgrades to elastic, auto-provisioning of nodes for performance and scalability.