<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Official Rackspace Blog &#187; Tomaz Muraus</title>
	<atom:link href="http://www.rackspace.com/blog/author/tomaz-muraus/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rackspace.com/blog</link>
	<description>The Official Rackspace Blog</description>
	<lastBuildDate>Wed, 22 May 2013 15:00:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Develop On The Rackspace Open Cloud With Vagrant</title>
		<link>http://www.rackspace.com/blog/develop-on-the-rackspace-open-cloud-with-vagrant/</link>
		<comments>http://www.rackspace.com/blog/develop-on-the-rackspace-open-cloud-with-vagrant/#comments</comments>
		<pubDate>Thu, 14 Mar 2013 16:00:12 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Open Cloud]]></category>
		<category><![CDATA[Open Source Technologies]]></category>
		<category><![CDATA[Product Discussion]]></category>
		<category><![CDATA[Tips for Devs and Sys Admins]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[open cloud]]></category>
		<category><![CDATA[vagrant]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=27995</guid>
		<description><![CDATA[Developing on the Rackspace Open Cloud is now easier with the new Rackspace provider driver in Vagrant 1.1.]]></description>
				<content:encoded><![CDATA[<p>Developing on the <a href="http://www.rackspace.com/open-cloud/">Rackspace Open Cloud</a> is now easier with the new Rackspace provider driver in <a href="http://www.vagrantup.com/">Vagrant 1.1</a>!</p>
<p>Vagrant is a Ruby-based tool for building and deploying virtualized development environments. Developers love it because it allows them to easily create and deploy reproducible development environments.</p>
<p>With Vagrant 1.1 and the new Rackspace driver you aren’t limited to your local machine and VirtualBox anymore. You can now also run your development machines on the Rackspace Open Cloud.</p>
<p>This allows you to utilize all of the <a href="http://www.rackspace.com/cloud/servers/compare/">benefits of the Rackspace Cloud</a>, such as instances with up to 30 GB of memory, virtual machine snapshots, server resizing and more.</p>
<p>For information on how to get started and more in depth look of the advantages of Vagrant 1.1 on the Rackspace Open Cloud, head over to the <a href="http://devops.rackspace.com/vagrant-now-supports-rackspace-open-cloud.html#.UUH3ZGemgwM">DevOps Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/develop-on-the-rackspace-open-cloud-with-vagrant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Storing Service Metadata: A Service Registry Use Case</title>
		<link>http://www.rackspace.com/blog/storing-service-metadata-a-service-registry-use-case/</link>
		<comments>http://www.rackspace.com/blog/storing-service-metadata-a-service-registry-use-case/#comments</comments>
		<pubDate>Thu, 21 Feb 2013 16:00:33 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Cloud Industry Topics]]></category>
		<category><![CDATA[Open Cloud]]></category>
		<category><![CDATA[Open Source Technologies]]></category>
		<category><![CDATA[Product Discussion]]></category>
		<category><![CDATA[Tips for Devs and Sys Admins]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[open cloud]]></category>
		<category><![CDATA[Rackspace Service Registry]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=27153</guid>
		<description><![CDATA[There are several use cases for the Rackspace Service Registry. Let's dig deeper into storing service metadata in Service Registry.]]></description>
				<content:encoded><![CDATA[<p>Late last year, <a href="http://www.rackspace.com/blog/keep-track-of-your-services-and-applications-with-the-new-rackspace-service-registry/">we launched the Rackspace Service Registry into preview</a>. The tool helps developers make their applications highly available through exposing the building blocks for automation and centralized configuration storage. It is one of the first Rackspace services focused on <a href="http://www.rackspace.com/blog/service-registry-behind-the-scenes-why-we-built-it/">helping our customers run and automate their application</a> versus their infrastructure.</p>
<p>There are several use cases for Service Registry. On the <a href="http://devops.rackspace.com/">Rackspace DevOps Blog</a>, I dig deeper into <a href="http://devops.rackspace.com/service-registry-use-cases-storing-service-metadata-in-the-registry.html#.USY7IHee4vQ">storing service metadata in Service Registry</a>.</p>
<p>Each service object in the Service Registry has a <i>metadata </i>field that stores arbitrary string key and value pairs. Some of the common values you can store in this field include application version, the region and data center where the service is running, the timestamp of when a service started, JMX port for Java services and a stats port. That information can be used to display a list of services with on an internal dashboard; for client side filtering based on some metadata attribute; and for finding services which are out of date.</p>
<p><a href="http://devops.rackspace.com/service-registry-use-cases-storing-service-metadata-in-the-registry.html#.USY_Inee4vR">Head over to the DevOps Blog</a> to read about this use case in more detail.</p>
<p>In upcoming posts we’ll look at more advanced use cases, including using service registry for middle-tier load balancing and using events feed as one of the information sources for your automation system.</p>
<p>Service Registry is currently in closed preview and is available free of charge. If you want access to the preview, you can request it by filling out <a href="https://surveys.rackspace.com/Survey.aspx?s=f3d6e51580ab4510a564487fafdafdfd">this survey</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/storing-service-metadata-a-service-registry-use-case/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Service Registry Behind The Scenes – Why We Built It</title>
		<link>http://www.rackspace.com/blog/service-registry-behind-the-scenes-why-we-built-it/</link>
		<comments>http://www.rackspace.com/blog/service-registry-behind-the-scenes-why-we-built-it/#comments</comments>
		<pubDate>Wed, 14 Nov 2012 16:00:38 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Cloud Industry Topics]]></category>
		<category><![CDATA[Open Cloud]]></category>
		<category><![CDATA[Product Announcements and Updates]]></category>
		<category><![CDATA[Product Discussion]]></category>
		<category><![CDATA[Cassandra]]></category>
		<category><![CDATA[Cloud Monitoring]]></category>
		<category><![CDATA[open cloud]]></category>
		<category><![CDATA[Rackspace Service Registry]]></category>
		<category><![CDATA[zookeeper]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=24946</guid>
		<description><![CDATA[Last week we announced the preview availability of Rackspace Service Registry. We want to give our customers some more insight into the Service Registry. This is the first article in a 'Behind the Scenes' series where I will talk in depth about different aspects of this product.]]></description>
				<content:encoded><![CDATA[<p>Last week we announced the preview availability of <a href="http://www.rackspace.com/blog/keep-track-of-your-services-and-applications-with-the-new-rackspace-service-registry/">Rackspace Service Registry</a>. We want to give our customers some more insight into the Service Registry. This is the first article in a “Behind the Scenes” series where I will talk in depth about different aspects of this product such as:</p>
<ul>
<li>Why we decided to build it.</li>
<li>How we built it (product architecture).</li>
<li>Best practices we have adopted for developing and deploying the product (continuous integration, continuous delivery / deployment, etc.)</li>
<li>How we use other Rackspace Cloud products such as Cloud Servers, Cloud Load Balancers, Cloud Files and Cloud Monitoring.</li>
<li>Product use cases.</li>
<li>How to integrate it into your application.</li>
</ul>
<p>In this blog post I will explain our motivation and reasoning for building it.</p>
<h2>Why did we build Rackspace Service Registry?</h2>
<p>While working on <a href="http://www.rackspace.com/cloud/public/monitoring/">Cloud Monitoring</a> we encountered several problems. One of them was that we had many different services but no easy way to keep track of them. Most services were already tracked in some way or another in Chef, but there were multiple problems with using Chef for this purpose:</p>
<ul>
<li>Our Chef setup is currently only deployed in a single region so it is not highly-available in the same way other components are.</li>
<li>Information in Chef isn’t real-time &#8211; Chef knows if some service should be present on some server, but it doesn’t know if service is actually up and / or running.</li>
<li>Chef was primarily built for applying configuration and keeping a set of servers in a consistent state that is defined in a set of cookbooks and recipes. As such, Chef primarily cares about the servers on which your application and services run. An ideal service registry shouldn’t need to know anything about the servers upon which those services run.</li>
</ul>
<p>Cloud Monitoring is a complex product composed of multiple services running on many servers in multiple regions.</p>
<div class="wp-caption alignleft" style="width: 633px"><img src="http://ddf912383141a8d7bbe4-e053e711fc85de3290f121ef0f0e3a1f.r87.cf1.rackcdn.com/service-registry-why-graphic.png" alt="" width="623" height="493" /><p class="wp-caption-text">Cloud Monitoring architecture &#8211; similar set of services runs in multiple data centers</p></div>
<p>If you are interested in more details about the Cloud Monitoring architecture, please refer to the great post Paul Querna wrote last year titled <a href="http://journal.paul.querna.org/articles/2011/12/17/technology-cloud-monitoring/">Technology behind Rackspace Cloud Monitoring</a>.</p>
<p>Usually the first thing we do when we need to solve a problem is look for an existing open-source project that already does what we need. In this case we could not find a project that fit our needs. We found <a href="https://github.com/lusis/Noah">Noah</a>, which looked really promising, but because it’s using Redis as a main data store it didn’t fulfill our main requirement &#8211; high availability without a single point of failure. Keep in mind that this was last year, long before Netflix announced <a href="http://techblog.netflix.com/2012/09/eureka.html">Eureka</a>.</p>
<p>Because we didn’t find a project that would fit our needs, we decided to build it ourselves on top of the excellent <a href="http://zookeeper.apache.org/">Apache ZooKeeper</a> project. Choosing Apache ZooKeeper had multiple advantages. We already used it for other operations such as leader election and distributed locking. This meant we were already familiar with its APIs and operations, so using it added no complexity or mental overhead to our project.</p>
<p>The data model and distributed architecture of Apache ZooKeeper make it a good fit for building a service registry on top of it.</p>
<p>The service registry we built in Cloud Monitoring is simple, but it makes service discovery and some other things a lot easier. Here are some examples:</p>
<ul>
<li>Service discovery &#8211; e.g. finding all the API servers located in ORD</li>
<li>Jobs discovery &#8211; We registered all the long running jobs (e.g. a script that calculates daily usage statistics, etc.) in the registry and this allowed us to see which jobs are currently running.</li>
<li>Version check &#8211; When registering an API server in the registry we included current version in the payload field. This allowed us to easily check which version of the software is running on which servers and check for potential version mismatches.</li>
</ul>
<p>We quickly saw that the service registry added a lot of value and simplified operations.  This motivated us to start thinking about how we could share it with other internal and possibly external users.</p>
<p>One approach would be to run a separate ZooKeeper cluster and service registry for each user/tenant, but this would be expensive to operate and maintain. Because of that we decided to build a new service registry using a SaaS model designed with multi-tenancy in mind from the start.</p>
<p>The new Rackspace Service Registry service builds on the core ideas and use cases we observed in Cloud Monitoring. While the original Cloud Monitoring service registry was simple and only offered service discovery, the new registry goes beyond that by offering useful features we think are helpful when building highly available and scalable applications. Some of these new features are listed below.</p>
<h3>Better object model</h3>
<p>In the Cloud Monitoring service registry we only had one object called service that could contain arbitrary key/value pairs in the payload field. This worked fine for our very simple and focused use case.</p>
<p>In Rackspace Service Registry we expanded this model and introduced a concept of a session and added “tags” and “metadata” fields to the service model. This allows users to use service registry in a variety of ways that were not possible with the previous model. You can learn about some of those ways in the next blog post where I will talk about some common use cases.</p>
<h3>HTTP + JSON</h3>
<p>In the Cloud Monitoring service registry, clients talked to the registry over TCP using a native binary ZooKeeper protocol.</p>
<p>In the Rackspace Service Registry we went with HTTP and JSON. In cases like this, a combination of HTTP + JSON has multiple advantages:</p>
<ul>
<li>It’s easier to start playing with it &#8211; you can use simple command line tools such as cURL.</li>
<li>It’s easier to build clients and talk to the service because almost every programming language supports HTTP.</li>
<li>It’s easier to debug issues because the text is human readable.</li>
</ul>
<p>In Rackspace Service Registry HTTP is also used for letting us know that the session is alive. This is done by heartbeating the session &#8211; periodically sending an HTTP POST request. Some people would argue that sending many heartbeats over HTTP is expensive, but we believe that with using HTTP/1.1 persistent connections this is not an issue.</p>
<h3>Events Feed</h3>
<p>We added an events feed that includes all of the events that have happened during the lifecycle of your account (e.g. a service comes online, a configuration value gets updated, etc.).</p>
<p>The events feed is a great information source about your infrastructure and can act as a platform for auto-scaling or be used to kick off a host of different automation processes.</p>
<h3>Configuration Storage</h3>
<p>Configuration storage allows users to store arbitrary configuration values in our system and get notified via the events feed when a value gets updated or deleted.</p>
<p>Storing all the configuration values in a centralized place allows for better visibility and easier introspection of the configuration data. It also allows applications to react to changes faster and makes automation of tasks that rely on those values a lot easier.</p>
<p>In a typical application you usually have configuration values stored in a config file and if you want to update it you kick off some process that updates the configuration file and restarts the service or sends it a SIGHUP signal.</p>
<p>With the Service Registry Configuration Storage feature you can poll the events feed for changes inside your application and once the value changes you can more easily and quickly react to those changes directly in your application.</p>
<h2>Conclusion</h2>
<p>I hope you’ve found this post helpful! If you haven’t signed up for the preview yet, I encourage you to do so by filling out <a href="https://surveys.rackspace.com/Survey.aspx?s=f3d6e51580ab4510a564487fafdafdfd">this short survey</a>. I also encourage you to come back next week when I’ll talk more in depth about why you might need Service Registry and present some typical use cases.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/service-registry-behind-the-scenes-why-we-built-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keep Track Of Your Services And Applications With The New Rackspace Service Registry</title>
		<link>http://www.rackspace.com/blog/keep-track-of-your-services-and-applications-with-the-new-rackspace-service-registry/</link>
		<comments>http://www.rackspace.com/blog/keep-track-of-your-services-and-applications-with-the-new-rackspace-service-registry/#comments</comments>
		<pubDate>Mon, 05 Nov 2012 16:20:00 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Cloud Industry Topics]]></category>
		<category><![CDATA[Open Cloud]]></category>
		<category><![CDATA[Product Announcements and Updates]]></category>
		<category><![CDATA[Product Discussion]]></category>
		<category><![CDATA[Cassandra]]></category>
		<category><![CDATA[open cloud]]></category>
		<category><![CDATA[Rackspace Service Registry]]></category>
		<category><![CDATA[zookeeper]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=24418</guid>
		<description><![CDATA[Rackspace Service Registry is an API-driven cloud service built to keep track of your services and store configuration values, which allows you to react to changes faster and make your application or service more highly-available.]]></description>
				<content:encoded><![CDATA[<p>High availability and agility are two of the main draws of cloud applications. With the new Rackspace Service Registry – available in preview today – we’re helping developers make their applications highly available through exposing the building blocks for automation and centralized configuration storage.</p>
<p>Rackspace Service Registry is one of the first Rackspace services focused on helping our customers run and automate their application versus their infrastructure.</p>
<h2>Rackspace Service Registry Overview</h2>
<p><strong>What is Rackspace Service Registry?</strong><br />
Rackspace Service Registry is an API-driven cloud service built to keep track of your services and store configuration values, which allows you to react to changes faster and make your application or service more highly-available.</p>
<p>The functionality that it exposes includes:</p>
<p><em><strong>Service Discovery</strong></em><br />
Find which services are currently online/active and find services based on different criteria. You can organize your services however best fits your application deployment.</p>
<p><em><strong>Platform for Automation</strong></em><br />
Service Registry exposes an events feed, which includes all of the events that have happened during the life-cycle of your account (e.g. a service comes online, a configuration value gets updated, etc.).</p>
<p>Events feed is a great information source about your infrastructure and can act as a platform for auto-scaling or be used to kick off a host of different automation processes, including:</p>
<ul>
<li>Add a web service to a load-balancer when it comes online</li>
<li>Open a ticket in the internal ticketing system when a services goes offline</li>
<li>Re-initialize the connection pool inside your application when a configuration value changes</li>
</ul>
<p><em><strong>Configuration Storage</strong></em><br />
Configuration storage allows users to store arbitrary configuration values in our system and get notified via the events feed when a value gets updated or deleted.</p>
<p>Check out <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/overview.html">API Guide</a>, <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/integration-instructions.html">Integration Guide</a>, <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/client-libraries-and-tools.html">Client libraries and tools</a> and <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/release-notes.html">Release Notes</a> for more details.</p>
<p><strong>Why did we build it?</strong><br />
Our primary motivation for building Service Registry was our need for it internally. We had already developed and used an internal project that offered a small subset of the features available in Service Registry, but it was difficult to maintain and scale.</p>
<p>When we started building the new product, we looked at what our current solution already offered and what we and our customers needed. The result is a Service Registry built on top of Apache Cassandra and Apache ZooKeeper that offers a lot of the functionality required for building highly-available services in dynamic environments.</p>
<p>We are releasing it as a cloud service because we want the general public to enjoy the same benefits we experience.</p>
<p><strong>How does it work?</strong><br />
Rackspace Service Registry exposes a REST based API, which means you communicate with it using HTTP(s).</p>
<p style="text-align: center;"><img class="aligncenter" src="http://ddf912383141a8d7bbe4-e053e711fc85de3290f121ef0f0e3a1f.r87.cf1.rackcdn.com/service-registry-graphic-1.png" alt="" width="474" height="355" /></p>
<p>The main concept in the Service Registry is a so called heartbeat. A heartbeat lets our system know that your service is alive and healthy. When a session is initially created, you must specify a heartbeat interval that defines how often you need to heartbeat the session.</p>
<p>If you don’t heartbeat a session in the defined interval, the session is considered dead, and a new event is inserted in the events feed that indicates the session and all of the services associated with it have died.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://ddf912383141a8d7bbe4-e053e711fc85de3290f121ef0f0e3a1f.r87.cf1.rackcdn.com/service-registry-graphic-2.png" alt="" width="635" height="444" /></p>
<p>For more information about the terminology and concepts please refer to the <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/overview.html">API documentation</a>.</p>
<p><strong>How do I integrate my services with it?</strong><br />
There are several options to integrate your services with Rackspace Service Registry:</p>
<p>1.  Download one of the official client libraries (currently we have libraries for Node.js, Twisted Python and Java) and include it in your service code.</p>
<p>If there is no client library for your programming language of choice and you want to build one yourself, be sure to check <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/client-libraries-and-tools.html">Best Practices for Writing Client Libraries</a> chapter in the documentation.</p>
<p>2. Use the “long-running process wrapper” tool which allows you to register arbitrary long-running processes with the Rackspace Service Registry.</p>
<p>Method No. 1 requires a bit more work on your side, but it offers more fine-grained level of control and it is the preferred method.</p>
<p><strong>How does it compare to Chef/Puppet/other configuration management solutions?</strong><br />
Rackspace Service Registry is not meant to replace configuration management systems like Chef or Puppet, but it can be used to augment their functionality.</p>
<p>In a lot of scenarios people store different configuration values in Chef inside attributes and data bags, and when performing a Chef run, configuration values get written out to a file on disk, and usually a service needs to be restarted or SIGHUP-ed to read those changes.</p>
<p>Service Registry allows users to store arbitrary configuration values on the server and be notified when a value changes or is deleted. This allows users to move this functionality into code and react to changes faster without interruption to the service.</p>
<p>A good use case for this is storing a list of database server IP addresses inside the configuration value in the Service Registry. Inside the code, users can poll the events feed for changes and re-initialize an internal connection pool when a value changes. This allows users to react to those changes faster compared to using other solutions such as using DNS hostnames instead of IP addresses.</p>
<p><strong>How is it different from Netflix’s Eureka?</strong><br />
Rackspace Service Registry is different from Netflix’s Eureka in multiple ways:</p>
<p><strong>1.  <em>It’s a hosted service</em></strong><br />
<strong>No Installation and Maintenance</strong>: Our service is a hosted service, which means we run it and operate it. This removes the load from your operations staff and allows you to put more resources into more business critical components of you application.</p>
<p><strong>Zero Downtime Update:</strong> Besides removing the operational load, the software as a service model allows you to benefit from continuous zero downtime updates, which are performed by our team almost every day.</p>
<p><strong>2. <em>It’s backed by Rackspace Fanatical Support</em></strong><br />
Like all of our services, Service Registry is backed by our trademark Fanatical Support. If you have a problem or need help, you can always call us and we will happily assist you.</p>
<p><strong>3. <em>It has a Configuration Storage feature</em></strong><br />
Besides the Service Registry, our service offers a Configuration Storage feature, which allows you to store arbitrary configuration values in our service and be notified via the event feed when they are updated or deleted.</p>
<p><strong>4. <em>It offers official client libraries for more programming languages</em></strong><br />
Netflix’s Eureka only has a single official client library written with Java. Starting with this preview, we offer official client libraries for the following programming languages:</p>
<ul>
<li>Java</li>
<li>Node.js</li>
<li>Twisted Python</li>
<li>Python</li>
</ul>
<p>Because we want to keep the user experience great, our goal is to also create and support official <a href="http://docs.rackspace.com/rsr/api/v1.0/sr-devguide/content/client-libraries-and-tools.html">client libraries</a> for other popular programming languages such as Ruby.</p>
<p><strong>Where can I apply for the preview?</strong><br />
To apply for the beta program, please fill out <a href="https://surveys.rackspace.com/Survey.aspx?s=f3d6e51580ab4510a564487fafdafdfd">this short survey</a> with your contact information and use case and we will determine your eligibility within 48 hours.</p>
<p>We look forward to hearing from you and getting valuable feedback, which will allow us to make product even better.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/keep-track-of-your-services-and-applications-with-the-new-rackspace-service-registry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Libcloud: New Features, Improvements</title>
		<link>http://www.rackspace.com/blog/apache-libcloud-new-features-improvements/</link>
		<comments>http://www.rackspace.com/blog/apache-libcloud-new-features-improvements/#comments</comments>
		<pubDate>Thu, 31 May 2012 15:41:04 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Open Source Technologies]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[libcloud]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=19715</guid>
		<description><![CDATA[Between 0.6.1 and current release (0.10.1) seven months of development took place and a lot of new features and improvements were added to Apache Libcloud.]]></description>
				<content:encoded><![CDATA[<p><a title="Libcloud | Apache.org" href="http://libcloud.apache.org/" target="_blank">Apache Libcloud</a> is an open-source Python client library that creates a standard interface for managing multiple cloud providers, including Rackspace.</p>
<p>Between 0.6.1 and current release (0.10.1) seven months of development took place and a lot of new features and improvements were added, which I want to talk about in this blog post.</p>
<h2><strong>Improvements In The OpenStack And Rackspace Drivers</strong></h2>
<p><strong></strong>OpenStack and Rackspace drivers received a lot of improvements and new features, including, but not limited to:</p>
<ul>
<li>Keystone 2.0 support (authentication),</li>
<li>New storage driver which works with OpenStack Swift installations</li>
<li>Large object upload support for CloudFiles driver</li>
<li>A lot of improvements and new extension methods in the Rackspace load balancer driver</li>
</ul>
<h2><strong>Python 3 Support</strong></h2>
<p>The 0.7.0 release introduced full support for Python 3. Libcloud is now one of the first Python cloud libraries that supports Python 2.5, Python 2.6, Python 2.7 / PyPy and Python 3 with a single code base.</p>
<h2><strong>Support For Compressed Responses</strong></h2>
<p><strong></strong>Since the 0.8.0 release Libcloud now knows how decompress and handle compressed responses (deflate, gzip). Compressed responses are usually much smaller than the uncompressed ones, which means this will save you a decent amount of bandwidth, especially if you do a lot of polling.</p>
<h2><strong>New Drivers</strong></h2>
<p>Since the latest update Libcloud has added support for more than 10 new providers and locations:</p>
<ul>
<li>CloudStack (compute)</li>
<li>OpenNebula v1.4, v2.x and v3.x (compute)</li>
<li>Joyent (compute)</li>
<li>VCL cloud (compute)</li>
<li>Vmware vCloud v1.5 (compute)</li>
<li>IBM SCE (compute)</li>
<li>libvirt (compute, experimental)</li>
<li>Amazon EC2 South America and Oregon locations (compute, storage)</li>
<li>ElasticHosts United States and Canada locations (compute)</li>
<li>CloudSigma United States location (compute)</li>
</ul>
<h2><strong>Conclusion</strong></h2>
<p>This is just a short list of new features and improvements that have landed in trunk in the last seven months. For a full list of changes, please see the <a title="Libcloud | Apache.org" href="https://svn.apache.org/repos/asf/libcloud/trunk/CHANGES" target="_blank">CHANGES file</a>. You can find more information including examples and a getting started guide, and follow Libcloud development and news on the project website &#8211; <a href="http://libcloud.apache.org/" target="_blank">http://libcloud.apache.org/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/apache-libcloud-new-features-improvements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>node-swiz &#8211; Node.js Library For Serializing, Deserializing And Validating Objects In REST APIs</title>
		<link>http://www.rackspace.com/blog/node-swiz-node-js-library-for-serializing-deserializing-and-validating-objects-in-rest-apis/</link>
		<comments>http://www.rackspace.com/blog/node-swiz-node-js-library-for-serializing-deserializing-and-validating-objects-in-rest-apis/#comments</comments>
		<pubDate>Wed, 30 May 2012 20:11:13 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Open Source Technologies]]></category>
		<category><![CDATA[Product Discussion]]></category>
		<category><![CDATA[Tips for Devs and Sys Admins]]></category>
		<category><![CDATA[Cloud Monitoring]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=19572</guid>
		<description><![CDATA[This is another post in the series about Cloud Monitoring and libraries we have open-sourced. In the first week I talked about Whiskey, a powerful Node.js test framework, in the second week Gary talked about the Cassandra CQL driver and in the third week I talked about node-elementtree, a Node.js library for building and parsing XML documents. This week I&#8217;ll talk about node-swiz, a [...]]]></description>
				<content:encoded><![CDATA[<p title="Cloud Monitoring Early Access Program | Rackspace Blog">This is another post in the series about <a title="Cloud Monitoring Early Access Program | Rackspace Blog" href="http://www.rackspace.com/blog/cloud-monitoring-early-access-program-opens-its-doors/" target="_blank">Cloud Monitoring </a>and libraries we have open-sourced. In the first week I talked about <a title="Rackspace Open Sources Whiskey | Rackspace Blog" href="http://www.rackspace.com/blog/rackspace-open-sources-whiskey-a-test-framework/" target="_blank">Whiskey, a powerful Node.js test framework</a>, in the second week Gary talked about the <a title="Rackspace Contributes to Cassandra CQL Drive for Node.js | Rackspace Blog" href="http://www.rackspace.com/blog/rackspace-contributes-cassandra-cql-driver-for-node-js/" target="_blank">Cassandra CQL driver</a> and in the third week I talked about <a title="node-elementtree - Node.js Library to Build and Parse XML Documents | Rackspace Blog" href="http://www.rackspace.com/blog/node-elementtree-node-js-library-to-build-and-parse-xml-documents/" target="_blank">node-elementtree, a Node.js library for building and parsing XML documents</a>. This week I&#8217;ll talk about <a title="Node-swiz | Github.com" href="https://github.com/racker/node-swiz" target="_blank">node-swiz</a>, a Node.js library for serializing, deserializing and validating objects in RESTful APIs.</p>
<p>An important building block of RESTful APIs is a system for serializing/deserializing responses and validating incoming data. Many other frameworks already have a library available (e.g. <a title="Django-Piston | Bitbucket.org" href="https://bitbucket.org/jespern/django-piston/wiki/Home" target="_blank">django-piston</a> for Python / Django), but when we started to work with Node.js there was no such library so we decided to build our own library called <a title="Node-swiz | Github.com" href="https://github.com/racker/node-swiz" target="_blank">node-swiz</a>.</p>
<p>Node-swiz is very powerful and flexible and can be used as a building block for very simple or complex RESTful APIs. The library itself introduces four main concepts which are described below with examples.</p>
<h1><strong>Swiz definitions</strong></h1>
<p>A Swiz definition describes how an object is serialized, deserialized and validated.</p>
<p>Here is an example object definition for a <em>Server</em> object:</p>
<p><script src="https://gist.github.com/2802822.js"> </script></p>
<p>Swiz struct module exposes two factory methods  &#8211; <em>Obj</em> for an object and <em>Field</em> for a field.</p>
<p>Each object takes the following arguments:</p>
<blockquote><p>1. Name &#8211; in our example is <em>Server</em><br />
2. An object with the following properties:<br />
a. fields &#8211; an array of Field objects (more details below)<br />
b. singular &#8211; singular name for this object (defaults to the object name if not provided) used when serializing lists in XML documents<br />
c. plural &#8211; plural name for this object used when serializing lists in XML documents</p></blockquote>
<p>Each field has a name (first argument which is passed to the factory method) and takes an object with many options as a second argument:</p>
<ul>
<li>src &#8211; name of the key on the object which is used as a source for the actual value. If not provided it defaults to the field name. This can also be name of a method on the object which is called when serializing it. This method gets passed in a callback and must pass a value as a second argument to this callback. You can find an example of how to do that in the <em>Serialization</em> section below.</li>
<li>desc &#8211; field description.</li>
<li>attribute &#8211; if true value will be included as an attribute instead of a tag when serializing to XML.</li>
<li>coerceTo &#8211; type to coerce the value to when deserializing a payload. This is only applicable when deserializing XML.</li>
<li>singular &#8211; name of a container tag when serializing a list to XML.</li>
<li>plural  &#8211; name of an item tag which is wrapped inside a container tag when serializing a list to XML.</li>
<li>enumerated &#8211; a list of enumerations for this value.</li>
<li>filterFrom &#8211; a list of targets from which this field should be excluded when serializing an object. User can pass in a target to the Swiz constructor in the options object. Below is an example which shows how to accomplish that in the <em>Serialization</em> section.</li>
</ul>
<h1><strong>Serialization</strong></h1>
<p>Serializing an object is easy and can be done in 2 steps:</p>
<blockquote><p>1. Instantiate a Swiz object with a list of your definitions<br />
2. Call a serialize method on the instantiated object and pass in requested format (JSON or XML) and your object</p></blockquote>
<p>Here is an example which shows how to do that:</p>
<p><script src="https://gist.github.com/2802590.js"> </script></p>
<p>JSON output:</p>
<p><script src="https://gist.github.com/2802638.js"> </script></p>
<p>JSON output (serializing for target called <em>public</em>):</p>
<p><script src="https://gist.github.com/2820793.js"> </script></p>
<p>In this case <em>public_ips</em> attribute is not included in the serialized object, because the definition contains <em>filterFrom</em> option and we are serializing for target called <em>public</em>.</p>
<p>XML output:</p>
<p><script src="https://gist.github.com/2802640.js"> </script></p>
<p>As you can see, our Server class has <em>getSerializerType </em>method. This is a special method which must be present if you want to serialize an object and tells Swiz which definition to use when serializing it.</p>
<h1><strong>Deserialization</strong></h1>
<p>Deserializing in Swiz means taking a JSON or XML payload and deserializing it to a JavaScript object. This can be done using a <em>deserialize</em>method on the swiz object. Here is an example which shows how to de-serialize a Node XML document:</p>
<p><script src="https://gist.github.com/2802627.js"> </script></p>
<p>And the output:</p>
<p><script src="https://gist.github.com/2802631.js"> </script></p>
<p>Deserializing a JSON document is the same, but instead of passing <em>swiz.SERIALIZATION.SERIALIZATION_XML </em>to the <em>deserialize</em> method you pass in <em>swiz.SERIALIZATION.SERIALIZATION_JSON</em>.</p>
<h1><strong>Validation (Valve)</strong></h1>
<p>Imagine how cool would it be if you could use the same definitions you already use for serializing and deserializing objects to also validate user data. That’s exactly what you can do with Swiz’s component called Valve. Valve is a Swiz component for validating data and making sure it conforms to the rules defined in the object definition.</p>
<p>Example which shows how to validate an object:</p>
<p><script src="https://gist.github.com/2802676.js"> </script></p>
<p>And the output:</p>
<p><script src="https://gist.github.com/2802679.js"> </script></p>
<p>If the validation succeeds, Swiz passes a cleaned object to the callback as a second argument. In the first example you can also see how <em>toBoolean() </em>transformation function works. We passed in <em>1</em> for the <em>active </em>key value, but Valve casted it to a boolean.</p>
<p>As you can see in the second example, if the validation fails, Swiz passes back a special error object to the callback as a first argument. This object contains a detailed error message and the key which failed the validation.</p>
<h1><strong>How we use node-swiz in Cloud Monitoring</strong></h1>
<p>In Cloud Monitoring we use Swiz extensively inside the API server to deserialize and validate all the incoming data for a particular request. However, another interesting point is we use swiz and valve on a non-HTTP protocol, but over a plain TLS TCP socket. Inside our upcoming agent endpoint we use swiz/valve to validate payload of the JSON-RPC messages sent by the agent.</p>
<p><strong>Serialization and deserialization</strong><br />
Our API supports both JSON and XML formats and we use Swiz to deserialize all the request payloads and serialize all the responses. For serializing and deserializing XML within Swiz, it uses the <a title="Node-Elementtree - Node.js Library to Build and Parse XML documents | Rackspace Blog" href="http://www.rackspace.com/blog/node-elementtree-node-js-library-to-build-and-parse-xml-documents/" target="_blank">previously described node-elementreelibrary</a>.</p>
<p><strong>Validation</strong><br />
After the API request comes in and it’s parsed by Swiz we use Valve to validate the payload and make sure it conforms to all the rules specified in the definitions. If the validation fails we return a detailed error back to the user.</p>
<p><strong>Automatic documentation generation</strong><br />
Another place where we use Swiz is for generating parts of our documentation. Every time we push to master our buildbot automatically starts a build which, among other things, generates parts of the documentation using Swiz which are then included in the main documentation file. Keeping documentation in sync with code is important but usually an overlooked thing. Using Swiz to generate parts of the documentation allows us to automate this process and makes sure that our documentation is always accurate and up to date.</p>
<p><a href="http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-entities.html#section-Entities"><img class="alignnone" src="http://c179631.r31.cf0.rackcdn.com/swizvalve_image1.png" alt="" width="506" height="404" /></a></p>
<p>Entities attributes table is automatically generated using Swiz definitions</p>
<p><a href="http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/service-check-types.html#section-check-types-remote.dns"><img class="alignnone" src="http://c179631.r31.cf0.rackcdn.com/swizvalve_image2.png" alt="" width="494" height="395" /></a></p>
<p>Check type details field table is automatically generated using Swiz definitions</p>
<h3><strong>Conclusion</strong></h3>
<p>I hope you found this post helpful! Don’t forget to play with the library and check out the code on Github &#8211; <a title="Node-swiz | Github.com" href="https://github.com/racker/node-swiz" target="_blank">https://github.com/racker/node-swiz</a>. We will see you around soon when we talk about another Node.js library we have open-sourced.</p>
<p>&nbsp;</p>
<p><em>If you think this kind of work would be challenging and fun, and you enjoy contributing to open-source projects, we are always looking for </em><a title="Jobs at Rackspace" href="http://jobs.rackspace.com/search?q=developer" target="_blank"><em>talented engineers</em></a><em>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/node-swiz-node-js-library-for-serializing-deserializing-and-validating-objects-in-rest-apis/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>node-elementtree &#8211; Node.js Library To Build And Parse XML Documents</title>
		<link>http://www.rackspace.com/blog/node-elementtree-node-js-library-to-build-and-parse-xml-documents/</link>
		<comments>http://www.rackspace.com/blog/node-elementtree-node-js-library-to-build-and-parse-xml-documents/#comments</comments>
		<pubDate>Wed, 09 May 2012 14:00:51 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Open Source Technologies]]></category>
		<category><![CDATA[Tips for Devs and Sys Admins]]></category>
		<category><![CDATA[Cloud Monitoring]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=18796</guid>
		<description><![CDATA[Tomaz Muraus is part of the Cloud Monitoring team that built and open sourced node-elementtree, a Node.js Library To Build And Parse XML Documents.]]></description>
				<content:encoded><![CDATA[<p><em>This is another post in the series about Cloud Monitoring libraries we have open-sourced. I first talked about <a href="http://www.rackspace.com/blog/rackspace-open-sources-whiskey-a-test-framework/" target="_blank">Whiskey, a powerful Node.js test framework</a> and recently Gary talked about the <a href="http://www.rackspace.com/blog/rackspace-contributes-cassandra-cql-driver-for-node-js/" target="_blank">Cassandra CQL driver</a>. This week I&#8217;m going to talk about node-elementtree, a Node.js library inspired by <a href="http://effbot.org/zone/element-index.htm" target="_blank">Python&#8217;s ElementTree module</a> for building and parsing XML</em>.</p>
<p>We began collecting requirements before we started to build our Monitoring-as-a-Service (MaaS) platform and one of the requirements was to support XML. None of the developers in our team particularly like XML (we prefer JSON), but we needed to support XML because some of the API consumers still use it. When we started working on the project, there wasn’t a good library available for creating XML documents, so we decided to build our own. Many of the developers on our team have previously worked with Python and were familiar with Python’s <a href="https://github.com/racker/node-elementtree" target="_blank">ElementTree</a> API, so we modeled our library after ElementTree’s straightforward and easy to use interface.</p>
<p>In this blog post I am going to go over a couple examples of leveraging the API.  First we’ll start with creating a document, and then we’ll talk about parsing a document.</p>
<h2>Example 1 &#8211; Creating An XML Document</h2>
<p>This example shows how to build a valid XML document that can be published to <a href="http://www.rackspace.com/blog/rackspace-open-sources-atom-hopper-an-atom-publishing-server/" target="_blank">Atom Hopper</a>. Atom Hopper is used internally as a bridge from products all the way to collecting revenue, called “Usage.”  MaaS and other products send similar events to it every time user performs an action on a resource (e.g. creates, updates or deletes). Below is an example of leveraging the API to create a new XML document.</p>
<pre style="text-align: left;"><strong>var</strong> et <strong>=</strong> require('elementtree');
<strong>var</strong> XML <strong>=</strong> et.XML;
<strong>var</strong> ElementTree <strong>=</strong> et.ElementTree;
<strong>var</strong> element <strong>=</strong> et.Element;
<strong>var</strong> subElement <strong>=</strong> et.SubElement;

<strong>var</strong> date, root, tenantId, serviceName, eventType, usageId, dataCenter, region, checks, resourceId, category, startTime, resourceName, etree, xml;

date <strong>=</strong> <strong>new</strong> Date();

root <strong>=</strong> element('entry');
root.set('xmlns', 'http://www.w3.org/2005/Atom');

tenantId <strong>=</strong> subElement(root, 'TenantId');
tenantId.text <strong>=</strong> '12345';

serviceName <strong>=</strong> subElement(root, 'ServiceName');
serviceName.text <strong>=</strong> 'MaaS';

resourceId <strong>=</strong> subElement(root, 'ResourceID');
resourceId.text <strong>=</strong> 'enAAAA';

usageId <strong>=</strong> subElement(root, 'UsageID');
usageId.text <strong>=</strong> '550e8400-e29b-41d4-a716-446655440000';

eventType <strong>=</strong> subElement(root, 'EventType');
eventType.text <strong>=</strong> 'create';

category <strong>=</strong> subElement(root, 'category');
category.set('term', 'monitoring.entity.create');

dataCenter <strong>=</strong> subElement(root, 'DataCenter');
dataCenter.text <strong>=</strong> 'global';

region <strong>=</strong> subElement(root, 'Region');
region.text <strong>=</strong> 'global';

startTime <strong>=</strong> subElement(root, 'StartTime');
startTime.text <strong>=</strong> date;

resourceName <strong>=</strong> subElement(root, 'ResourceName');
resourceName.text <strong>=</strong> 'entity';

etree <strong>=</strong> <strong>new</strong> ElementTree(root);
xml <strong>=</strong> etree.write({'xml_declaration'<strong>:</strong> <strong>false</strong>});
console.log(xml);</pre>
<p><a href="https://gist.github.com/2554363" target="_blank">https://gist.github.com/2554363</a></p>
<p>As you can see, both et.Element and et.SubElement are factory methods which return a new instance of Element and SubElement class, respectively. When you create a new element (tag) you can use <em>set </em>method to set an attribute. To set the tag value, assign a value to the <em>.text </em>attribute.</p>
<p>This example would output a document that looks like this:</p>
<pre style="text-align: left;">&lt;entry xmlns="http://www.w3.org/2005/Atom"&gt;
  &lt;TenantId&gt;12345&lt;/TenantId&gt;
  &lt;ServiceName&gt;MaaS&lt;/ServiceName&gt;
  &lt;ResourceID&gt;enAAAA&lt;/ResourceID&gt;
  &lt;UsageID&gt;550e8400-e29b-41d4-a716-446655440000&lt;/UsageID&gt;
  &lt;EventType&gt;create&lt;/EventType&gt;
  &lt;category term="monitoring.entity.create"/&gt;
  &lt;DataCenter&gt;global&lt;/DataCenter&gt;
  &lt;Region&gt;global&lt;/Region&gt;
  &lt;StartTime&gt;Sun Apr 29 2012 16:37:32 GMT-0700 (PDT)&lt;/StartTime&gt;
  &lt;ResourceName&gt;entity&lt;/ResourceName&gt;
&lt;/entry&gt;</pre>
<p style="text-align: left;" align="center"><a href="https://gist.github.com/2632179" target="_blank">https://gist.github.com/2632179</a></p>
<h2>Example 2 &#8211; Parsing An XML Document</h2>
<p>This example shows how to parse an XML document and use simple XPath selectors. For demonstration purposes, we will use the XML document located at <a href="https://gist.github.com/2554343" target="_blank">https://gist.github.com/2554343</a>.</p>
<p>Behind the scenes, node-elementtree uses <a href="https://github.com/isaacs/sax-js" target="_blank">Isaac’s sax library</a> for parsing XML, but the library has a concept of “parsers,” which means it’s pretty simple to add support for a different parser.</p>
<pre style="text-align: left;"><strong>var</strong> fs <strong>=</strong> require('fs');

<strong>var</strong> et <strong>=</strong> require('elementtree');

<strong>var</strong> XML <strong>=</strong> et.XML;
<strong>var</strong> ElementTree <strong>=</strong> et.ElementTree;
<strong>var</strong> element <strong>=</strong> et.Element;
<strong>var</strong> subElement <strong>=</strong> et.SubElement;

<strong>var</strong> data, etree;

data <strong>=</strong> fs.readFileSync('document.xml').toString();
etree <strong>=</strong> et.parse(data);

console.log(etree.findall('./entry/TenantId').length); <em>// 2</em>
console.log(etree.findtext('./entry/ServiceName')); <em>// MaaS</em>
console.log(etree.findall('./entry/category')[0].get('term')); <em>// monitoring.entity.create</em>
console.log(etree.findall('*/category/[@term="monitoring.entity.update"]').length); <em>// 1</em></pre>
<p><a href="https://gist.github.com/2554353" target="_blank">https://gist.github.com/2554353</a></p>
<p>Basically, the module exposes three methods on the ElementTree instance:<br />
•    etree.find &#8211; return a single element which matches the XPath selector<br />
•    etree.findall &#8211; returns an array of elements which match the XPath selector<br />
•    etree.findtext &#8211; return a text value of the tag which matches the XPath selector</p>
<p>For more information on how to use XPath selectors you can refer to the <a href="http://effbot.org/zone/element-xpath.htm" target="_blank">Python documentation</a>.</p>
<h2>How We Use node-elementtree In MaaS</h2>
<p>In MaaS we use it in two places:<br />
1. Sending usage documents to an Atom Hopper instance<br />
2. Returning a response to the API user which has requested a response format to be XML</p>
<p>In the second case we actually use it in combination with our validation and serialization framework called Swiz. We use Swiz to define field types and validators for every object in the system. When a user hits our API and requests XML, Swiz serializes the response using the object definition and node-elementtree library.</p>
<h2>Conclusion</h2>
<p>I hope you found this post helpful! More examples and project source code can be found on <a href="https://github.com/racker/node-elementtree" target="_blank">Github</a>. We will see you around soon when we talk more about our previously mentioned serialization and validation framework called Swiz. If you think this kind of work would be challenging and fun, and you enjoy contributing to open-source projects, we are always looking for <a href="http://jobs.rackspace.com/search?q=developer">talented engineers</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/node-elementtree-node-js-library-to-build-and-parse-xml-documents/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rackspace Open Sources Whiskey, A Test Framework</title>
		<link>http://www.rackspace.com/blog/rackspace-open-sources-whiskey-a-test-framework/</link>
		<comments>http://www.rackspace.com/blog/rackspace-open-sources-whiskey-a-test-framework/#comments</comments>
		<pubDate>Wed, 14 Mar 2012 18:30:51 +0000</pubDate>
		<dc:creator>Tomaz Muraus</dc:creator>
				<category><![CDATA[Open Source Technologies]]></category>
		<category><![CDATA[Tips for Devs and Sys Admins]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Rackspace Monitoring]]></category>
		<category><![CDATA[Whiskey]]></category>

		<guid isPermaLink="false">http://www.rackspace.com/blog/?p=15913</guid>
		<description><![CDATA[Racker Tomaz Muraus discusses Whiskey, an Open Source technology the Rackspace Cloud Monitoring team developed to help with testing and test automation.]]></description>
				<content:encoded><![CDATA[<p>Giving back to the technical community is very important to Rackspace so we’ve open sourced a lot of the technology behind Cloud Monitoring.  In this series of blog posts, we’d like to introduce you to these different technologies and why you should care about them.  Primarily we’ll focus on the why, what and how you can use them.</p>
<p>For us (and many others), open source is an enabler to building new products (just like the cloud) and we’re part of strong communities and other projects. However, when we get a chance to open source something, we jump at the opportunity to give back.  And to be honest, we get back something in return.  Peer review, feedback and general discussion around the technologies help us make them better.</p>
<p>We’ve invested a lot of time and effort in Node.js and it has enabled so much velocity in such a familiar paradigm.  We have a ton of modules to share with the community.  The first one we’d like to share is around testing and test automation.  So to kick it off, our first piece of technology is the Whiskey test automation stack named after our team’s favorite adult beverage.</p>
<p>When we first started working with Node.js there weren&#8217;t many different test frameworks available. There was <a title="expresso | github" href="https://github.com/visionmedia/expresso" target="_blank">expresso</a> and some other BDD frameworks and that was pretty much it. Since we didn’t really follow the BDD practices we decided to go with expresso.</p>
<p>It worked fine for basic async and unit tests, but it didn&#8217;t really offer any kind of test isolation and process orchestration which we were looking for. Those are just two of the reasons we decided to write our own test framework called <a title="Whiskey | github" href="https://github.com/cloudkick/whiskey" target="_blank">Whiskey</a>.</p>
<h2>Test Isolation</h2>
<p>In Whiskey test isolation is achieved by running each test file (a test file is a collection of tests) in a separate child process. This model is also more scalable compared to a classical model where all the tests run in the same process. Currently child (worker) processes communicate with a parent (reporter) process over a Unix socket, but in the future we could easily change this to TCP and distribute child (worker) processes over multiple servers.</p>
<h2>Process Orchestration</h2>
<p>In our product we have a lot of integration tests and services that tests depend on. Those services also have a lot of inner-dependencies, e.g. Zookeeper and Cassandra need to be started before the messenger service and so on. At first, when we only had a few services, we used a custom <a title="SCons | Official Site" href="http://www.scons.org/" target="_blank">SCons</a> target that started all the services before running the integration tests. Maintaining custom SCons targets soon became too cumbersome and simply starting all the services one by one in a sequential order was relatively slow. That&#8217;s why we added support for process orchestration to Whiskey.</p>
<p>Process runner uses a simple JSON configuration file where you specify all the services and their dependencies. When you start Whiskey with &#8211;dependencies &lt;config path&gt; option, the config file is parsed and used to start services in the correct order. If it is possible, multiple independent services are also started in parallel, which speeds up the whole bootstrap process.</p>
<p>If you are interested in more details you can also read a post I wrote on my personal blog called <a title="Whiskey Node.js test runner now with more goodness - introducing process runner | Tomaz Blog" href="http://www.tomaz.me/2011/11/27/whiskey-now-with-more-goodness-introducing-process-runner" target="_blank">Whiskey Node.js test runner now with more goodness &#8211; introducing process runner</a>.</p>
<div class="wp-caption aligncenter" style="width: 488px"><a href="http://c179631.r31.cf0.rackcdn.com/Whiskey_01.png"><img class=" " title="Process runner" src="http://c179631.r31.cf0.rackcdn.com/Whiskey_01.png" alt="" width="478" height="108" /></a><p class="wp-caption-text">Process runner starting the processes before running our integration tests.</p></div>
<h2>Test Coverage</h2>
<p>One of the important features on our list was also a fully integrated code coverage framework. Expresso did offer basic code coverage support, but it only supported outputting the results to the console, which is not useful for larger files and projects. The code coverage module in Whiskey is similar to expresso using <a title="node-jscoverage | github" href="https://github.com/visionmedia/node-jscoverage" target="_blank">node-jscoverage</a> for actually instrumenting the code, but it offers more flexibility and features, including:</p>
<p>●    three different reporters &#8211; text, html and json<br />
●    support for hooking up the coverage for services started with the process runner<br />
●    support for aggregating code coverage reports</p>
<p>Aggregated code coverage reports are especially useful if you have multiple test suites in a single code base. In our case we have two types of tests &#8211; simple unit tests which don&#8217;t rely on external services and more complex integration tests which rely on different services. We use the JSON reporter when we are generating code coverage reports. This way, Whiskey writes out a JSON file with the code coverage statistics before exiting. In our case we end up with multiple different JSON coverage report files: one for simple tests, one for integration tests and one for each node service that has been started by the process runner. The report files are aggregated with a &#8211;coverage-aggregate option and we end up with a nice looking HTML report.</p>
<div class="wp-caption aligncenter" style="width: 515px"><a href="http://c179631.r31.cf0.rackcdn.com/Whiskey_02.png"><img class="  " title="Coverage Report" src="http://c179631.r31.cf0.rackcdn.com/Whiskey_02.png" alt="" width="505" height="389" /></a><p class="wp-caption-text">Code coverage HTML report overview page.</p></div>
<div class="wp-caption aligncenter" style="width: 492px"><a href="http://c179631.r31.cf0.rackcdn.com/Whiskey_03.png"><img class=" " title="Coverage Report" src="http://c179631.r31.cf0.rackcdn.com/Whiskey_03.png" alt="" width="482" height="302" /></a><p class="wp-caption-text">Code coverage HTML report single file view.</p></div>
<p>Those are just a few of the cool features of Whiskey. Other features include:</p>
<p>●    support for async tests<br />
●    support for tap output<br />
●    support for reporting variables which have leaked into the global scope<br />
●    support for generating Makefiles with common test targets<br />
●    simple integration with node debugger<br />
●    support for reporting tests timing</p>
<p>That&#8217;s it for today. Don&#8217;t forget to check the <a title="Whiskey | github" href="https://github.com/cloudkick/whiskey" target="_blank">Whiskey github page</a> and check back for a future post when Racker Gary will talk about the Node.js Cassandra CQL client we have open sourced.</p>
<p><em>As much as we love building these technologies, we’d love for people to use and break them. All of these projects are released under the Apache 2.0 license and available under the <a href="http://github.com/racker">github</a><a href="http://github.com/racker">.</a><a href="http://github.com/racker">com</a><a href="http://github.com/racker">/</a><a href="http://github.com/racker">racker</a> organization. Would you like to work on project like this? Check us out, <a title="San Francisco Jobs | Rackspace" href="http://rackertalent.com/san-francisco/" target="_blank">we’re hiring</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rackspace.com/blog/rackspace-open-sources-whiskey-a-test-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Content Delivery Network via Rackspace Cloud Files: c3414940.r40.cf0.rackcdn.com

 Served from: www.rackspace.com @ 2013-05-22 10:22:43 by W3 Total Cache -->