You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jclouds.apache.org by Zack Shoylev <za...@RACKSPACE.COM> on 2014/09/04 18:35:26 UTC

RE: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...

AFAIK latest versions of both. Anything broken?
________________________________________
From: Ignasi Barrera [ignasi.barrera@gmail.com]
Sent: Thursday, September 04, 2014 11:29 AM
To: dev@jclouds.apache.org
Subject: Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...

Zach wichi version of Jekyll were you using? Did you use the latest
version of the script to generate the site?

I'm just wondering, why the commit for your blog post modified all those files.

In any case, that can be prevented by taking a look at the script
output (which should prompt you) and manually adding *only* the
relevant files if needed, and discard the rest?



On 4 September 2014 17:18,  <za...@apache.org> wrote:
> Author: zachsh
> Date: Thu Sep  4 15:18:35 2014
> New Revision: 1622496
>
> URL: http://svn.apache.org/r1622496
> Log:
> deploy jclouds site content
>
> Added:
>     jclouds/site-content/blog/2014/09/
>     jclouds/site-content/blog/2014/09/03/
>     jclouds/site-content/blog/2014/09/03/better-builders/
>     jclouds/site-content/blog/2014/09/03/better-builders/index.html
> Modified:
>     jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>     jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>     jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>     jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>     jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>     jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>     jclouds/site-content/blog/atom.xml
>     jclouds/site-content/blog/index.html
>     jclouds/site-content/blog/page2/index.html
>     jclouds/site-content/blog/page3/index.html
>     jclouds/site-content/blog/page4/index.html
>     jclouds/site-content/blog/page5/index.html
>     jclouds/site-content/guides/abiquo-cloud/index.html
>     jclouds/site-content/guides/abiquo/index.html
>     jclouds/site-content/guides/aws-ebs/index.html
>     jclouds/site-content/guides/aws-ec2/index.html
>     jclouds/site-content/guides/aws-sqs/index.html
>     jclouds/site-content/guides/aws/index.html
>     jclouds/site-content/guides/azure-storage/index.html
>     jclouds/site-content/guides/bluelock/index.html
>     jclouds/site-content/guides/chef/index.html
>     jclouds/site-content/guides/cloudsigma/index.html
>     jclouds/site-content/guides/docker/index.html
>     jclouds/site-content/guides/filesystem/index.html
>     jclouds/site-content/guides/glacier/index.html
>     jclouds/site-content/guides/go-grid/index.html
>     jclouds/site-content/guides/hpcloud/index.html
>     jclouds/site-content/guides/karaf/index.html
>     jclouds/site-content/guides/openstack/index.html
>     jclouds/site-content/guides/rackspace/index.html
>     jclouds/site-content/guides/vcloud-director/index.html
>     jclouds/site-content/guides/vcloud/index.html
>     jclouds/site-content/index.html
>     jclouds/site-content/reference/configuration/index.html
>     jclouds/site-content/reference/logging/index.html
>     jclouds/site-content/reference/troubleshooting/index.html
>     jclouds/site-content/releasenotes/1.1.0/index.html
>     jclouds/site-content/releasenotes/1.2/index.html
>     jclouds/site-content/releasenotes/1.6.1/index.html
>     jclouds/site-content/releasenotes/1.6.2/index.html
>     jclouds/site-content/releasenotes/1.6.3/index.html
>     jclouds/site-content/releasenotes/1.7.0/index.html
>     jclouds/site-content/releasenotes/1.7.1/index.html
>     jclouds/site-content/releasenotes/1.7.2/index.html
>     jclouds/site-content/releasenotes/1.7.3/index.html
>     jclouds/site-content/releasenotes/atom.xml
>     jclouds/site-content/start/blobstore/index.html
>     jclouds/site-content/start/compute/index.html
>     jclouds/site-content/start/install/index.html
>
> Modified: jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html (original)
> +++ jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html Thu Sep  4 15:18:35 2014
> @@ -154,8 +154,7 @@
>  <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>      <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>      <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
> -<span class="o">}</span>
> -</code></pre></div>
> +<span class="o">}</span></code></pre></div>
>
>
>  <p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
> @@ -170,8 +169,7 @@
>      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>          <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>      <span class="o">}</span>
> -<span class="o">}</span>
> -</code></pre></div>
> +<span class="o">}</span></code></pre></div>
>
>
>  <p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>
> Modified: jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html (original)
> +++ jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html Thu Sep  4 15:18:35 2014
> @@ -158,8 +158,7 @@
>
>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
> -</code></pre></div>
> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>
>
>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>
> Modified: jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html (original)
> +++ jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html Thu Sep  4 15:18:35 2014
> @@ -162,14 +162,12 @@
>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
> -</code></pre></div>
> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>
>
>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>
> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
> -</code></pre></div>
> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>
>
>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
> @@ -182,8 +180,7 @@
>
>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>
> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>
>
>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
> @@ -192,8 +189,7 @@
>
>  <p>Oh, and don't forget to clean up your nodes :)</p>
>
> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>
>
>
>
> Modified: jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html (original)
> +++ jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html Thu Sep  4 15:18:35 2014
> @@ -161,8 +161,7 @@
>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>          <span class="c1">// ...</span>
>      <span class="o">}</span>
> -<span class="o">}</span>
> -</code></pre></div>
> +<span class="o">}</span></code></pre></div>
>
>
>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
> @@ -177,8 +176,7 @@
>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>          <span class="c1">// ...</span>
>      <span class="o">}</span>
> -<span class="o">}</span>
> -</code></pre></div>
> +<span class="o">}</span></code></pre></div>
>
>
>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
> @@ -187,8 +185,7 @@
>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>
>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
> -</code></pre></div>
> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>
>
>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>
> Modified: jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html (original)
> +++ jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html Thu Sep  4 15:18:35 2014
> @@ -168,8 +168,7 @@
>
>  <h3>Lazy advance through all your metrics:</h3>
>
> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>
>
>  <h3>Â Advance only until we find the load balancer we want:</h3>
> @@ -177,14 +176,12 @@
>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
> -</code></pre></div>
> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>
>
>  <h3>Get only the first page of database instances</h3>
>
> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>
>
>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>
> Modified: jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html (original)
> +++ jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html Thu Sep  4 15:18:35 2014
> @@ -156,8 +156,7 @@
>
>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>
> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
> -</code></pre></div>
> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>
>
>  <h2>What else is in 1.5.4?</h2>
> @@ -168,16 +167,14 @@
>
>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>
> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>
>
>  <h3>Nova Server Diagnostics</h3>
>
>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>
> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>
>
>  <h3>S3 Multi-Object delete</h3>
> @@ -185,8 +182,7 @@
>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>
>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
> -</code></pre></div>
> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>
>
>  <h2>What's next</h2>
>
> Added: jclouds/site-content/blog/2014/09/03/better-builders/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2014/09/03/better-builders/index.html?rev=1622496&view=auto
> ==============================================================================
> --- jclouds/site-content/blog/2014/09/03/better-builders/index.html (added)
> +++ jclouds/site-content/blog/2014/09/03/better-builders/index.html Thu Sep  4 15:18:35 2014
> @@ -0,0 +1,344 @@
> +<!DOCTYPE html>
> +<html lang="en">
> +    <head>
> +        <meta charset="utf-8">
> +<title>Apache jclouds&reg; :: Better Builders with jclouds!</title>
> +<meta name="viewport" content="width=device-width, initial-scale=1.0">
> +<meta name="description" content="">
> +<meta name="author" content="">
> +
> +<!--link rel="stylesheet/less" href="less/bootstrap.less" type="text/css" /-->
> +<!--link rel="stylesheet/less" href="less/responsive.less" type="text/css" /-->
> +<!--script src="js/less-1.3.3.min.js"></script-->
> +<!--append â?~#!watchâ?T to the browser URL, then refresh the page. -->
> +
> +<link href="/css/bootstrap.min.css" rel="stylesheet">
> +<link href="/css/style.css" rel="stylesheet">
> +<link href="/css/syntax.css" rel="stylesheet">
> +
> +<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
> +<!--[if lt IE 9]>
> +<script src="js/html5shiv.js"></script>
> +<![endif]-->
> +
> +<!-- Fav and touch icons -->
> +<!--
> +<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/img/apple-touch-icon-144-precomposed.png">
> +<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/apple-touch-icon-114-precomposed.png">
> +<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/apple-touch-icon-72-precomposed.png">
> +<link rel="apple-touch-icon-precomposed" href="/img/apple-touch-icon-57-precomposed.png">
> +-->
> +<link rel="shortcut icon" href="/favicon.ico">
> +
> +<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Blog Posts Feed">
> +<link rel="alternate" type="application/atom+xml" href="/releasenotes/atom.xml" title="Release Notes Feed">
> +
> +<script type="text/javascript" src="/js/jquery.min.js"></script>
> +<script type="text/javascript" src="/js/bootstrap.min.js"></script>
> +<script type="text/javascript" src="/js/toc.js"></script>
> +
> +<script type="text/javascript">
> +    var _gaq = _gaq || [];
> +    _gaq.push(['_setAccount', 'UA-8638379-1']);
> +    _gaq.push(['_trackPageview']);
> +
> +    (function() {
> +     var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
> +     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
> +     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
> +     })();
> +</script>
> +<script type="text/javascript">
> +    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
> +     (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
> +     m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
> +     })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
> +
> +    ga('create', 'UA-47106724-1', 'jclouds.apache.org');
> +    ga('send', 'pageview');
> +</script>
> +
> +    </head>
> +    <body>
> +        <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
> +    <div class="container">
> +        <div class="navbar-header">
> +            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
> +                <span class="sr-only">Toggle navigation</span>
> +                <span class="icon-bar"></span>
> +                <span class="icon-bar"></span>
> +                <span class="icon-bar"></span>
> +            </button>
> +            <a class="navbar-brand" href="/">Apache jclouds &reg;</a>
> +        </div>
> +
> +        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
> +            <ul class="nav navbar-nav">
> +                <li class="dropdown">
> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Getting Started<strong class="caret"></strong></a>
> +                    <ul class="dropdown-menu">
> +                        <li><a href="/start/what-is-jclouds/">What Is Apache jclouds?</a></li>
> +                        <li><a href="/start/install/">Installation Guide</a></li>
> +                        <li class="divider"></li>
> +                        <li><a href="/start/concepts/">Core Concepts</a></li>
> +                        <li><a href="/start/compute/">ComputeService</a></li>
> +                        <li><a href="/start/blobstore/">BlobStore</a></li>
> +                        <li><a href="http://github.com/jclouds/jclouds-examples">Examples</a></li>
> +                    </ul>
> +                </li>
> +                <li class="dropdown">
> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation<strong class="caret"></strong></a>
> +                    <ul class="dropdown-menu">
> +                        <li><a href="/reference/providers/">Cloud Providers</a></li>
> +                        <li><a href="/guides">User Guides</a></li>
> +                        <li><a href="/reference/troubleshooting/">Troubleshooting</a></li>
> +                        <li><a href="/reference/configuration/">Configuration</a></li>
> +                        <li><a href="/reference/logging/">Logging</a></li>
> +                        <li><a href="/reference/javadoc/">Javadoc</a></li>
> +                        <li class="divider"></li>
> +                        <li class="dropdown-header">Developer Guides</li>
> +                        <li><a href="http://wiki.apache.org/jclouds/">Wiki</a></li>
> +                    </ul>
> +                </li>
> +                <li class="dropdown">
> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Community<strong class="caret"></strong></a>
> +                    <ul class="dropdown-menu">
> +                        <li><a href="/community/">Get In Touch!</a></li>
> +                        <li><a href="http://www.meetup.com/jclouds/">Attend An Event</a></li>
> +                        <li><a href="/community/users/">Who Is Using jclouds?</a></li>
> +                        <li class="divider"></li>
> +                        <li class="dropdown-header">Contribute</li>
> +                        <li><a href="/reference/report-a-bug/">Report a Bug</a></li>
> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute">How To Contribute Code</a></li>
> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">How To Contribute Documentation</a></li>
> +                    </ul>
> +                </li>
> +                <li><a href="/blog">Blog</a></li>
> +            </ul>
> +            <ul class="nav navbar-nav navbar-right">
> +                <li class="dropdown">
> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Release Notes<strong class="caret"></strong></a>
> +                    <ul class="dropdown-menu">
> +                        <!-- only keep the release notes for supported versions in this list -->
> +                        <li><a href="/releasenotes/1.8.0">1.8.0</a></li>
> +                        <li><a href="/releasenotes/1.7.3">1.7.3</a></li>
> +                        <li><a href="/releasenotes/1.7.2">1.7.2</a></li>
> +                        <li><a href="/releasenotes/1.7.1">1.7.1</a></li>
> +                        <li><a href="/releasenotes/1.7.0">1.7.0</a></li>
> +                        <li class="divider"></li>
> +                        <li class="dropdown-header">Previous releases</li>
> +                        <li><a href="/releasenotes">Release archive</a></li>
> +                    </ul>
> +                </li>
> +                <li>
> +                    <div>
> +                        <a class="btn btn-success navbar-btn" href="/start/install/">
> +                            <span class="glyphicon glyphicon-download"></span>
> +                            Install
> +                        </a>
> +                    </div>
> +                </li>
> +            </ul>
> +        </div>
> +    </div>
> +</nav>
> +
> +        <div class="container">
> +            <div class="page-header">
> +                <h1>Better Builders with jclouds!</h1>
> +                <span class="text-muted">03 September 2014, by Zack Shoylev</span>
> +            </div>
> +            <p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
> +
> +<!--more-->
> +
> +
> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
> +
> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
> +        <span class="p">},</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
> +                <span class="p">{</span>
> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
> +                <span class="p">},</span>
> +                <span class="p">{</span>
> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
> +                <span class="p">}</span>
> +            <span class="p">],</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
> +        <span class="p">},</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
> +        <span class="p">},</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
> +                <span class="p">{</span>
> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
> +                <span class="p">}</span>
> +            <span class="p">],</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
> +        <span class="p">}</span>
> +    <span class="p">]</span>
> +<span class="p">}</span></code></pre></div>
> +
> +
> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
> +
> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
> +
> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
> +
> +
> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
> +
> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
> +
> +<p>Current implementations have the following two issues :</p>
> +
> +<ol>
> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
> +</ol>
> +
> +
> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
> +
> +<p>We want to</p>
> +
> +<ol>
> +<li>Ensure object immutability.</li>
> +<li>Utilize the fluent builder pattern.</li>
> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
> +<li>Allow using different validation strategies (for example, create vs update).</li>
> +</ol>
> +
> +
> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
> +
> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
> +
> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
> +
> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
> +
> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
> +
> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
> +
> +<ol>
> +<li>Listing networks returns a Network or a list of Networks.</li>
> +<li>Updating a network requires Network.UpdateOptions.</li>
> +<li>Creating a network requires Network.CreateOptions.</li>
> +</ol>
> +
> +
> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
> +
> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
> +
> +<p>This is how it all works out from the developer's perspective:</p>
> +
> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
> +
> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
> +
> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
> +
> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
> +
> +
> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
> +
> +
> +            <div id="comments">
> +                <hr/>
> +                <div id="disqus_thread"></div>
> +<script type="text/javascript">
> +var disqus_shortname = 'jclouds';
> +/* * * DON'T EDIT BELOW THIS LINE * * */
> +(function() {
> +    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
> +    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
> +    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
> +})();
> +</script>
> +<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">Comments powered by Disqus.</a></noscript>
> +<a href="http://disqus.com" class="dsq-brlink">Comments powered by <span class="logo-disqus">Disqus</span></a>
> +
> +            </div>
> +
> +            <div class="row clearfix">
> +                <div id="footer" class="col-md-12 column">
> +                    <div id="footer">
> +    <hr/>
> +    <div class="row clearfix">
> +        <div class="col-md-2 column">
> +            <p class="text-center">
> +                <a class="text-primary" href="/start/">Getting Started</a>
> +            </p>
> +        </div>
> +        <div class="col-md-2 column">
> +            <p class="text-center">
> +                <a class="text-primary" href="/reference/report-a-bug/">Report a Bug</a>
> +            </p>
> +        </div>
> +        <div class="col-md-2 column">
> +            <p class="text-center">
> +                <a href="https://github.com/jclouds/jclouds-site/edit/master/_posts/2014-09-03-better-builders.md">Fix This Page</a><a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation"><sup>*</sup></a>
> +            </p>
> +        </div>
> +        <div class="col-md-2 column">
> +            <p class="text-center">
> +                <a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute">Contribute Code</a>
> +            </p>
> +        </div>
> +        <div class="col-md-2 column">
> +            <p class="text-center">
> +                <a class="text-primary" href="/community/">Contact Us</a>
> +            </p>
> +        </div>
> +        <div class="col-md-2 column">
> +            <p class="text-center">
> +                <a class="text-primary" href="https://twitter.com/jclouds">Follow Us</a>
> +            </p>
> +        </div>
> +    </div>
> +    <hr style="margin-top: 10px"/>
> +    <div class="row clearfix">
> +        <div class="col-md-12 column">
> +            <p class="text-center">
> +              Copyright &copy; 2011-2014 <a href="http://www.apache.org">The Apache Software Foundation</a>. All Rights Reserved.
> +            </p>
> +            <p class="text-center">
> +              Apache, jclouds, Apache jclouds, the jclouds logo, and the Apache feather logos are registered trademarks or trademarks of the Apache Software Foundation.
> +            </p>
> +            <p class="text-center">
> +              <img src="/img/feather-small.gif" width="80", height="24"/>
> +            </p>
> +            <br/>
> +        </div>
> +    </div>
> +</div>
> +
> +                </div>
> +            </div>
> +        </div>
> +    </body>
> +</html>
>
> Modified: jclouds/site-content/blog/atom.xml
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/atom.xml?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/atom.xml (original)
> +++ jclouds/site-content/blog/atom.xml Thu Sep  4 15:18:35 2014
> @@ -8,6 +8,131 @@
>
>
>    <entry>
> +    <id>http://jclouds.apache.org/blog/2014/09/03/better-builders</id>
> +    <title type="html"><![CDATA[Better Builders with jclouds!]]></title>
> +    <link href="http://jclouds.apache.org/blog/2014/09/03/better-builders"/>
> +    <updated>2014-09-03T00:00:00Z</updated>
> +    <content type="html"><![CDATA[<p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
> +
> +<!--more-->
> +
> +
> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
> +
> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
> +        <span class="p">},</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
> +                <span class="p">{</span>
> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
> +                <span class="p">},</span>
> +                <span class="p">{</span>
> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
> +                <span class="p">}</span>
> +            <span class="p">],</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
> +        <span class="p">},</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
> +        <span class="p">},</span>
> +        <span class="p">{</span>
> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
> +                <span class="p">{</span>
> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
> +                <span class="p">}</span>
> +            <span class="p">],</span>
> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
> +        <span class="p">}</span>
> +    <span class="p">]</span>
> +<span class="p">}</span></code></pre></div>
> +
> +
> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
> +
> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
> +
> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
> +
> +
> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
> +
> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
> +
> +<p>Current implementations have the following two issues :</p>
> +
> +<ol>
> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
> +</ol>
> +
> +
> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
> +
> +<p>We want to</p>
> +
> +<ol>
> +<li>Ensure object immutability.</li>
> +<li>Utilize the fluent builder pattern.</li>
> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
> +<li>Allow using different validation strategies (for example, create vs update).</li>
> +</ol>
> +
> +
> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
> +
> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
> +
> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
> +
> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
> +
> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
> +
> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
> +
> +<ol>
> +<li>Listing networks returns a Network or a list of Networks.</li>
> +<li>Updating a network requires Network.UpdateOptions.</li>
> +<li>Creating a network requires Network.CreateOptions.</li>
> +</ol>
> +
> +
> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
> +
> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
> +
> +<p>This is how it all works out from the developer's perspective:</p>
> +
> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
> +
> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
> +
> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
> +
> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
> +
> +
> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
> +]]></content>
> +  </entry>
> +
> +  <entry>
>      <id>http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers</id>
>      <title type="html"><![CDATA[1 release, 2 committers...a busy week for jclouds!]]></title>
>      <link href="http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers"/>
> @@ -480,8 +605,7 @@
>
>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>
> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
> -</code></pre></div>
> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>
>
>  <h2>What else is in 1.5.4?</h2>
> @@ -492,16 +616,14 @@
>
>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>
> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>
>
>  <h3>Nova Server Diagnostics</h3>
>
>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>
> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>
>
>  <h3>S3 Multi-Object delete</h3>
> @@ -509,8 +631,7 @@
>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>
>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
> -</code></pre></div>
> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>
>
>  <h2>What's next</h2>
> @@ -602,8 +723,7 @@
>
>  <h3>Lazy advance through all your metrics:</h3>
>
> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>
>
>  <h3>Â Advance only until we find the load balancer we want:</h3>
> @@ -611,14 +731,12 @@
>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
> -</code></pre></div>
> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>
>
>  <h3>Get only the first page of database instances</h3>
>
> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>
>
>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
> @@ -655,8 +773,7 @@
>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>          <span class="c1">// ...</span>
>      <span class="o">}</span>
> -<span class="o">}</span>
> -</code></pre></div>
> +<span class="o">}</span></code></pre></div>
>
>
>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
> @@ -671,8 +788,7 @@
>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>          <span class="c1">// ...</span>
>      <span class="o">}</span>
> -<span class="o">}</span>
> -</code></pre></div>
> +<span class="o">}</span></code></pre></div>
>
>
>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
> @@ -681,8 +797,7 @@
>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>
>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
> -</code></pre></div>
> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>
>
>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
> @@ -710,14 +825,12 @@
>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
> -</code></pre></div>
> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>
>
>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>
> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
> -</code></pre></div>
> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>
>
>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
> @@ -730,8 +843,7 @@
>
>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>
> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>
>
>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
> @@ -740,8 +852,7 @@
>
>  <p>Oh, and don't forget to clean up your nodes :)</p>
>
> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
> -</code></pre></div>
> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>
>
>
> @@ -862,8 +973,7 @@
>
>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
> -</code></pre></div>
> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>
>
>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
> @@ -876,41 +986,4 @@
>  ]]></content>
>    </entry>
>
> -  <entry>
> -    <id>http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes</id>
> -    <title type="html"><![CDATA[Catching exceptions with fewer keystrokes]]></title>
> -    <link href="http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes"/>
> -    <updated>2009-05-13T00:00:00Z</updated>
> -    <content type="html"><![CDATA[<p>Some of us hate checked exceptions, but still use them for one reason or another. A common problem we have is unnecessary exception nesting, or runtime swallowing. This often leads to the all to familiar and crufty code with a million catch blocks. jclouds has a slightly different approach that strikes a balance, allowing checked exceptions to be dealt with, but without the pain of so many lines of repetitious code.</p>
> -
> -<div class="highlight"><pre><code class="java"><span class="k">try</span> <span class="o">{</span>
> -<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
> -    <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
> -    <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
> -<span class="o">}</span>
> -</code></pre></div>
> -
> -
> -<p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
> -
> -<p>Now, this code shouldn't work, as current versions of java hava a generic type erasure problem. The reason it does work is a somewhat hackish line in the rethrowIfRuntimeOrSameType method:</p>
> -
> -<div class="highlight"><pre><code class="java"><span class="k">if</span> <span class="o">(</span><span class="n">e</span> <span class="k">instanceof</span> <span class="n">RuntimeException</span><span class="o">)</span> <span class="o">{</span>
> -    <span class="k">throw</span> <span class="o">(</span><span class="n">RuntimeException</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
> -<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
> -    <span class="k">try</span> <span class="o">{</span>
> -        <span class="k">throw</span> <span class="o">(</span><span class="n">E</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
> -    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
> -        <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
> -    <span class="o">}</span>
> -<span class="o">}</span>
> -</code></pre></div>
> -
> -
> -<p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
> -
> -<p>If nothing else, I hope you enjoy the perspective!</p>
> -]]></content>
> -  </entry>
> -
>  </feed>
>
> Modified: jclouds/site-content/blog/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/index.html (original)
> +++ jclouds/site-content/blog/index.html Thu Sep  4 15:18:35 2014
> @@ -150,6 +150,12 @@
>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>
>
> +<h3><a class="text-primary" href="/blog/2014/09/03/better-builders">Better Builders with jclouds!</a></h3>
> +<span class="text-muted">03 September 2014, by Zack Shoylev</span>
> +<p>If you are a new jclouds developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.
> +</p>
> +
>  <h3><a class="text-primary" href="/blog/2014/08/04/1-release-2-committers">1 release, 2 committers...a busy week for jclouds!</a></h3>
>  <span class="text-muted">04 August 2014, by <a href="http://blog.xebialabs.com/author/aphillips/">Andrew Phillips</a></span>
>  <p>There's a lot going on this week for the jclouds community. Most importantly, we're really pleased to introduce two new committers: Andrea Turli and Chris Custine.
> @@ -170,11 +176,6 @@
>  <p>The Google Summer of Code (GSoC) accepted projects have been announced and we will have 3 students working on jclouds related projects!
>  </p>
>
> -<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
> -<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
> -<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
> -</p>
> -
>
>
>  <ul class="pagination text-center">
> @@ -189,25 +190,25 @@
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page2">2</a>
> +                <a class="text-primary" href="blog/page2">2</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page3">3</a>
> +                <a class="text-primary" href="blog/page3">3</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page4">4</a>
> +                <a class="text-primary" href="blog/page4">4</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page5">5</a>
> +                <a class="text-primary" href="blog/page5">5</a>
>
>          </li>
>
>
> Modified: jclouds/site-content/blog/page2/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page2/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/page2/index.html (original)
> +++ jclouds/site-content/blog/page2/index.html Thu Sep  4 15:18:35 2014
> @@ -150,6 +150,11 @@
>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>
>
> +<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
> +<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
> +<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
> +</p>
> +
>  <h3><a class="text-primary" href="/blog/2014/03/03/joining-the-asf-new-site-and-jclouds-1-7">Joining the ASF, new site, and jclouds 1.7!</a></h3>
>  <span class="text-muted">03 March 2014, by Ignasi Barrera</span>
>  <p>It's been a while since our last blog post, and lots has happened since then. There have been many things that have kept us busy, and finally, all the hard work is starting to show up. During this time, we've:
> @@ -170,11 +175,6 @@
>  <p>jclouds community is an international group with over 100 contributors since we started in early 2009. The idea of holidays vary, but we decided Mistletoe as an appropriate codename for jclouds 1.5.4. Here's why.
>  </p>
>
> -<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
> -<span class="text-muted">17 November 2012, by Adrian Cole</span>
> -<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
> -</p>
> -
>
>
>  <ul class="pagination text-center">
> @@ -191,25 +191,25 @@
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page2">2</a>
> +                <a class="text-primary" href="blog/page2">2</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page3">3</a>
> +                <a class="text-primary" href="blog/page3">3</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page4">4</a>
> +                <a class="text-primary" href="blog/page4">4</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page5">5</a>
> +                <a class="text-primary" href="blog/page5">5</a>
>
>          </li>
>
>
> Modified: jclouds/site-content/blog/page3/index.html
> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page3/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
> ==============================================================================
> --- jclouds/site-content/blog/page3/index.html (original)
> +++ jclouds/site-content/blog/page3/index.html Thu Sep  4 15:18:35 2014
> @@ -150,6 +150,11 @@
>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>
>
> +<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
> +<span class="text-muted">17 November 2012, by Adrian Cole</span>
> +<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
> +</p>
> +
>  <h3><a class="text-primary" href="/blog/2012/11/09/500-jclouds-builds-on-buildhive-and-counting">500 jclouds builds on BuildHive and counting...</a></h3>
>  <span class="text-muted">09 November 2012, by Adrian Cole</span>
>  <p>At jclouds, we've been running our Jenkins continuous integration jobs in CloudBees' DEV@cloud for a while now (CloudBees has a FOSS programme). We also have an active and ever-increasing contributor community, which amongst others means... lots of pull requests.
> @@ -170,11 +175,6 @@
>  <p>We are very near beta, I promise! In the mean time, we just cut a new codebase with a bunch of cool new toys. Here's a few. Thanks to Adam Lowe, we are getting even deeper into OpenStack with more Keystone support than ever. Setup your code to pull org.jclouds.labs/openstack-keystone, and you can do stuff like this.
>  </p>
>
> -<h3><a class="text-primary" href="/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and">Take a peek at vCloud Director 1.5, OpenStack, and VirtualBox</a></h3>
> -<span class="text-muted">23 March 2012, by Adrian Cole</span>
> -<p>The jclouds team have been working very hard lately, particularly on a few new apis. We've decided to cage them no longer and cut jclouds 1.5.0-alpha.1. Most notably, we've added the openstack-nova api, and three new providers, all of which discovered via OpenStack Keystone v2.0.
> -</p>
> -
>
>
>  <ul class="pagination text-center">
> @@ -191,25 +191,25 @@
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page2">2</a>
> +                <a class="text-primary" href="blog/page2">2</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page3">3</a>
> +                <a class="text-primary" href="blog/page3">3</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page4">4</a>
> +                <a class="text-primary" href="blog/page4">4</a>
>
>          </li>
>
>          <li>
>
> -                <a class="text-primary" href="/blog/page5">5</a>
> +                <a class="text-primary" href="blog/page5">5</a>
>
>          </li>
>
>
>

Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...

Posted by Ignasi Barrera <ig...@gmail.com>.
Well, the script was made progressively and evolved when we found
issues, and until now there hasn't been a need for sticking to a
concrete Jekyll version.
I'm happy with any change that prevents us from committing unnecessary
stuff in the future.

Wanna take it? :)

On 5 September 2014 13:08, Zack Shoylev <za...@rackspace.com> wrote:
> I followed the wiki documentation to deploy. It seems it needs to be updated with specific versions (and anything else if needed).
> Also, I am curious - shouldn't the deploy script check versions then?
>
> ________________________________________
> From: Ignasi Barrera [ignasi.barrera@gmail.com]
> Sent: Friday, September 05, 2014 2:56 AM
> To: dev@jclouds.apache.org
> Subject: Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...
>
> I think it is due to the version of Jekyll. Our Jenkins uses Jekyll
> 1.5.1, and it renders a bit different than older versions (IIRC). We
> should definitely better document that.
> For the next time, there are two options:
>
> * Install Jekyll 1.5.1 and force the version when generating the site
> as explained here [1].
> * Carefully read the script prompt with the changes that are going to
> be committed and just commit the ones that are relevant and discard
> the rest.
>
>
> [1] https://github.com/jclouds/jclouds-site/blob/master/deploy-site.sh#L3-L9
>
> On 4 September 2014 18:35, Zack Shoylev <za...@rackspace.com> wrote:
>> AFAIK latest versions of both. Anything broken?
>> ________________________________________
>> From: Ignasi Barrera [ignasi.barrera@gmail.com]
>> Sent: Thursday, September 04, 2014 11:29 AM
>> To: dev@jclouds.apache.org
>> Subject: Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...
>>
>> Zach wichi version of Jekyll were you using? Did you use the latest
>> version of the script to generate the site?
>>
>> I'm just wondering, why the commit for your blog post modified all those files.
>>
>> In any case, that can be prevented by taking a look at the script
>> output (which should prompt you) and manually adding *only* the
>> relevant files if needed, and discard the rest?
>>
>>
>>
>> On 4 September 2014 17:18,  <za...@apache.org> wrote:
>>> Author: zachsh
>>> Date: Thu Sep  4 15:18:35 2014
>>> New Revision: 1622496
>>>
>>> URL: http://svn.apache.org/r1622496
>>> Log:
>>> deploy jclouds site content
>>>
>>> Added:
>>>     jclouds/site-content/blog/2014/09/
>>>     jclouds/site-content/blog/2014/09/03/
>>>     jclouds/site-content/blog/2014/09/03/better-builders/
>>>     jclouds/site-content/blog/2014/09/03/better-builders/index.html
>>> Modified:
>>>     jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>>>     jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>>>     jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>>>     jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>>>     jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>>>     jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>>>     jclouds/site-content/blog/atom.xml
>>>     jclouds/site-content/blog/index.html
>>>     jclouds/site-content/blog/page2/index.html
>>>     jclouds/site-content/blog/page3/index.html
>>>     jclouds/site-content/blog/page4/index.html
>>>     jclouds/site-content/blog/page5/index.html
>>>     jclouds/site-content/guides/abiquo-cloud/index.html
>>>     jclouds/site-content/guides/abiquo/index.html
>>>     jclouds/site-content/guides/aws-ebs/index.html
>>>     jclouds/site-content/guides/aws-ec2/index.html
>>>     jclouds/site-content/guides/aws-sqs/index.html
>>>     jclouds/site-content/guides/aws/index.html
>>>     jclouds/site-content/guides/azure-storage/index.html
>>>     jclouds/site-content/guides/bluelock/index.html
>>>     jclouds/site-content/guides/chef/index.html
>>>     jclouds/site-content/guides/cloudsigma/index.html
>>>     jclouds/site-content/guides/docker/index.html
>>>     jclouds/site-content/guides/filesystem/index.html
>>>     jclouds/site-content/guides/glacier/index.html
>>>     jclouds/site-content/guides/go-grid/index.html
>>>     jclouds/site-content/guides/hpcloud/index.html
>>>     jclouds/site-content/guides/karaf/index.html
>>>     jclouds/site-content/guides/openstack/index.html
>>>     jclouds/site-content/guides/rackspace/index.html
>>>     jclouds/site-content/guides/vcloud-director/index.html
>>>     jclouds/site-content/guides/vcloud/index.html
>>>     jclouds/site-content/index.html
>>>     jclouds/site-content/reference/configuration/index.html
>>>     jclouds/site-content/reference/logging/index.html
>>>     jclouds/site-content/reference/troubleshooting/index.html
>>>     jclouds/site-content/releasenotes/1.1.0/index.html
>>>     jclouds/site-content/releasenotes/1.2/index.html
>>>     jclouds/site-content/releasenotes/1.6.1/index.html
>>>     jclouds/site-content/releasenotes/1.6.2/index.html
>>>     jclouds/site-content/releasenotes/1.6.3/index.html
>>>     jclouds/site-content/releasenotes/1.7.0/index.html
>>>     jclouds/site-content/releasenotes/1.7.1/index.html
>>>     jclouds/site-content/releasenotes/1.7.2/index.html
>>>     jclouds/site-content/releasenotes/1.7.3/index.html
>>>     jclouds/site-content/releasenotes/atom.xml
>>>     jclouds/site-content/start/blobstore/index.html
>>>     jclouds/site-content/start/compute/index.html
>>>     jclouds/site-content/start/install/index.html
>>>
>>> Modified: jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html (original)
>>> +++ jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html Thu Sep  4 15:18:35 2014
>>> @@ -154,8 +154,7 @@
>>>  <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>>>      <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>>>      <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> +<span class="o">}</span></code></pre></div>
>>>
>>>
>>>  <p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
>>> @@ -170,8 +169,7 @@
>>>      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>>>          <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>>>      <span class="o">}</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> +<span class="o">}</span></code></pre></div>
>>>
>>>
>>>  <p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>>>
>>> Modified: jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html (original)
>>> +++ jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html Thu Sep  4 15:18:35 2014
>>> @@ -158,8 +158,7 @@
>>>
>>>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>>>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
>>> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
>>> -</code></pre></div>
>>> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>>>
>>>
>>>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>>>
>>> Modified: jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html (original)
>>> +++ jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html Thu Sep  4 15:18:35 2014
>>> @@ -162,14 +162,12 @@
>>>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>>>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>>>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
>>> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
>>> -</code></pre></div>
>>> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>>>
>>>
>>>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>>>
>>> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>>>
>>>
>>>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
>>> @@ -182,8 +180,7 @@
>>>
>>>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>>>
>>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>>>
>>>
>>>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
>>> @@ -192,8 +189,7 @@
>>>
>>>  <p>Oh, and don't forget to clean up your nodes :)</p>
>>>
>>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>>>
>>>
>>>
>>>
>>> Modified: jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html (original)
>>> +++ jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html Thu Sep  4 15:18:35 2014
>>> @@ -161,8 +161,7 @@
>>>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>>>          <span class="c1">// ...</span>
>>>      <span class="o">}</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> +<span class="o">}</span></code></pre></div>
>>>
>>>
>>>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
>>> @@ -177,8 +176,7 @@
>>>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>>>          <span class="c1">// ...</span>
>>>      <span class="o">}</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> +<span class="o">}</span></code></pre></div>
>>>
>>>
>>>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
>>> @@ -187,8 +185,7 @@
>>>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>>
>>>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
>>> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>>>
>>> Modified: jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html (original)
>>> +++ jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html Thu Sep  4 15:18:35 2014
>>> @@ -168,8 +168,7 @@
>>>
>>>  <h3>Lazy advance through all your metrics:</h3>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>>>
>>>
>>>  <h3>Â Advance only until we find the load balancer we want:</h3>
>>> @@ -177,14 +176,12 @@
>>>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>>>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>>>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
>>> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
>>> -</code></pre></div>
>>> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>>>
>>>
>>>  <h3>Get only the first page of database instances</h3>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>>>
>>> Modified: jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html (original)
>>> +++ jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html Thu Sep  4 15:18:35 2014
>>> @@ -156,8 +156,7 @@
>>>
>>>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>>>
>>> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>>>
>>>
>>>  <h2>What else is in 1.5.4?</h2>
>>> @@ -168,16 +167,14 @@
>>>
>>>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <h3>Nova Server Diagnostics</h3>
>>>
>>>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <h3>S3 Multi-Object delete</h3>
>>> @@ -185,8 +182,7 @@
>>>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>>>
>>>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
>>> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
>>> -</code></pre></div>
>>> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>>>
>>>
>>>  <h2>What's next</h2>
>>>
>>> Added: jclouds/site-content/blog/2014/09/03/better-builders/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2014/09/03/better-builders/index.html?rev=1622496&view=auto
>>> ==============================================================================
>>> --- jclouds/site-content/blog/2014/09/03/better-builders/index.html (added)
>>> +++ jclouds/site-content/blog/2014/09/03/better-builders/index.html Thu Sep  4 15:18:35 2014
>>> @@ -0,0 +1,344 @@
>>> +<!DOCTYPE html>
>>> +<html lang="en">
>>> +    <head>
>>> +        <meta charset="utf-8">
>>> +<title>Apache jclouds&reg; :: Better Builders with jclouds!</title>
>>> +<meta name="viewport" content="width=device-width, initial-scale=1.0">
>>> +<meta name="description" content="">
>>> +<meta name="author" content="">
>>> +
>>> +<!--link rel="stylesheet/less" href="less/bootstrap.less" type="text/css" /-->
>>> +<!--link rel="stylesheet/less" href="less/responsive.less" type="text/css" /-->
>>> +<!--script src="js/less-1.3.3.min.js"></script-->
>>> +<!--append â?~#!watchâ?T to the browser URL, then refresh the page. -->
>>> +
>>> +<link href="/css/bootstrap.min.css" rel="stylesheet">
>>> +<link href="/css/style.css" rel="stylesheet">
>>> +<link href="/css/syntax.css" rel="stylesheet">
>>> +
>>> +<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
>>> +<!--[if lt IE 9]>
>>> +<script src="js/html5shiv.js"></script>
>>> +<![endif]-->
>>> +
>>> +<!-- Fav and touch icons -->
>>> +<!--
>>> +<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/img/apple-touch-icon-144-precomposed.png">
>>> +<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/apple-touch-icon-114-precomposed.png">
>>> +<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/apple-touch-icon-72-precomposed.png">
>>> +<link rel="apple-touch-icon-precomposed" href="/img/apple-touch-icon-57-precomposed.png">
>>> +-->
>>> +<link rel="shortcut icon" href="/favicon.ico">
>>> +
>>> +<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Blog Posts Feed">
>>> +<link rel="alternate" type="application/atom+xml" href="/releasenotes/atom.xml" title="Release Notes Feed">
>>> +
>>> +<script type="text/javascript" src="/js/jquery.min.js"></script>
>>> +<script type="text/javascript" src="/js/bootstrap.min.js"></script>
>>> +<script type="text/javascript" src="/js/toc.js"></script>
>>> +
>>> +<script type="text/javascript">
>>> +    var _gaq = _gaq || [];
>>> +    _gaq.push(['_setAccount', 'UA-8638379-1']);
>>> +    _gaq.push(['_trackPageview']);
>>> +
>>> +    (function() {
>>> +     var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
>>> +     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
>>> +     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
>>> +     })();
>>> +</script>
>>> +<script type="text/javascript">
>>> +    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
>>> +     (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
>>> +     m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
>>> +     })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
>>> +
>>> +    ga('create', 'UA-47106724-1', 'jclouds.apache.org');
>>> +    ga('send', 'pageview');
>>> +</script>
>>> +
>>> +    </head>
>>> +    <body>
>>> +        <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
>>> +    <div class="container">
>>> +        <div class="navbar-header">
>>> +            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
>>> +                <span class="sr-only">Toggle navigation</span>
>>> +                <span class="icon-bar"></span>
>>> +                <span class="icon-bar"></span>
>>> +                <span class="icon-bar"></span>
>>> +            </button>
>>> +            <a class="navbar-brand" href="/">Apache jclouds &reg;</a>
>>> +        </div>
>>> +
>>> +        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
>>> +            <ul class="nav navbar-nav">
>>> +                <li class="dropdown">
>>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Getting Started<strong class="caret"></strong></a>
>>> +                    <ul class="dropdown-menu">
>>> +                        <li><a href="/start/what-is-jclouds/">What Is Apache jclouds?</a></li>
>>> +                        <li><a href="/start/install/">Installation Guide</a></li>
>>> +                        <li class="divider"></li>
>>> +                        <li><a href="/start/concepts/">Core Concepts</a></li>
>>> +                        <li><a href="/start/compute/">ComputeService</a></li>
>>> +                        <li><a href="/start/blobstore/">BlobStore</a></li>
>>> +                        <li><a href="http://github.com/jclouds/jclouds-examples">Examples</a></li>
>>> +                    </ul>
>>> +                </li>
>>> +                <li class="dropdown">
>>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation<strong class="caret"></strong></a>
>>> +                    <ul class="dropdown-menu">
>>> +                        <li><a href="/reference/providers/">Cloud Providers</a></li>
>>> +                        <li><a href="/guides">User Guides</a></li>
>>> +                        <li><a href="/reference/troubleshooting/">Troubleshooting</a></li>
>>> +                        <li><a href="/reference/configuration/">Configuration</a></li>
>>> +                        <li><a href="/reference/logging/">Logging</a></li>
>>> +                        <li><a href="/reference/javadoc/">Javadoc</a></li>
>>> +                        <li class="divider"></li>
>>> +                        <li class="dropdown-header">Developer Guides</li>
>>> +                        <li><a href="http://wiki.apache.org/jclouds/">Wiki</a></li>
>>> +                    </ul>
>>> +                </li>
>>> +                <li class="dropdown">
>>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Community<strong class="caret"></strong></a>
>>> +                    <ul class="dropdown-menu">
>>> +                        <li><a href="/community/">Get In Touch!</a></li>
>>> +                        <li><a href="http://www.meetup.com/jclouds/">Attend An Event</a></li>
>>> +                        <li><a href="/community/users/">Who Is Using jclouds?</a></li>
>>> +                        <li class="divider"></li>
>>> +                        <li class="dropdown-header">Contribute</li>
>>> +                        <li><a href="/reference/report-a-bug/">Report a Bug</a></li>
>>> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute">How To Contribute Code</a></li>
>>> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">How To Contribute Documentation</a></li>
>>> +                    </ul>
>>> +                </li>
>>> +                <li><a href="/blog">Blog</a></li>
>>> +            </ul>
>>> +            <ul class="nav navbar-nav navbar-right">
>>> +                <li class="dropdown">
>>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Release Notes<strong class="caret"></strong></a>
>>> +                    <ul class="dropdown-menu">
>>> +                        <!-- only keep the release notes for supported versions in this list -->
>>> +                        <li><a href="/releasenotes/1.8.0">1.8.0</a></li>
>>> +                        <li><a href="/releasenotes/1.7.3">1.7.3</a></li>
>>> +                        <li><a href="/releasenotes/1.7.2">1.7.2</a></li>
>>> +                        <li><a href="/releasenotes/1.7.1">1.7.1</a></li>
>>> +                        <li><a href="/releasenotes/1.7.0">1.7.0</a></li>
>>> +                        <li class="divider"></li>
>>> +                        <li class="dropdown-header">Previous releases</li>
>>> +                        <li><a href="/releasenotes">Release archive</a></li>
>>> +                    </ul>
>>> +                </li>
>>> +                <li>
>>> +                    <div>
>>> +                        <a class="btn btn-success navbar-btn" href="/start/install/">
>>> +                            <span class="glyphicon glyphicon-download"></span>
>>> +                            Install
>>> +                        </a>
>>> +                    </div>
>>> +                </li>
>>> +            </ul>
>>> +        </div>
>>> +    </div>
>>> +</nav>
>>> +
>>> +        <div class="container">
>>> +            <div class="page-header">
>>> +                <h1>Better Builders with jclouds!</h1>
>>> +                <span class="text-muted">03 September 2014, by Zack Shoylev</span>
>>> +            </div>
>>> +            <p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
>>> +
>>> +<!--more-->
>>> +
>>> +
>>> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
>>> +
>>> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
>>> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
>>> +        <span class="p">},</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>>> +                <span class="p">{</span>
>>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
>>> +                <span class="p">},</span>
>>> +                <span class="p">{</span>
>>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
>>> +                <span class="p">}</span>
>>> +            <span class="p">],</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
>>> +        <span class="p">},</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
>>> +        <span class="p">},</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>>> +                <span class="p">{</span>
>>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
>>> +                <span class="p">}</span>
>>> +            <span class="p">],</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
>>> +        <span class="p">}</span>
>>> +    <span class="p">]</span>
>>> +<span class="p">}</span></code></pre></div>
>>> +
>>> +
>>> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
>>> +
>>> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
>>> +
>>> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
>>> +
>>> +
>>> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
>>> +
>>> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
>>> +
>>> +<p>Current implementations have the following two issues :</p>
>>> +
>>> +<ol>
>>> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
>>> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
>>> +</ol>
>>> +
>>> +
>>> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
>>> +
>>> +<p>We want to</p>
>>> +
>>> +<ol>
>>> +<li>Ensure object immutability.</li>
>>> +<li>Utilize the fluent builder pattern.</li>
>>> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
>>> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
>>> +<li>Allow using different validation strategies (for example, create vs update).</li>
>>> +</ol>
>>> +
>>> +
>>> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
>>> +
>>> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
>>> +
>>> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
>>> +
>>> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
>>> +
>>> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
>>> +
>>> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
>>> +
>>> +<ol>
>>> +<li>Listing networks returns a Network or a list of Networks.</li>
>>> +<li>Updating a network requires Network.UpdateOptions.</li>
>>> +<li>Creating a network requires Network.CreateOptions.</li>
>>> +</ol>
>>> +
>>> +
>>> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
>>> +
>>> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
>>> +
>>> +<p>This is how it all works out from the developer's perspective:</p>
>>> +
>>> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>> +
>>> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
>>> +
>>> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
>>> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>> +
>>> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
>>> +
>>> +
>>> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
>>> +
>>> +
>>> +            <div id="comments">
>>> +                <hr/>
>>> +                <div id="disqus_thread"></div>
>>> +<script type="text/javascript">
>>> +var disqus_shortname = 'jclouds';
>>> +/* * * DON'T EDIT BELOW THIS LINE * * */
>>> +(function() {
>>> +    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
>>> +    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
>>> +    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
>>> +})();
>>> +</script>
>>> +<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">Comments powered by Disqus.</a></noscript>
>>> +<a href="http://disqus.com" class="dsq-brlink">Comments powered by <span class="logo-disqus">Disqus</span></a>
>>> +
>>> +            </div>
>>> +
>>> +            <div class="row clearfix">
>>> +                <div id="footer" class="col-md-12 column">
>>> +                    <div id="footer">
>>> +    <hr/>
>>> +    <div class="row clearfix">
>>> +        <div class="col-md-2 column">
>>> +            <p class="text-center">
>>> +                <a class="text-primary" href="/start/">Getting Started</a>
>>> +            </p>
>>> +        </div>
>>> +        <div class="col-md-2 column">
>>> +            <p class="text-center">
>>> +                <a class="text-primary" href="/reference/report-a-bug/">Report a Bug</a>
>>> +            </p>
>>> +        </div>
>>> +        <div class="col-md-2 column">
>>> +            <p class="text-center">
>>> +                <a href="https://github.com/jclouds/jclouds-site/edit/master/_posts/2014-09-03-better-builders.md">Fix This Page</a><a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation"><sup>*</sup></a>
>>> +            </p>
>>> +        </div>
>>> +        <div class="col-md-2 column">
>>> +            <p class="text-center">
>>> +                <a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute">Contribute Code</a>
>>> +            </p>
>>> +        </div>
>>> +        <div class="col-md-2 column">
>>> +            <p class="text-center">
>>> +                <a class="text-primary" href="/community/">Contact Us</a>
>>> +            </p>
>>> +        </div>
>>> +        <div class="col-md-2 column">
>>> +            <p class="text-center">
>>> +                <a class="text-primary" href="https://twitter.com/jclouds">Follow Us</a>
>>> +            </p>
>>> +        </div>
>>> +    </div>
>>> +    <hr style="margin-top: 10px"/>
>>> +    <div class="row clearfix">
>>> +        <div class="col-md-12 column">
>>> +            <p class="text-center">
>>> +              Copyright &copy; 2011-2014 <a href="http://www.apache.org">The Apache Software Foundation</a>. All Rights Reserved.
>>> +            </p>
>>> +            <p class="text-center">
>>> +              Apache, jclouds, Apache jclouds, the jclouds logo, and the Apache feather logos are registered trademarks or trademarks of the Apache Software Foundation.
>>> +            </p>
>>> +            <p class="text-center">
>>> +              <img src="/img/feather-small.gif" width="80", height="24"/>
>>> +            </p>
>>> +            <br/>
>>> +        </div>
>>> +    </div>
>>> +</div>
>>> +
>>> +                </div>
>>> +            </div>
>>> +        </div>
>>> +    </body>
>>> +</html>
>>>
>>> Modified: jclouds/site-content/blog/atom.xml
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/atom.xml?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/atom.xml (original)
>>> +++ jclouds/site-content/blog/atom.xml Thu Sep  4 15:18:35 2014
>>> @@ -8,6 +8,131 @@
>>>
>>>
>>>    <entry>
>>> +    <id>http://jclouds.apache.org/blog/2014/09/03/better-builders</id>
>>> +    <title type="html"><![CDATA[Better Builders with jclouds!]]></title>
>>> +    <link href="http://jclouds.apache.org/blog/2014/09/03/better-builders"/>
>>> +    <updated>2014-09-03T00:00:00Z</updated>
>>> +    <content type="html"><![CDATA[<p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
>>> +
>>> +<!--more-->
>>> +
>>> +
>>> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
>>> +
>>> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
>>> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
>>> +        <span class="p">},</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>>> +                <span class="p">{</span>
>>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
>>> +                <span class="p">},</span>
>>> +                <span class="p">{</span>
>>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
>>> +                <span class="p">}</span>
>>> +            <span class="p">],</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
>>> +        <span class="p">},</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
>>> +        <span class="p">},</span>
>>> +        <span class="p">{</span>
>>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>>> +                <span class="p">{</span>
>>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
>>> +                <span class="p">}</span>
>>> +            <span class="p">],</span>
>>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
>>> +        <span class="p">}</span>
>>> +    <span class="p">]</span>
>>> +<span class="p">}</span></code></pre></div>
>>> +
>>> +
>>> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
>>> +
>>> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
>>> +
>>> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
>>> +
>>> +
>>> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
>>> +
>>> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
>>> +
>>> +<p>Current implementations have the following two issues :</p>
>>> +
>>> +<ol>
>>> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
>>> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
>>> +</ol>
>>> +
>>> +
>>> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
>>> +
>>> +<p>We want to</p>
>>> +
>>> +<ol>
>>> +<li>Ensure object immutability.</li>
>>> +<li>Utilize the fluent builder pattern.</li>
>>> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
>>> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
>>> +<li>Allow using different validation strategies (for example, create vs update).</li>
>>> +</ol>
>>> +
>>> +
>>> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
>>> +
>>> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
>>> +
>>> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
>>> +
>>> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
>>> +
>>> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
>>> +
>>> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
>>> +
>>> +<ol>
>>> +<li>Listing networks returns a Network or a list of Networks.</li>
>>> +<li>Updating a network requires Network.UpdateOptions.</li>
>>> +<li>Creating a network requires Network.CreateOptions.</li>
>>> +</ol>
>>> +
>>> +
>>> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
>>> +
>>> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
>>> +
>>> +<p>This is how it all works out from the developer's perspective:</p>
>>> +
>>> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>> +
>>> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
>>> +
>>> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
>>> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>> +
>>> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
>>> +
>>> +
>>> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
>>> +]]></content>
>>> +  </entry>
>>> +
>>> +  <entry>
>>>      <id>http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers</id>
>>>      <title type="html"><![CDATA[1 release, 2 committers...a busy week for jclouds!]]></title>
>>>      <link href="http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers"/>
>>> @@ -480,8 +605,7 @@
>>>
>>>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>>>
>>> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>>>
>>>
>>>  <h2>What else is in 1.5.4?</h2>
>>> @@ -492,16 +616,14 @@
>>>
>>>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <h3>Nova Server Diagnostics</h3>
>>>
>>>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <h3>S3 Multi-Object delete</h3>
>>> @@ -509,8 +631,7 @@
>>>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>>>
>>>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
>>> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
>>> -</code></pre></div>
>>> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>>>
>>>
>>>  <h2>What's next</h2>
>>> @@ -602,8 +723,7 @@
>>>
>>>  <h3>Lazy advance through all your metrics:</h3>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>>>
>>>
>>>  <h3>Â Advance only until we find the load balancer we want:</h3>
>>> @@ -611,14 +731,12 @@
>>>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>>>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>>>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
>>> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
>>> -</code></pre></div>
>>> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>>>
>>>
>>>  <h3>Get only the first page of database instances</h3>
>>>
>>> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>>> @@ -655,8 +773,7 @@
>>>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>>>          <span class="c1">// ...</span>
>>>      <span class="o">}</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> +<span class="o">}</span></code></pre></div>
>>>
>>>
>>>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
>>> @@ -671,8 +788,7 @@
>>>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>>>          <span class="c1">// ...</span>
>>>      <span class="o">}</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> +<span class="o">}</span></code></pre></div>
>>>
>>>
>>>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
>>> @@ -681,8 +797,7 @@
>>>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>>
>>>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
>>> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
>>> -</code></pre></div>
>>> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>>>
>>>
>>>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>>> @@ -710,14 +825,12 @@
>>>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>>>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>>>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
>>> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
>>> -</code></pre></div>
>>> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>>>
>>>
>>>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>>>
>>> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>>>
>>>
>>>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
>>> @@ -730,8 +843,7 @@
>>>
>>>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>>>
>>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>>>
>>>
>>>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
>>> @@ -740,8 +852,7 @@
>>>
>>>  <p>Oh, and don't forget to clean up your nodes :)</p>
>>>
>>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
>>> -</code></pre></div>
>>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>>>
>>>
>>>
>>> @@ -862,8 +973,7 @@
>>>
>>>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>>>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
>>> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
>>> -</code></pre></div>
>>> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>>>
>>>
>>>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>>> @@ -876,41 +986,4 @@
>>>  ]]></content>
>>>    </entry>
>>>
>>> -  <entry>
>>> -    <id>http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes</id>
>>> -    <title type="html"><![CDATA[Catching exceptions with fewer keystrokes]]></title>
>>> -    <link href="http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes"/>
>>> -    <updated>2009-05-13T00:00:00Z</updated>
>>> -    <content type="html"><![CDATA[<p>Some of us hate checked exceptions, but still use them for one reason or another. A common problem we have is unnecessary exception nesting, or runtime swallowing. This often leads to the all to familiar and crufty code with a million catch blocks. jclouds has a slightly different approach that strikes a balance, allowing checked exceptions to be dealt with, but without the pain of so many lines of repetitious code.</p>
>>> -
>>> -<div class="highlight"><pre><code class="java"><span class="k">try</span> <span class="o">{</span>
>>> -<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>>> -    <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>>> -    <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> -
>>> -
>>> -<p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
>>> -
>>> -<p>Now, this code shouldn't work, as current versions of java hava a generic type erasure problem. The reason it does work is a somewhat hackish line in the rethrowIfRuntimeOrSameType method:</p>
>>> -
>>> -<div class="highlight"><pre><code class="java"><span class="k">if</span> <span class="o">(</span><span class="n">e</span> <span class="k">instanceof</span> <span class="n">RuntimeException</span><span class="o">)</span> <span class="o">{</span>
>>> -    <span class="k">throw</span> <span class="o">(</span><span class="n">RuntimeException</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
>>> -<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
>>> -    <span class="k">try</span> <span class="o">{</span>
>>> -        <span class="k">throw</span> <span class="o">(</span><span class="n">E</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
>>> -    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>>> -        <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>>> -    <span class="o">}</span>
>>> -<span class="o">}</span>
>>> -</code></pre></div>
>>> -
>>> -
>>> -<p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>>> -
>>> -<p>If nothing else, I hope you enjoy the perspective!</p>
>>> -]]></content>
>>> -  </entry>
>>> -
>>>  </feed>
>>>
>>> Modified: jclouds/site-content/blog/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/index.html (original)
>>> +++ jclouds/site-content/blog/index.html Thu Sep  4 15:18:35 2014
>>> @@ -150,6 +150,12 @@
>>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>>
>>>
>>> +<h3><a class="text-primary" href="/blog/2014/09/03/better-builders">Better Builders with jclouds!</a></h3>
>>> +<span class="text-muted">03 September 2014, by Zack Shoylev</span>
>>> +<p>If you are a new jclouds developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.
>>> +</p>
>>> +
>>>  <h3><a class="text-primary" href="/blog/2014/08/04/1-release-2-committers">1 release, 2 committers...a busy week for jclouds!</a></h3>
>>>  <span class="text-muted">04 August 2014, by <a href="http://blog.xebialabs.com/author/aphillips/">Andrew Phillips</a></span>
>>>  <p>There's a lot going on this week for the jclouds community. Most importantly, we're really pleased to introduce two new committers: Andrea Turli and Chris Custine.
>>> @@ -170,11 +176,6 @@
>>>  <p>The Google Summer of Code (GSoC) accepted projects have been announced and we will have 3 students working on jclouds related projects!
>>>  </p>
>>>
>>> -<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
>>> -<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
>>> -<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
>>> -</p>
>>> -
>>>
>>>
>>>  <ul class="pagination text-center">
>>> @@ -189,25 +190,25 @@
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page2">2</a>
>>> +                <a class="text-primary" href="blog/page2">2</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page3">3</a>
>>> +                <a class="text-primary" href="blog/page3">3</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page4">4</a>
>>> +                <a class="text-primary" href="blog/page4">4</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page5">5</a>
>>> +                <a class="text-primary" href="blog/page5">5</a>
>>>
>>>          </li>
>>>
>>>
>>> Modified: jclouds/site-content/blog/page2/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page2/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/page2/index.html (original)
>>> +++ jclouds/site-content/blog/page2/index.html Thu Sep  4 15:18:35 2014
>>> @@ -150,6 +150,11 @@
>>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>>
>>>
>>> +<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
>>> +<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
>>> +<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
>>> +</p>
>>> +
>>>  <h3><a class="text-primary" href="/blog/2014/03/03/joining-the-asf-new-site-and-jclouds-1-7">Joining the ASF, new site, and jclouds 1.7!</a></h3>
>>>  <span class="text-muted">03 March 2014, by Ignasi Barrera</span>
>>>  <p>It's been a while since our last blog post, and lots has happened since then. There have been many things that have kept us busy, and finally, all the hard work is starting to show up. During this time, we've:
>>> @@ -170,11 +175,6 @@
>>>  <p>jclouds community is an international group with over 100 contributors since we started in early 2009. The idea of holidays vary, but we decided Mistletoe as an appropriate codename for jclouds 1.5.4. Here's why.
>>>  </p>
>>>
>>> -<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
>>> -<span class="text-muted">17 November 2012, by Adrian Cole</span>
>>> -<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
>>> -</p>
>>> -
>>>
>>>
>>>  <ul class="pagination text-center">
>>> @@ -191,25 +191,25 @@
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page2">2</a>
>>> +                <a class="text-primary" href="blog/page2">2</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page3">3</a>
>>> +                <a class="text-primary" href="blog/page3">3</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page4">4</a>
>>> +                <a class="text-primary" href="blog/page4">4</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page5">5</a>
>>> +                <a class="text-primary" href="blog/page5">5</a>
>>>
>>>          </li>
>>>
>>>
>>> Modified: jclouds/site-content/blog/page3/index.html
>>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page3/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>>> ==============================================================================
>>> --- jclouds/site-content/blog/page3/index.html (original)
>>> +++ jclouds/site-content/blog/page3/index.html Thu Sep  4 15:18:35 2014
>>> @@ -150,6 +150,11 @@
>>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>>
>>>
>>> +<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
>>> +<span class="text-muted">17 November 2012, by Adrian Cole</span>
>>> +<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
>>> +</p>
>>> +
>>>  <h3><a class="text-primary" href="/blog/2012/11/09/500-jclouds-builds-on-buildhive-and-counting">500 jclouds builds on BuildHive and counting...</a></h3>
>>>  <span class="text-muted">09 November 2012, by Adrian Cole</span>
>>>  <p>At jclouds, we've been running our Jenkins continuous integration jobs in CloudBees' DEV@cloud for a while now (CloudBees has a FOSS programme). We also have an active and ever-increasing contributor community, which amongst others means... lots of pull requests.
>>> @@ -170,11 +175,6 @@
>>>  <p>We are very near beta, I promise! In the mean time, we just cut a new codebase with a bunch of cool new toys. Here's a few. Thanks to Adam Lowe, we are getting even deeper into OpenStack with more Keystone support than ever. Setup your code to pull org.jclouds.labs/openstack-keystone, and you can do stuff like this.
>>>  </p>
>>>
>>> -<h3><a class="text-primary" href="/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and">Take a peek at vCloud Director 1.5, OpenStack, and VirtualBox</a></h3>
>>> -<span class="text-muted">23 March 2012, by Adrian Cole</span>
>>> -<p>The jclouds team have been working very hard lately, particularly on a few new apis. We've decided to cage them no longer and cut jclouds 1.5.0-alpha.1. Most notably, we've added the openstack-nova api, and three new providers, all of which discovered via OpenStack Keystone v2.0.
>>> -</p>
>>> -
>>>
>>>
>>>  <ul class="pagination text-center">
>>> @@ -191,25 +191,25 @@
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page2">2</a>
>>> +                <a class="text-primary" href="blog/page2">2</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page3">3</a>
>>> +                <a class="text-primary" href="blog/page3">3</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page4">4</a>
>>> +                <a class="text-primary" href="blog/page4">4</a>
>>>
>>>          </li>
>>>
>>>          <li>
>>>
>>> -                <a class="text-primary" href="/blog/page5">5</a>
>>> +                <a class="text-primary" href="blog/page5">5</a>
>>>
>>>          </li>
>>>
>>>
>>>

RE: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...

Posted by Zack Shoylev <za...@RACKSPACE.COM>.
I followed the wiki documentation to deploy. It seems it needs to be updated with specific versions (and anything else if needed).
Also, I am curious - shouldn't the deploy script check versions then?

________________________________________
From: Ignasi Barrera [ignasi.barrera@gmail.com]
Sent: Friday, September 05, 2014 2:56 AM
To: dev@jclouds.apache.org
Subject: Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...

I think it is due to the version of Jekyll. Our Jenkins uses Jekyll
1.5.1, and it renders a bit different than older versions (IIRC). We
should definitely better document that.
For the next time, there are two options:

* Install Jekyll 1.5.1 and force the version when generating the site
as explained here [1].
* Carefully read the script prompt with the changes that are going to
be committed and just commit the ones that are relevant and discard
the rest.


[1] https://github.com/jclouds/jclouds-site/blob/master/deploy-site.sh#L3-L9

On 4 September 2014 18:35, Zack Shoylev <za...@rackspace.com> wrote:
> AFAIK latest versions of both. Anything broken?
> ________________________________________
> From: Ignasi Barrera [ignasi.barrera@gmail.com]
> Sent: Thursday, September 04, 2014 11:29 AM
> To: dev@jclouds.apache.org
> Subject: Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...
>
> Zach wichi version of Jekyll were you using? Did you use the latest
> version of the script to generate the site?
>
> I'm just wondering, why the commit for your blog post modified all those files.
>
> In any case, that can be prevented by taking a look at the script
> output (which should prompt you) and manually adding *only* the
> relevant files if needed, and discard the rest?
>
>
>
> On 4 September 2014 17:18,  <za...@apache.org> wrote:
>> Author: zachsh
>> Date: Thu Sep  4 15:18:35 2014
>> New Revision: 1622496
>>
>> URL: http://svn.apache.org/r1622496
>> Log:
>> deploy jclouds site content
>>
>> Added:
>>     jclouds/site-content/blog/2014/09/
>>     jclouds/site-content/blog/2014/09/03/
>>     jclouds/site-content/blog/2014/09/03/better-builders/
>>     jclouds/site-content/blog/2014/09/03/better-builders/index.html
>> Modified:
>>     jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>>     jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>>     jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>>     jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>>     jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>>     jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>>     jclouds/site-content/blog/atom.xml
>>     jclouds/site-content/blog/index.html
>>     jclouds/site-content/blog/page2/index.html
>>     jclouds/site-content/blog/page3/index.html
>>     jclouds/site-content/blog/page4/index.html
>>     jclouds/site-content/blog/page5/index.html
>>     jclouds/site-content/guides/abiquo-cloud/index.html
>>     jclouds/site-content/guides/abiquo/index.html
>>     jclouds/site-content/guides/aws-ebs/index.html
>>     jclouds/site-content/guides/aws-ec2/index.html
>>     jclouds/site-content/guides/aws-sqs/index.html
>>     jclouds/site-content/guides/aws/index.html
>>     jclouds/site-content/guides/azure-storage/index.html
>>     jclouds/site-content/guides/bluelock/index.html
>>     jclouds/site-content/guides/chef/index.html
>>     jclouds/site-content/guides/cloudsigma/index.html
>>     jclouds/site-content/guides/docker/index.html
>>     jclouds/site-content/guides/filesystem/index.html
>>     jclouds/site-content/guides/glacier/index.html
>>     jclouds/site-content/guides/go-grid/index.html
>>     jclouds/site-content/guides/hpcloud/index.html
>>     jclouds/site-content/guides/karaf/index.html
>>     jclouds/site-content/guides/openstack/index.html
>>     jclouds/site-content/guides/rackspace/index.html
>>     jclouds/site-content/guides/vcloud-director/index.html
>>     jclouds/site-content/guides/vcloud/index.html
>>     jclouds/site-content/index.html
>>     jclouds/site-content/reference/configuration/index.html
>>     jclouds/site-content/reference/logging/index.html
>>     jclouds/site-content/reference/troubleshooting/index.html
>>     jclouds/site-content/releasenotes/1.1.0/index.html
>>     jclouds/site-content/releasenotes/1.2/index.html
>>     jclouds/site-content/releasenotes/1.6.1/index.html
>>     jclouds/site-content/releasenotes/1.6.2/index.html
>>     jclouds/site-content/releasenotes/1.6.3/index.html
>>     jclouds/site-content/releasenotes/1.7.0/index.html
>>     jclouds/site-content/releasenotes/1.7.1/index.html
>>     jclouds/site-content/releasenotes/1.7.2/index.html
>>     jclouds/site-content/releasenotes/1.7.3/index.html
>>     jclouds/site-content/releasenotes/atom.xml
>>     jclouds/site-content/start/blobstore/index.html
>>     jclouds/site-content/start/compute/index.html
>>     jclouds/site-content/start/install/index.html
>>
>> Modified: jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html (original)
>> +++ jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html Thu Sep  4 15:18:35 2014
>> @@ -154,8 +154,7 @@
>>  <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>>      <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>>      <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
>> @@ -170,8 +169,7 @@
>>      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>>          <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>>
>> Modified: jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html (original)
>> +++ jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html Thu Sep  4 15:18:35 2014
>> @@ -158,8 +158,7 @@
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
>> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
>> -</code></pre></div>
>> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>>
>>
>>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>>
>> Modified: jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html (original)
>> +++ jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html Thu Sep  4 15:18:35 2014
>> @@ -162,14 +162,12 @@
>>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
>> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
>> -</code></pre></div>
>> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>>
>>
>>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>>
>> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>>
>>
>>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
>> @@ -182,8 +180,7 @@
>>
>>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>>
>>
>>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
>> @@ -192,8 +189,7 @@
>>
>>  <p>Oh, and don't forget to clean up your nodes :)</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>>
>>
>>
>>
>> Modified: jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html (original)
>> +++ jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html Thu Sep  4 15:18:35 2014
>> @@ -161,8 +161,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
>> @@ -177,8 +176,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
>> @@ -187,8 +185,7 @@
>>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>
>>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
>> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
>> -</code></pre></div>
>> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>>
>> Modified: jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html (original)
>> +++ jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html Thu Sep  4 15:18:35 2014
>> @@ -168,8 +168,7 @@
>>
>>  <h3>Lazy advance through all your metrics:</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>>
>>
>>  <h3>Â Advance only until we find the load balancer we want:</h3>
>> @@ -177,14 +176,12 @@
>>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
>> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
>> -</code></pre></div>
>> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h3>Get only the first page of database instances</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>>
>> Modified: jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html (original)
>> +++ jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html Thu Sep  4 15:18:35 2014
>> @@ -156,8 +156,7 @@
>>
>>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>>
>> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>>
>>
>>  <h2>What else is in 1.5.4?</h2>
>> @@ -168,16 +167,14 @@
>>
>>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>Nova Server Diagnostics</h3>
>>
>>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>S3 Multi-Object delete</h3>
>> @@ -185,8 +182,7 @@
>>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
>> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
>> -</code></pre></div>
>> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h2>What's next</h2>
>>
>> Added: jclouds/site-content/blog/2014/09/03/better-builders/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2014/09/03/better-builders/index.html?rev=1622496&view=auto
>> ==============================================================================
>> --- jclouds/site-content/blog/2014/09/03/better-builders/index.html (added)
>> +++ jclouds/site-content/blog/2014/09/03/better-builders/index.html Thu Sep  4 15:18:35 2014
>> @@ -0,0 +1,344 @@
>> +<!DOCTYPE html>
>> +<html lang="en">
>> +    <head>
>> +        <meta charset="utf-8">
>> +<title>Apache jclouds&reg; :: Better Builders with jclouds!</title>
>> +<meta name="viewport" content="width=device-width, initial-scale=1.0">
>> +<meta name="description" content="">
>> +<meta name="author" content="">
>> +
>> +<!--link rel="stylesheet/less" href="less/bootstrap.less" type="text/css" /-->
>> +<!--link rel="stylesheet/less" href="less/responsive.less" type="text/css" /-->
>> +<!--script src="js/less-1.3.3.min.js"></script-->
>> +<!--append â?~#!watchâ?T to the browser URL, then refresh the page. -->
>> +
>> +<link href="/css/bootstrap.min.css" rel="stylesheet">
>> +<link href="/css/style.css" rel="stylesheet">
>> +<link href="/css/syntax.css" rel="stylesheet">
>> +
>> +<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
>> +<!--[if lt IE 9]>
>> +<script src="js/html5shiv.js"></script>
>> +<![endif]-->
>> +
>> +<!-- Fav and touch icons -->
>> +<!--
>> +<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/img/apple-touch-icon-144-precomposed.png">
>> +<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/apple-touch-icon-114-precomposed.png">
>> +<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/apple-touch-icon-72-precomposed.png">
>> +<link rel="apple-touch-icon-precomposed" href="/img/apple-touch-icon-57-precomposed.png">
>> +-->
>> +<link rel="shortcut icon" href="/favicon.ico">
>> +
>> +<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Blog Posts Feed">
>> +<link rel="alternate" type="application/atom+xml" href="/releasenotes/atom.xml" title="Release Notes Feed">
>> +
>> +<script type="text/javascript" src="/js/jquery.min.js"></script>
>> +<script type="text/javascript" src="/js/bootstrap.min.js"></script>
>> +<script type="text/javascript" src="/js/toc.js"></script>
>> +
>> +<script type="text/javascript">
>> +    var _gaq = _gaq || [];
>> +    _gaq.push(['_setAccount', 'UA-8638379-1']);
>> +    _gaq.push(['_trackPageview']);
>> +
>> +    (function() {
>> +     var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
>> +     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
>> +     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
>> +     })();
>> +</script>
>> +<script type="text/javascript">
>> +    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
>> +     (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
>> +     m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
>> +     })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
>> +
>> +    ga('create', 'UA-47106724-1', 'jclouds.apache.org');
>> +    ga('send', 'pageview');
>> +</script>
>> +
>> +    </head>
>> +    <body>
>> +        <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
>> +    <div class="container">
>> +        <div class="navbar-header">
>> +            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
>> +                <span class="sr-only">Toggle navigation</span>
>> +                <span class="icon-bar"></span>
>> +                <span class="icon-bar"></span>
>> +                <span class="icon-bar"></span>
>> +            </button>
>> +            <a class="navbar-brand" href="/">Apache jclouds &reg;</a>
>> +        </div>
>> +
>> +        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
>> +            <ul class="nav navbar-nav">
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Getting Started<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <li><a href="/start/what-is-jclouds/">What Is Apache jclouds?</a></li>
>> +                        <li><a href="/start/install/">Installation Guide</a></li>
>> +                        <li class="divider"></li>
>> +                        <li><a href="/start/concepts/">Core Concepts</a></li>
>> +                        <li><a href="/start/compute/">ComputeService</a></li>
>> +                        <li><a href="/start/blobstore/">BlobStore</a></li>
>> +                        <li><a href="http://github.com/jclouds/jclouds-examples">Examples</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <li><a href="/reference/providers/">Cloud Providers</a></li>
>> +                        <li><a href="/guides">User Guides</a></li>
>> +                        <li><a href="/reference/troubleshooting/">Troubleshooting</a></li>
>> +                        <li><a href="/reference/configuration/">Configuration</a></li>
>> +                        <li><a href="/reference/logging/">Logging</a></li>
>> +                        <li><a href="/reference/javadoc/">Javadoc</a></li>
>> +                        <li class="divider"></li>
>> +                        <li class="dropdown-header">Developer Guides</li>
>> +                        <li><a href="http://wiki.apache.org/jclouds/">Wiki</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Community<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <li><a href="/community/">Get In Touch!</a></li>
>> +                        <li><a href="http://www.meetup.com/jclouds/">Attend An Event</a></li>
>> +                        <li><a href="/community/users/">Who Is Using jclouds?</a></li>
>> +                        <li class="divider"></li>
>> +                        <li class="dropdown-header">Contribute</li>
>> +                        <li><a href="/reference/report-a-bug/">Report a Bug</a></li>
>> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute">How To Contribute Code</a></li>
>> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">How To Contribute Documentation</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li><a href="/blog">Blog</a></li>
>> +            </ul>
>> +            <ul class="nav navbar-nav navbar-right">
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Release Notes<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <!-- only keep the release notes for supported versions in this list -->
>> +                        <li><a href="/releasenotes/1.8.0">1.8.0</a></li>
>> +                        <li><a href="/releasenotes/1.7.3">1.7.3</a></li>
>> +                        <li><a href="/releasenotes/1.7.2">1.7.2</a></li>
>> +                        <li><a href="/releasenotes/1.7.1">1.7.1</a></li>
>> +                        <li><a href="/releasenotes/1.7.0">1.7.0</a></li>
>> +                        <li class="divider"></li>
>> +                        <li class="dropdown-header">Previous releases</li>
>> +                        <li><a href="/releasenotes">Release archive</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li>
>> +                    <div>
>> +                        <a class="btn btn-success navbar-btn" href="/start/install/">
>> +                            <span class="glyphicon glyphicon-download"></span>
>> +                            Install
>> +                        </a>
>> +                    </div>
>> +                </li>
>> +            </ul>
>> +        </div>
>> +    </div>
>> +</nav>
>> +
>> +        <div class="container">
>> +            <div class="page-header">
>> +                <h1>Better Builders with jclouds!</h1>
>> +                <span class="text-muted">03 September 2014, by Zack Shoylev</span>
>> +            </div>
>> +            <p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
>> +
>> +<!--more-->
>> +
>> +
>> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
>> +
>> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
>> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
>> +                <span class="p">},</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
>> +        <span class="p">}</span>
>> +    <span class="p">]</span>
>> +<span class="p">}</span></code></pre></div>
>> +
>> +
>> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
>> +
>> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
>> +
>> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
>> +
>> +<p>Current implementations have the following two issues :</p>
>> +
>> +<ol>
>> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
>> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
>> +</ol>
>> +
>> +
>> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
>> +
>> +<p>We want to</p>
>> +
>> +<ol>
>> +<li>Ensure object immutability.</li>
>> +<li>Utilize the fluent builder pattern.</li>
>> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
>> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
>> +<li>Allow using different validation strategies (for example, create vs update).</li>
>> +</ol>
>> +
>> +
>> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
>> +
>> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
>> +
>> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
>> +
>> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
>> +
>> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
>> +
>> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
>> +
>> +<ol>
>> +<li>Listing networks returns a Network or a list of Networks.</li>
>> +<li>Updating a network requires Network.UpdateOptions.</li>
>> +<li>Creating a network requires Network.CreateOptions.</li>
>> +</ol>
>> +
>> +
>> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
>> +
>> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
>> +
>> +<p>This is how it all works out from the developer's perspective:</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
>> +
>> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
>> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
>> +
>> +
>> +            <div id="comments">
>> +                <hr/>
>> +                <div id="disqus_thread"></div>
>> +<script type="text/javascript">
>> +var disqus_shortname = 'jclouds';
>> +/* * * DON'T EDIT BELOW THIS LINE * * */
>> +(function() {
>> +    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
>> +    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
>> +    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
>> +})();
>> +</script>
>> +<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">Comments powered by Disqus.</a></noscript>
>> +<a href="http://disqus.com" class="dsq-brlink">Comments powered by <span class="logo-disqus">Disqus</span></a>
>> +
>> +            </div>
>> +
>> +            <div class="row clearfix">
>> +                <div id="footer" class="col-md-12 column">
>> +                    <div id="footer">
>> +    <hr/>
>> +    <div class="row clearfix">
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="/start/">Getting Started</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="/reference/report-a-bug/">Report a Bug</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a href="https://github.com/jclouds/jclouds-site/edit/master/_posts/2014-09-03-better-builders.md">Fix This Page</a><a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation"><sup>*</sup></a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute">Contribute Code</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="/community/">Contact Us</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="https://twitter.com/jclouds">Follow Us</a>
>> +            </p>
>> +        </div>
>> +    </div>
>> +    <hr style="margin-top: 10px"/>
>> +    <div class="row clearfix">
>> +        <div class="col-md-12 column">
>> +            <p class="text-center">
>> +              Copyright &copy; 2011-2014 <a href="http://www.apache.org">The Apache Software Foundation</a>. All Rights Reserved.
>> +            </p>
>> +            <p class="text-center">
>> +              Apache, jclouds, Apache jclouds, the jclouds logo, and the Apache feather logos are registered trademarks or trademarks of the Apache Software Foundation.
>> +            </p>
>> +            <p class="text-center">
>> +              <img src="/img/feather-small.gif" width="80", height="24"/>
>> +            </p>
>> +            <br/>
>> +        </div>
>> +    </div>
>> +</div>
>> +
>> +                </div>
>> +            </div>
>> +        </div>
>> +    </body>
>> +</html>
>>
>> Modified: jclouds/site-content/blog/atom.xml
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/atom.xml?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/atom.xml (original)
>> +++ jclouds/site-content/blog/atom.xml Thu Sep  4 15:18:35 2014
>> @@ -8,6 +8,131 @@
>>
>>
>>    <entry>
>> +    <id>http://jclouds.apache.org/blog/2014/09/03/better-builders</id>
>> +    <title type="html"><![CDATA[Better Builders with jclouds!]]></title>
>> +    <link href="http://jclouds.apache.org/blog/2014/09/03/better-builders"/>
>> +    <updated>2014-09-03T00:00:00Z</updated>
>> +    <content type="html"><![CDATA[<p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
>> +
>> +<!--more-->
>> +
>> +
>> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
>> +
>> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
>> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
>> +                <span class="p">},</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
>> +        <span class="p">}</span>
>> +    <span class="p">]</span>
>> +<span class="p">}</span></code></pre></div>
>> +
>> +
>> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
>> +
>> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
>> +
>> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
>> +
>> +<p>Current implementations have the following two issues :</p>
>> +
>> +<ol>
>> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
>> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
>> +</ol>
>> +
>> +
>> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
>> +
>> +<p>We want to</p>
>> +
>> +<ol>
>> +<li>Ensure object immutability.</li>
>> +<li>Utilize the fluent builder pattern.</li>
>> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
>> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
>> +<li>Allow using different validation strategies (for example, create vs update).</li>
>> +</ol>
>> +
>> +
>> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
>> +
>> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
>> +
>> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
>> +
>> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
>> +
>> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
>> +
>> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
>> +
>> +<ol>
>> +<li>Listing networks returns a Network or a list of Networks.</li>
>> +<li>Updating a network requires Network.UpdateOptions.</li>
>> +<li>Creating a network requires Network.CreateOptions.</li>
>> +</ol>
>> +
>> +
>> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
>> +
>> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
>> +
>> +<p>This is how it all works out from the developer's perspective:</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
>> +
>> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
>> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
>> +]]></content>
>> +  </entry>
>> +
>> +  <entry>
>>      <id>http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers</id>
>>      <title type="html"><![CDATA[1 release, 2 committers...a busy week for jclouds!]]></title>
>>      <link href="http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers"/>
>> @@ -480,8 +605,7 @@
>>
>>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>>
>> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>>
>>
>>  <h2>What else is in 1.5.4?</h2>
>> @@ -492,16 +616,14 @@
>>
>>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>Nova Server Diagnostics</h3>
>>
>>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>S3 Multi-Object delete</h3>
>> @@ -509,8 +631,7 @@
>>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
>> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
>> -</code></pre></div>
>> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h2>What's next</h2>
>> @@ -602,8 +723,7 @@
>>
>>  <h3>Lazy advance through all your metrics:</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>>
>>
>>  <h3>Â Advance only until we find the load balancer we want:</h3>
>> @@ -611,14 +731,12 @@
>>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
>> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
>> -</code></pre></div>
>> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h3>Get only the first page of database instances</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>> @@ -655,8 +773,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
>> @@ -671,8 +788,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
>> @@ -681,8 +797,7 @@
>>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>
>>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
>> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
>> -</code></pre></div>
>> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>> @@ -710,14 +825,12 @@
>>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
>> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
>> -</code></pre></div>
>> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>>
>>
>>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>>
>> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>>
>>
>>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
>> @@ -730,8 +843,7 @@
>>
>>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>>
>>
>>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
>> @@ -740,8 +852,7 @@
>>
>>  <p>Oh, and don't forget to clean up your nodes :)</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>>
>>
>>
>> @@ -862,8 +973,7 @@
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
>> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
>> -</code></pre></div>
>> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>>
>>
>>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>> @@ -876,41 +986,4 @@
>>  ]]></content>
>>    </entry>
>>
>> -  <entry>
>> -    <id>http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes</id>
>> -    <title type="html"><![CDATA[Catching exceptions with fewer keystrokes]]></title>
>> -    <link href="http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes"/>
>> -    <updated>2009-05-13T00:00:00Z</updated>
>> -    <content type="html"><![CDATA[<p>Some of us hate checked exceptions, but still use them for one reason or another. A common problem we have is unnecessary exception nesting, or runtime swallowing. This often leads to the all to familiar and crufty code with a million catch blocks. jclouds has a slightly different approach that strikes a balance, allowing checked exceptions to be dealt with, but without the pain of so many lines of repetitious code.</p>
>> -
>> -<div class="highlight"><pre><code class="java"><span class="k">try</span> <span class="o">{</span>
>> -<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>> -    <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>> -    <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> -
>> -
>> -<p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
>> -
>> -<p>Now, this code shouldn't work, as current versions of java hava a generic type erasure problem. The reason it does work is a somewhat hackish line in the rethrowIfRuntimeOrSameType method:</p>
>> -
>> -<div class="highlight"><pre><code class="java"><span class="k">if</span> <span class="o">(</span><span class="n">e</span> <span class="k">instanceof</span> <span class="n">RuntimeException</span><span class="o">)</span> <span class="o">{</span>
>> -    <span class="k">throw</span> <span class="o">(</span><span class="n">RuntimeException</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
>> -<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
>> -    <span class="k">try</span> <span class="o">{</span>
>> -        <span class="k">throw</span> <span class="o">(</span><span class="n">E</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
>> -    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>> -        <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>> -    <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> -
>> -
>> -<p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>> -
>> -<p>If nothing else, I hope you enjoy the perspective!</p>
>> -]]></content>
>> -  </entry>
>> -
>>  </feed>
>>
>> Modified: jclouds/site-content/blog/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/index.html (original)
>> +++ jclouds/site-content/blog/index.html Thu Sep  4 15:18:35 2014
>> @@ -150,6 +150,12 @@
>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>
>>
>> +<h3><a class="text-primary" href="/blog/2014/09/03/better-builders">Better Builders with jclouds!</a></h3>
>> +<span class="text-muted">03 September 2014, by Zack Shoylev</span>
>> +<p>If you are a new jclouds developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.
>> +</p>
>> +
>>  <h3><a class="text-primary" href="/blog/2014/08/04/1-release-2-committers">1 release, 2 committers...a busy week for jclouds!</a></h3>
>>  <span class="text-muted">04 August 2014, by <a href="http://blog.xebialabs.com/author/aphillips/">Andrew Phillips</a></span>
>>  <p>There's a lot going on this week for the jclouds community. Most importantly, we're really pleased to introduce two new committers: Andrea Turli and Chris Custine.
>> @@ -170,11 +176,6 @@
>>  <p>The Google Summer of Code (GSoC) accepted projects have been announced and we will have 3 students working on jclouds related projects!
>>  </p>
>>
>> -<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
>> -<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
>> -<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
>> -</p>
>> -
>>
>>
>>  <ul class="pagination text-center">
>> @@ -189,25 +190,25 @@
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page2">2</a>
>> +                <a class="text-primary" href="blog/page2">2</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page3">3</a>
>> +                <a class="text-primary" href="blog/page3">3</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page4">4</a>
>> +                <a class="text-primary" href="blog/page4">4</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page5">5</a>
>> +                <a class="text-primary" href="blog/page5">5</a>
>>
>>          </li>
>>
>>
>> Modified: jclouds/site-content/blog/page2/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page2/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/page2/index.html (original)
>> +++ jclouds/site-content/blog/page2/index.html Thu Sep  4 15:18:35 2014
>> @@ -150,6 +150,11 @@
>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>
>>
>> +<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
>> +<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
>> +<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
>> +</p>
>> +
>>  <h3><a class="text-primary" href="/blog/2014/03/03/joining-the-asf-new-site-and-jclouds-1-7">Joining the ASF, new site, and jclouds 1.7!</a></h3>
>>  <span class="text-muted">03 March 2014, by Ignasi Barrera</span>
>>  <p>It's been a while since our last blog post, and lots has happened since then. There have been many things that have kept us busy, and finally, all the hard work is starting to show up. During this time, we've:
>> @@ -170,11 +175,6 @@
>>  <p>jclouds community is an international group with over 100 contributors since we started in early 2009. The idea of holidays vary, but we decided Mistletoe as an appropriate codename for jclouds 1.5.4. Here's why.
>>  </p>
>>
>> -<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
>> -<span class="text-muted">17 November 2012, by Adrian Cole</span>
>> -<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
>> -</p>
>> -
>>
>>
>>  <ul class="pagination text-center">
>> @@ -191,25 +191,25 @@
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page2">2</a>
>> +                <a class="text-primary" href="blog/page2">2</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page3">3</a>
>> +                <a class="text-primary" href="blog/page3">3</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page4">4</a>
>> +                <a class="text-primary" href="blog/page4">4</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page5">5</a>
>> +                <a class="text-primary" href="blog/page5">5</a>
>>
>>          </li>
>>
>>
>> Modified: jclouds/site-content/blog/page3/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page3/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/page3/index.html (original)
>> +++ jclouds/site-content/blog/page3/index.html Thu Sep  4 15:18:35 2014
>> @@ -150,6 +150,11 @@
>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>
>>
>> +<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
>> +<span class="text-muted">17 November 2012, by Adrian Cole</span>
>> +<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
>> +</p>
>> +
>>  <h3><a class="text-primary" href="/blog/2012/11/09/500-jclouds-builds-on-buildhive-and-counting">500 jclouds builds on BuildHive and counting...</a></h3>
>>  <span class="text-muted">09 November 2012, by Adrian Cole</span>
>>  <p>At jclouds, we've been running our Jenkins continuous integration jobs in CloudBees' DEV@cloud for a while now (CloudBees has a FOSS programme). We also have an active and ever-increasing contributor community, which amongst others means... lots of pull requests.
>> @@ -170,11 +175,6 @@
>>  <p>We are very near beta, I promise! In the mean time, we just cut a new codebase with a bunch of cool new toys. Here's a few. Thanks to Adam Lowe, we are getting even deeper into OpenStack with more Keystone support than ever. Setup your code to pull org.jclouds.labs/openstack-keystone, and you can do stuff like this.
>>  </p>
>>
>> -<h3><a class="text-primary" href="/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and">Take a peek at vCloud Director 1.5, OpenStack, and VirtualBox</a></h3>
>> -<span class="text-muted">23 March 2012, by Adrian Cole</span>
>> -<p>The jclouds team have been working very hard lately, particularly on a few new apis. We've decided to cage them no longer and cut jclouds 1.5.0-alpha.1. Most notably, we've added the openstack-nova api, and three new providers, all of which discovered via OpenStack Keystone v2.0.
>> -</p>
>> -
>>
>>
>>  <ul class="pagination text-center">
>> @@ -191,25 +191,25 @@
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page2">2</a>
>> +                <a class="text-primary" href="blog/page2">2</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page3">3</a>
>> +                <a class="text-primary" href="blog/page3">3</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page4">4</a>
>> +                <a class="text-primary" href="blog/page4">4</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page5">5</a>
>> +                <a class="text-primary" href="blog/page5">5</a>
>>
>>          </li>
>>
>>
>>

Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...

Posted by Ignasi Barrera <ig...@gmail.com>.
I think it is due to the version of Jekyll. Our Jenkins uses Jekyll
1.5.1, and it renders a bit different than older versions (IIRC). We
should definitely better document that.
For the next time, there are two options:

* Install Jekyll 1.5.1 and force the version when generating the site
as explained here [1].
* Carefully read the script prompt with the changes that are going to
be committed and just commit the ones that are relevant and discard
the rest.


[1] https://github.com/jclouds/jclouds-site/blob/master/deploy-site.sh#L3-L9

On 4 September 2014 18:35, Zack Shoylev <za...@rackspace.com> wrote:
> AFAIK latest versions of both. Anything broken?
> ________________________________________
> From: Ignasi Barrera [ignasi.barrera@gmail.com]
> Sent: Thursday, September 04, 2014 11:29 AM
> To: dev@jclouds.apache.org
> Subject: Re: svn commit: r1622496 [1/4] - in /jclouds/site-content: ./ blog/ blog/2009/05/13/catching-exceptions-with-less-keystrokes/ blog/2011/10/18/jclouds-1-2-released/ blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/ blog/2012/05/02/new-to...
>
> Zach wichi version of Jekyll were you using? Did you use the latest
> version of the script to generate the site?
>
> I'm just wondering, why the commit for your blog post modified all those files.
>
> In any case, that can be prevented by taking a look at the script
> output (which should prompt you) and manually adding *only* the
> relevant files if needed, and discard the rest?
>
>
>
> On 4 September 2014 17:18,  <za...@apache.org> wrote:
>> Author: zachsh
>> Date: Thu Sep  4 15:18:35 2014
>> New Revision: 1622496
>>
>> URL: http://svn.apache.org/r1622496
>> Log:
>> deploy jclouds site content
>>
>> Added:
>>     jclouds/site-content/blog/2014/09/
>>     jclouds/site-content/blog/2014/09/03/
>>     jclouds/site-content/blog/2014/09/03/better-builders/
>>     jclouds/site-content/blog/2014/09/03/better-builders/index.html
>> Modified:
>>     jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>>     jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>>     jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>>     jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>>     jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>>     jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>>     jclouds/site-content/blog/atom.xml
>>     jclouds/site-content/blog/index.html
>>     jclouds/site-content/blog/page2/index.html
>>     jclouds/site-content/blog/page3/index.html
>>     jclouds/site-content/blog/page4/index.html
>>     jclouds/site-content/blog/page5/index.html
>>     jclouds/site-content/guides/abiquo-cloud/index.html
>>     jclouds/site-content/guides/abiquo/index.html
>>     jclouds/site-content/guides/aws-ebs/index.html
>>     jclouds/site-content/guides/aws-ec2/index.html
>>     jclouds/site-content/guides/aws-sqs/index.html
>>     jclouds/site-content/guides/aws/index.html
>>     jclouds/site-content/guides/azure-storage/index.html
>>     jclouds/site-content/guides/bluelock/index.html
>>     jclouds/site-content/guides/chef/index.html
>>     jclouds/site-content/guides/cloudsigma/index.html
>>     jclouds/site-content/guides/docker/index.html
>>     jclouds/site-content/guides/filesystem/index.html
>>     jclouds/site-content/guides/glacier/index.html
>>     jclouds/site-content/guides/go-grid/index.html
>>     jclouds/site-content/guides/hpcloud/index.html
>>     jclouds/site-content/guides/karaf/index.html
>>     jclouds/site-content/guides/openstack/index.html
>>     jclouds/site-content/guides/rackspace/index.html
>>     jclouds/site-content/guides/vcloud-director/index.html
>>     jclouds/site-content/guides/vcloud/index.html
>>     jclouds/site-content/index.html
>>     jclouds/site-content/reference/configuration/index.html
>>     jclouds/site-content/reference/logging/index.html
>>     jclouds/site-content/reference/troubleshooting/index.html
>>     jclouds/site-content/releasenotes/1.1.0/index.html
>>     jclouds/site-content/releasenotes/1.2/index.html
>>     jclouds/site-content/releasenotes/1.6.1/index.html
>>     jclouds/site-content/releasenotes/1.6.2/index.html
>>     jclouds/site-content/releasenotes/1.6.3/index.html
>>     jclouds/site-content/releasenotes/1.7.0/index.html
>>     jclouds/site-content/releasenotes/1.7.1/index.html
>>     jclouds/site-content/releasenotes/1.7.2/index.html
>>     jclouds/site-content/releasenotes/1.7.3/index.html
>>     jclouds/site-content/releasenotes/atom.xml
>>     jclouds/site-content/start/blobstore/index.html
>>     jclouds/site-content/start/compute/index.html
>>     jclouds/site-content/start/install/index.html
>>
>> Modified: jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html (original)
>> +++ jclouds/site-content/blog/2009/05/13/catching-exceptions-with-less-keystrokes/index.html Thu Sep  4 15:18:35 2014
>> @@ -154,8 +154,7 @@
>>  <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>>      <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>>      <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
>> @@ -170,8 +169,7 @@
>>      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>>          <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>>
>> Modified: jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html (original)
>> +++ jclouds/site-content/blog/2011/10/18/jclouds-1-2-released/index.html Thu Sep  4 15:18:35 2014
>> @@ -158,8 +158,7 @@
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
>> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
>> -</code></pre></div>
>> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>>
>>
>>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>>
>> Modified: jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html (original)
>> +++ jclouds/site-content/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and/index.html Thu Sep  4 15:18:35 2014
>> @@ -162,14 +162,12 @@
>>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
>> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
>> -</code></pre></div>
>> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>>
>>
>>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>>
>> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>>
>>
>>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
>> @@ -182,8 +180,7 @@
>>
>>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>>
>>
>>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
>> @@ -192,8 +189,7 @@
>>
>>  <p>Oh, and don't forget to clean up your nodes :)</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>>
>>
>>
>>
>> Modified: jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html (original)
>> +++ jclouds/site-content/blog/2012/05/02/new-toys-in-1-5-0-alpha-6/index.html Thu Sep  4 15:18:35 2014
>> @@ -161,8 +161,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
>> @@ -177,8 +176,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
>> @@ -187,8 +185,7 @@
>>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>
>>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
>> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
>> -</code></pre></div>
>> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>>
>> Modified: jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html (original)
>> +++ jclouds/site-content/blog/2012/07/16/fluency-for-paginated-api-lists/index.html Thu Sep  4 15:18:35 2014
>> @@ -168,8 +168,7 @@
>>
>>  <h3>Lazy advance through all your metrics:</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>>
>>
>>  <h3>Â Advance only until we find the load balancer we want:</h3>
>> @@ -177,14 +176,12 @@
>>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
>> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
>> -</code></pre></div>
>> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h3>Get only the first page of database instances</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>>
>> Modified: jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html (original)
>> +++ jclouds/site-content/blog/2012/12/12/jclouds-1-5-4-mistletoe-released/index.html Thu Sep  4 15:18:35 2014
>> @@ -156,8 +156,7 @@
>>
>>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>>
>> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>>
>>
>>  <h2>What else is in 1.5.4?</h2>
>> @@ -168,16 +167,14 @@
>>
>>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>Nova Server Diagnostics</h3>
>>
>>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>S3 Multi-Object delete</h3>
>> @@ -185,8 +182,7 @@
>>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
>> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
>> -</code></pre></div>
>> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h2>What's next</h2>
>>
>> Added: jclouds/site-content/blog/2014/09/03/better-builders/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/2014/09/03/better-builders/index.html?rev=1622496&view=auto
>> ==============================================================================
>> --- jclouds/site-content/blog/2014/09/03/better-builders/index.html (added)
>> +++ jclouds/site-content/blog/2014/09/03/better-builders/index.html Thu Sep  4 15:18:35 2014
>> @@ -0,0 +1,344 @@
>> +<!DOCTYPE html>
>> +<html lang="en">
>> +    <head>
>> +        <meta charset="utf-8">
>> +<title>Apache jclouds&reg; :: Better Builders with jclouds!</title>
>> +<meta name="viewport" content="width=device-width, initial-scale=1.0">
>> +<meta name="description" content="">
>> +<meta name="author" content="">
>> +
>> +<!--link rel="stylesheet/less" href="less/bootstrap.less" type="text/css" /-->
>> +<!--link rel="stylesheet/less" href="less/responsive.less" type="text/css" /-->
>> +<!--script src="js/less-1.3.3.min.js"></script-->
>> +<!--append â?~#!watchâ?T to the browser URL, then refresh the page. -->
>> +
>> +<link href="/css/bootstrap.min.css" rel="stylesheet">
>> +<link href="/css/style.css" rel="stylesheet">
>> +<link href="/css/syntax.css" rel="stylesheet">
>> +
>> +<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
>> +<!--[if lt IE 9]>
>> +<script src="js/html5shiv.js"></script>
>> +<![endif]-->
>> +
>> +<!-- Fav and touch icons -->
>> +<!--
>> +<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/img/apple-touch-icon-144-precomposed.png">
>> +<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/apple-touch-icon-114-precomposed.png">
>> +<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/apple-touch-icon-72-precomposed.png">
>> +<link rel="apple-touch-icon-precomposed" href="/img/apple-touch-icon-57-precomposed.png">
>> +-->
>> +<link rel="shortcut icon" href="/favicon.ico">
>> +
>> +<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Blog Posts Feed">
>> +<link rel="alternate" type="application/atom+xml" href="/releasenotes/atom.xml" title="Release Notes Feed">
>> +
>> +<script type="text/javascript" src="/js/jquery.min.js"></script>
>> +<script type="text/javascript" src="/js/bootstrap.min.js"></script>
>> +<script type="text/javascript" src="/js/toc.js"></script>
>> +
>> +<script type="text/javascript">
>> +    var _gaq = _gaq || [];
>> +    _gaq.push(['_setAccount', 'UA-8638379-1']);
>> +    _gaq.push(['_trackPageview']);
>> +
>> +    (function() {
>> +     var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
>> +     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
>> +     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
>> +     })();
>> +</script>
>> +<script type="text/javascript">
>> +    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
>> +     (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
>> +     m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
>> +     })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
>> +
>> +    ga('create', 'UA-47106724-1', 'jclouds.apache.org');
>> +    ga('send', 'pageview');
>> +</script>
>> +
>> +    </head>
>> +    <body>
>> +        <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
>> +    <div class="container">
>> +        <div class="navbar-header">
>> +            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
>> +                <span class="sr-only">Toggle navigation</span>
>> +                <span class="icon-bar"></span>
>> +                <span class="icon-bar"></span>
>> +                <span class="icon-bar"></span>
>> +            </button>
>> +            <a class="navbar-brand" href="/">Apache jclouds &reg;</a>
>> +        </div>
>> +
>> +        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
>> +            <ul class="nav navbar-nav">
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Getting Started<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <li><a href="/start/what-is-jclouds/">What Is Apache jclouds?</a></li>
>> +                        <li><a href="/start/install/">Installation Guide</a></li>
>> +                        <li class="divider"></li>
>> +                        <li><a href="/start/concepts/">Core Concepts</a></li>
>> +                        <li><a href="/start/compute/">ComputeService</a></li>
>> +                        <li><a href="/start/blobstore/">BlobStore</a></li>
>> +                        <li><a href="http://github.com/jclouds/jclouds-examples">Examples</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <li><a href="/reference/providers/">Cloud Providers</a></li>
>> +                        <li><a href="/guides">User Guides</a></li>
>> +                        <li><a href="/reference/troubleshooting/">Troubleshooting</a></li>
>> +                        <li><a href="/reference/configuration/">Configuration</a></li>
>> +                        <li><a href="/reference/logging/">Logging</a></li>
>> +                        <li><a href="/reference/javadoc/">Javadoc</a></li>
>> +                        <li class="divider"></li>
>> +                        <li class="dropdown-header">Developer Guides</li>
>> +                        <li><a href="http://wiki.apache.org/jclouds/">Wiki</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Community<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <li><a href="/community/">Get In Touch!</a></li>
>> +                        <li><a href="http://www.meetup.com/jclouds/">Attend An Event</a></li>
>> +                        <li><a href="/community/users/">Who Is Using jclouds?</a></li>
>> +                        <li class="divider"></li>
>> +                        <li class="dropdown-header">Contribute</li>
>> +                        <li><a href="/reference/report-a-bug/">Report a Bug</a></li>
>> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute">How To Contribute Code</a></li>
>> +                        <li><a href="http://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">How To Contribute Documentation</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li><a href="/blog">Blog</a></li>
>> +            </ul>
>> +            <ul class="nav navbar-nav navbar-right">
>> +                <li class="dropdown">
>> +                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Release Notes<strong class="caret"></strong></a>
>> +                    <ul class="dropdown-menu">
>> +                        <!-- only keep the release notes for supported versions in this list -->
>> +                        <li><a href="/releasenotes/1.8.0">1.8.0</a></li>
>> +                        <li><a href="/releasenotes/1.7.3">1.7.3</a></li>
>> +                        <li><a href="/releasenotes/1.7.2">1.7.2</a></li>
>> +                        <li><a href="/releasenotes/1.7.1">1.7.1</a></li>
>> +                        <li><a href="/releasenotes/1.7.0">1.7.0</a></li>
>> +                        <li class="divider"></li>
>> +                        <li class="dropdown-header">Previous releases</li>
>> +                        <li><a href="/releasenotes">Release archive</a></li>
>> +                    </ul>
>> +                </li>
>> +                <li>
>> +                    <div>
>> +                        <a class="btn btn-success navbar-btn" href="/start/install/">
>> +                            <span class="glyphicon glyphicon-download"></span>
>> +                            Install
>> +                        </a>
>> +                    </div>
>> +                </li>
>> +            </ul>
>> +        </div>
>> +    </div>
>> +</nav>
>> +
>> +        <div class="container">
>> +            <div class="page-header">
>> +                <h1>Better Builders with jclouds!</h1>
>> +                <span class="text-muted">03 September 2014, by Zack Shoylev</span>
>> +            </div>
>> +            <p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
>> +
>> +<!--more-->
>> +
>> +
>> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
>> +
>> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
>> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
>> +                <span class="p">},</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
>> +        <span class="p">}</span>
>> +    <span class="p">]</span>
>> +<span class="p">}</span></code></pre></div>
>> +
>> +
>> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
>> +
>> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
>> +
>> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
>> +
>> +<p>Current implementations have the following two issues :</p>
>> +
>> +<ol>
>> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
>> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
>> +</ol>
>> +
>> +
>> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
>> +
>> +<p>We want to</p>
>> +
>> +<ol>
>> +<li>Ensure object immutability.</li>
>> +<li>Utilize the fluent builder pattern.</li>
>> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
>> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
>> +<li>Allow using different validation strategies (for example, create vs update).</li>
>> +</ol>
>> +
>> +
>> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
>> +
>> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
>> +
>> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
>> +
>> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
>> +
>> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
>> +
>> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
>> +
>> +<ol>
>> +<li>Listing networks returns a Network or a list of Networks.</li>
>> +<li>Updating a network requires Network.UpdateOptions.</li>
>> +<li>Creating a network requires Network.CreateOptions.</li>
>> +</ol>
>> +
>> +
>> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
>> +
>> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
>> +
>> +<p>This is how it all works out from the developer's perspective:</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
>> +
>> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
>> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
>> +
>> +
>> +            <div id="comments">
>> +                <hr/>
>> +                <div id="disqus_thread"></div>
>> +<script type="text/javascript">
>> +var disqus_shortname = 'jclouds';
>> +/* * * DON'T EDIT BELOW THIS LINE * * */
>> +(function() {
>> +    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
>> +    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
>> +    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
>> +})();
>> +</script>
>> +<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">Comments powered by Disqus.</a></noscript>
>> +<a href="http://disqus.com" class="dsq-brlink">Comments powered by <span class="logo-disqus">Disqus</span></a>
>> +
>> +            </div>
>> +
>> +            <div class="row clearfix">
>> +                <div id="footer" class="col-md-12 column">
>> +                    <div id="footer">
>> +    <hr/>
>> +    <div class="row clearfix">
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="/start/">Getting Started</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="/reference/report-a-bug/">Report a Bug</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a href="https://github.com/jclouds/jclouds-site/edit/master/_posts/2014-09-03-better-builders.md">Fix This Page</a><a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation"><sup>*</sup></a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="https://wiki.apache.org/jclouds/How%20to%20Contribute">Contribute Code</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="/community/">Contact Us</a>
>> +            </p>
>> +        </div>
>> +        <div class="col-md-2 column">
>> +            <p class="text-center">
>> +                <a class="text-primary" href="https://twitter.com/jclouds">Follow Us</a>
>> +            </p>
>> +        </div>
>> +    </div>
>> +    <hr style="margin-top: 10px"/>
>> +    <div class="row clearfix">
>> +        <div class="col-md-12 column">
>> +            <p class="text-center">
>> +              Copyright &copy; 2011-2014 <a href="http://www.apache.org">The Apache Software Foundation</a>. All Rights Reserved.
>> +            </p>
>> +            <p class="text-center">
>> +              Apache, jclouds, Apache jclouds, the jclouds logo, and the Apache feather logos are registered trademarks or trademarks of the Apache Software Foundation.
>> +            </p>
>> +            <p class="text-center">
>> +              <img src="/img/feather-small.gif" width="80", height="24"/>
>> +            </p>
>> +            <br/>
>> +        </div>
>> +    </div>
>> +</div>
>> +
>> +                </div>
>> +            </div>
>> +        </div>
>> +    </body>
>> +</html>
>>
>> Modified: jclouds/site-content/blog/atom.xml
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/atom.xml?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/atom.xml (original)
>> +++ jclouds/site-content/blog/atom.xml Thu Sep  4 15:18:35 2014
>> @@ -8,6 +8,131 @@
>>
>>
>>    <entry>
>> +    <id>http://jclouds.apache.org/blog/2014/09/03/better-builders</id>
>> +    <title type="html"><![CDATA[Better Builders with jclouds!]]></title>
>> +    <link href="http://jclouds.apache.org/blog/2014/09/03/better-builders"/>
>> +    <updated>2014-09-03T00:00:00Z</updated>
>> +    <content type="html"><![CDATA[<p>If you are a new <a href="jclouds.apache.org">jclouds</a> developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.</p>
>> +
>> +<!--more-->
>> +
>> +
>> +<p>For example, when listing database users in openstack-trove (the OpenStack database API), the service returns a JSON response body describing the existing users. This JSON might look something like this:</p>
>> +
>> +<div class="highlight"><pre><code class="json"><span class="p">{</span>
>> +    <span class="nt">&quot;users&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser1&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseB&quot;</span>
>> +                <span class="p">},</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;databaseC&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser2&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[],</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;dbuser3&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span>
>> +        <span class="p">},</span>
>> +        <span class="p">{</span>
>> +            <span class="nt">&quot;databases&quot;</span><span class="p">:</span> <span class="p">[</span>
>> +                <span class="p">{</span>
>> +                    <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;sampledb&quot;</span>
>> +                <span class="p">}</span>
>> +            <span class="p">],</span>
>> +            <span class="nt">&quot;host&quot;</span><span class="p">:</span> <span class="s2">&quot;%&quot;</span><span class="p">,</span>
>> +            <span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;demouser&quot;</span>
>> +        <span class="p">}</span>
>> +    <span class="p">]</span>
>> +<span class="p">}</span></code></pre></div>
>> +
>> +
>> +<p>To parse the response, jclouds uses <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/domain/User.java">domain classes</a> to represent the JSON data returned by the service. The array of "users" is unwrapped into individual User domain objects. Conversely, when creating users, domain objects are transformed into a JSON request body.</p>
>> +
>> +<p>Because of the relative simplicity of user creation in trove, jclouds developers can use a create method in the features package without having to build an instance of the User class. For example, the developer might use a method such as</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="kt">boolean</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">userName</span><span class="o">,</span> <span class="n">String</span> <span class="n">password</span><span class="o">,</span> <span class="n">String</span> <span class="n">databaseName</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>In this case, it was easy to add support for this call by using a <a href="https://github.com/jclouds/jclouds/blob/master/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/binders/BindCreateUserToJson.java">map binder</a>.</p>
>> +
>> +<p>However, some APIs send or receive significantly more complex JSON structures. Recent work on Neutron has shown that there are benefits to increased consistency among the domain classes and the OpenStack API calls that use them.</p>
>> +
>> +<p>Current implementations have the following two issues :</p>
>> +
>> +<ol>
>> +<li>Heavy use of map-binders and parsers to transform JSON. Map-binders use  annotation-selected classes to map method data (such as the data in the create-user call above) to the JSON required by the service. The <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/functions/ParseNetworkDetails.java">parsers</a> apply the reverse transformation: from JSON to domain objects.</li>
>> +<li>Lack of consistent, concise, and user-friendly way to use domain objects in create/update/list methods.</li>
>> +</ol>
>> +
>> +
>> +<p>In addition to fixing these issues, jclouds wants to provide developers with some compiler checks and other syntactic sugar (fluent builders), while also supporting different updating, creating, or listing validation strategies.</p>
>> +
>> +<p>We want to</p>
>> +
>> +<ol>
>> +<li>Ensure object immutability.</li>
>> +<li>Utilize the fluent builder pattern.</li>
>> +<li>Ensure that "create" objects can only be used for create; update for update; and listed resources cannot be directly sent back to the service.</li>
>> +<li>Reuse code and keep domain classes <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li>
>> +<li>Allow using different validation strategies (for example, create vs update).</li>
>> +</ol>
>> +
>> +
>> +<p>We have been able to identify a pattern that addresses these issues. Here is some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/Router.java">sample code</a>.</p>
>> +
>> +<p>This approach reuses code by having <a href="https://code.google.com/p/google-gson/">GSON</a> handle the domain objects directly, as much as possible, both for serialization and deserialization, thus eliminating map-binders and parsers in most cases. The domain classes annotate their member variables using the @Named (for serialization) and @ConstructorProperties (for deserialization) annotations.</p>
>> +
>> +<p>Many of the JSON attributes in Neutron are optional. GSON's jclouds configuration supports such optional values by using @Nullable and boxed types. An alternate supported method, more convoluted, implements Optional<T> private member variables and getter return types.</p>
>> +
>> +<p>To ensure immutability, users have no access to a constructor or setters, and instead they must instantiate domain objects by using a slightly modified Builder pattern. The builder pattern also provides proper validation and user-friendliness.</p>
>> +
>> +<p>Some <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/domain/AddressPair.java">simpler classes</a> implement the regular fluent builder pattern.</p>
>> +
>> +<p>In <a href="https://github.com/jclouds/jclouds-labs-openstack/blob/master/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2/features/NetworkApi.java">other cases</a>, the same domain class has several different purposes, such as making sure users have different Network-subtype object instances for updating, creating, and listing networks:</p>
>> +
>> +<ol>
>> +<li>Listing networks returns a Network or a list of Networks.</li>
>> +<li>Updating a network requires Network.UpdateOptions.</li>
>> +<li>Creating a network requires Network.CreateOptions.</li>
>> +</ol>
>> +
>> +
>> +<p>CreateOptions and UpdateOptions extend Network and implement their own copy constructors, with custom validation, if needed.</p>
>> +
>> +<p>To instantiate these create or update-specific objects, developers have access to CreateBuilder and UpdateBuilder, which both extend the regular Network builder abstract class. The only code these special builders implement: the constructor (taking as parameters any required properties), a build() method returning the create or update object, and also self(). The self method is needed to make sure we can reuse most of the Builder code, but still be able to chain the fluent builder methods.</p>
>> +
>> +<p>This is how it all works out from the developer's perspective:</p>
>> +
>> +<div class="highlight"><pre><code class="java"><span class="n">Network</span><span class="o">.</span><span class="na">CreateOptions</span> <span class="n">createNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">createOptions</span><span class="o">(</span><span class="s">&quot;jclouds-wibble&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">Network</span> <span class="n">network</span> <span class="o">=</span> <span class="n">networkApi</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">createNetwork</span><span class="o">);</span>
>> +
>> +<span class="n">Network</span><span class="o">.</span><span class="na">UpdateOptions</span> <span class="n">updateNetwork</span> <span class="o">=</span> <span class="n">Network</span><span class="o">.</span><span class="na">updateOptions</span><span class="o">()</span>
>> +           <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">&quot;jclouds-wibble-updated&quot;</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">networkType</span><span class="o">(</span><span class="n">NetworkType</span><span class="o">.</span><span class="na">LOCAL</span><span class="o">)</span>
>> +           <span class="o">.</span><span class="na">build</span><span class="o">();</span>
>> +
>> +<span class="n">networkApi</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="s">&quot;some id&quot;</span><span class="o">,</span> <span class="n">updateNetwork</span><span class="o">);</span></code></pre></div>
>> +
>> +
>> +<p>This ensures developers get an easy to understand interface, with validation and compiler checks. It also allows jclouds developers to use significantly less code when developing complex domain classes that need to be reused in list/create/update API calls.</p>
>> +]]></content>
>> +  </entry>
>> +
>> +  <entry>
>>      <id>http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers</id>
>>      <title type="html"><![CDATA[1 release, 2 committers...a busy week for jclouds!]]></title>
>>      <link href="http://jclouds.apache.org/blog/2014/08/04/1-release-2-committers"/>
>> @@ -480,8 +605,7 @@
>>
>>  <p>For example, the following syntax can be used in karaf directly, or via the <a href="https://github.com/jclouds/jclouds-cli">jclouds cli</a> to start a node in any supported cloud and bootstrap chef recipes.</p>
>>
>> -<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">karaf@root&gt;node-create --adminAccess --recipe chef/java::openjdk karaf</code></pre></div>
>>
>>
>>  <h2>What else is in 1.5.4?</h2>
>> @@ -492,16 +616,14 @@
>>
>>  <p><a href="https://github.com/everett-toews">Everett</a> modernized support for <strong>rackspace-cloudloadbalancers-us</strong> and <strong>uk</strong> is now available. This includes syntactic sugar such as auto-pagination and easy transforms.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">HostAndPort</span><span class="o">&gt;</span> <span class="n">sockets</span> <span class="o">=</span> <span class="n">clb</span><span class="o">.</span><span class="na">getLoadBalancerApiForZone</span><span class="o">(</span><span class="n">zone</span><span class="o">).</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">().</span><span class="na">transform</span><span class="o">(</span><span class="n">converter</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>Nova Server Diagnostics</h3>
>>
>>  <p>Some implementations of Nova have diagnostic information available. Thanks to <a href="https://github.com/LeanderBB">Leander</a>, you can now discover this capability at runtime.</p>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">Map</span><span class="o">&gt;</span> <span class="n">diagnosticInfo</span> <span class="o">=</span> <span class="n">novaApi</span><span class="o">.</span><span class="na">getServerApiForZone</span><span class="o">(</span><span class="s">&quot;az-1.region-a.geo-1&quot;</span><span class="o">).</span><span class="na">getDiagnostics</span><span class="o">(</span><span class="n">serverId</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <h3>S3 Multi-Object delete</h3>
>> @@ -509,8 +631,7 @@
>>  <p><a href="http://maginatics.com/">Maginatics</a> have BlobStore containers with over a billion objects in them. S3 containers (buckets) can now be cleared with 1/1000 the requests, thanks to <a href="https://twitter.com/andreisavu">Andrei</a>'s additional support of S3 multi-delete.</p>
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">DeleteResult</span> <span class="n">result</span> <span class="o">=</span> <span class="n">s3Api</span><span class="o">.</span><span class="na">deleteObjects</span><span class="o">(</span><span class="n">container</span><span class="o">,</span> <span class="n">keys</span><span class="o">);</span>
>> -<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
>> -</code></pre></div>
>> +<span class="n">assertEquals</span><span class="o">(</span><span class="n">result</span><span class="o">.</span><span class="na">size</span><span class="o">(),</span> <span class="n">keys</span><span class="o">.</span><span class="na">size</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h2>What's next</h2>
>> @@ -602,8 +723,7 @@
>>
>>  <h3>Lazy advance through all your metrics:</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">FluentIterable</span><span class="o">&lt;</span><span class="n">Metric</span><span class="o">&gt;</span> <span class="n">allMetrics</span> <span class="o">=</span> <span class="n">cloudwatch</span><span class="o">.</span><span class="na">getMetricApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">concat</span><span class="o">();</span></code></pre></div>
>>
>>
>>  <h3>Â Advance only until we find the load balancer we want:</h3>
>> @@ -611,14 +731,12 @@
>>  <div class="highlight"><pre><code class="java"><span class="n">Optional</span><span class="o">&lt;</span><span class="n">LoadBalancer</span><span class="o">&gt;</span> <span class="n">firstInterestingLoadBalancer</span> <span class="o">=</span> <span class="n">elb</span>
>>     <span class="o">.</span><span class="na">getLoadBalancerApi</span><span class="o">().</span><span class="na">list</span><span class="o">()</span>
>>     <span class="o">.</span><span class="na">concat</span><span class="o">()</span>
>> -   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span>
>> -</code></pre></div>
>> +   <span class="o">.</span><span class="na">firstMatch</span><span class="o">(</span><span class="n">isInterestingLB</span><span class="o">());</span></code></pre></div>
>>
>>
>>  <h3>Get only the first page of database instances</h3>
>>
>> -<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="java"><span class="n">IterableWithMarker</span><span class="o">&lt;</span><span class="n">Instance</span><span class="o">&gt;</span> <span class="n">firstPage</span> <span class="o">=</span> <span class="n">rds</span><span class="o">.</span><span class="na">getInstanceApi</span><span class="o">().</span><span class="na">list</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>The above syntax is being worked through relevant apis. In order to try it out, grab jclouds 1.5.0-beta.7 (releasing today), and use any of the following methods:</p>
>> @@ -655,8 +773,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Tenant</span> <span class="n">tenant</span> <span class="o">:</span> <span class="n">adminClient</span><span class="o">.</span><span class="na">listTenants</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>Also pro, is our new Amazon CloudWatch support from Jeremy Whitlock. This is our first complete renovation of an AWS api to have the same look/feel as our new OpenStack stuff. Just add a dependency on <em>org.jclouds.providers/aws-cloudwatch</em> and you can do this!</p>
>> @@ -671,8 +788,7 @@
>>      <span class="k">for</span> <span class="o">(</span><span class="n">Metric</span> <span class="n">metric</span> <span class="o">:</span> <span class="n">metricClient</span><span class="o">.</span><span class="na">listMetrics</span><span class="o">())</span> <span class="o">{</span>
>>          <span class="c1">// ...</span>
>>      <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> +<span class="o">}</span></code></pre></div>
>>
>>
>>  <p>And for the jenkins users, we also have an api for remote job and computer control, at <em>org.jclouds.labs/jenkins</em>!</p>
>> @@ -681,8 +797,7 @@
>>  <span class="n">RestContext</span> <span class="n">localhost</span> <span class="o">=</span> <span class="n">contextBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">();</span>
>>
>>  <span class="n">Node</span> <span class="n">master</span> <span class="o">=</span> <span class="n">localhost</span><span class="o">.</span><span class="na">getApi</span><span class="o">().</span><span class="na">getMaster</span><span class="o">();</span>
>> -<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span>
>> -</code></pre></div>
>> +<span class="n">localhost</span><span class="o">.</span><span class="na">getJobClient</span><span class="o">().</span><span class="na">createFromXML</span><span class="o">(</span><span class="s">&quot;newJob&quot;</span><span class="o">,</span> <span class="n">xmlAsString</span><span class="o">);</span></code></pre></div>
>>
>>
>>  <p>This is especially helpful with the new <a href="https://github.com/jenkinsci/jclouds-plugin">jclouds-plugin</a>, which uses jclouds to spin up new slaves and publish artifacts to BlobStore. Tons more in there, too.</p>
>> @@ -710,14 +825,12 @@
>>  <div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">use</span> <span class="o">&#39;</span><span class="ss">&#39;org.jclouds.compute2</span><span class="p">)</span>
>>  <span class="p">(</span><span class="nb">import </span><span class="o">&#39;</span><span class="ss">&#39;org.jclouds.scriptbuilder.statements.login.AdminAccess</span><span class="p">)</span>
>>  <span class="p">(</span><span class="k">def </span><span class="nv">compute</span>  <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;hpcloud-compute&quot;</span> <span class="s">&quot;tenantId:ACCESSKEY&quot;</span> <span class="s">&quot;SECRETKEY&quot;</span>    <span class="ss">:slf4j</span> <span class="ss">:sshj</span><span class="p">))</span>
>> -<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span>
>> -</code></pre></div>
>> +<span class="p">(</span><span class="nf">create-node</span> <span class="nv">compute</span> <span class="s">&quot;test&quot;</span>   <span class="p">(</span><span class="nf">build-template</span> <span class="nv">compute</span> <span class="p">{</span> <span class="ss">:run-script</span> <span class="p">(</span><span class="nf">AdminAccess/standard</span><span class="p">)</span> <span class="p">}</span> <span class="p">))</span></code></pre></div>
>>
>>
>>  <p>Here's an example of how to do the same on <a href="https://trystack.org/">TryStack</a>, authenticating w/ user &amp; pass as opposed to key, via our <a href="https://github.com/jclouds/jclouds-examples/tree/master/compute-basics">java example</a>:</p>
>>
>> -<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="bash">java -jar target/compute-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add</code></pre></div>
>>
>>
>>  <p>In the group org.jclouds.labs, you'll find two more new and notable members of the jclouds family:</p>
>> @@ -730,8 +843,7 @@
>>
>>  <p>You can try out virtualbox like any other api. For example, you can use the clojure above, only changing how you create the connection slightly:</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="k">def </span><span class="nv">compute</span> <span class="p">(</span><span class="nf">compute-service</span> <span class="s">&quot;virtualbox&quot;</span> <span class="s">&quot;administrator&quot;</span> <span class="s">&quot;12345&quot;</span> <span class="ss">:sshj</span> <span class="ss">:slf4j</span><span class="p">))</span></code></pre></div>
>>
>>
>>  <p>The code in labs will certainly change before we release a beta, but feel free to check them out. Meanwhile, you can try them out and give us feedback on #jclouds irc freenode or jclouds-dev google group!</p>
>> @@ -740,8 +852,7 @@
>>
>>  <p>Oh, and don't forget to clean up your nodes :)</p>
>>
>> -<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span>
>> -</code></pre></div>
>> +<div class="highlight"><pre><code class="clojure"><span class="p">(</span><span class="nf">destroy-nodes-matching</span> <span class="nv">compute</span> <span class="p">(</span><span class="nb">constantly </span><span class="nv">true</span><span class="p">))</span></code></pre></div>
>>
>>
>>
>> @@ -862,8 +973,7 @@
>>
>>  <div class="highlight"><pre><code class="java"><span class="n">future</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">submitScriptOnNode</span><span class="o">(</span><span class="n">node</span><span class="o">.</span><span class="na">getId</span><span class="o">(),</span>
>>                  <span class="n">AdminAccess</span><span class="o">.</span><span class="na">builder</span><span class="o">().</span><span class="na">adminUsername</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
>> -                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span>
>> -</code></pre></div>
>> +                <span class="n">nameTask</span><span class="o">(</span><span class="s">&quot;adminUpdate&quot;</span><span class="o">));</span></code></pre></div>
>>
>>
>>  <p>As always, we keep our <a href="https://github.com/jclouds/jclouds-examples">examples site</a> up to date so you can see how to work this stuff. Next release will be in approximately 1-months time. Look out for progress including <a href="http://www.vmware.com/products/vcloud-director/overview.html">vCloud 1.5</a>, <a href="http://voxel.net/voxcloud">Voxel</a>, and <a href="https://www.virtualbox.org/">VirtualBox</a>.</p>
>> @@ -876,41 +986,4 @@
>>  ]]></content>
>>    </entry>
>>
>> -  <entry>
>> -    <id>http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes</id>
>> -    <title type="html"><![CDATA[Catching exceptions with fewer keystrokes]]></title>
>> -    <link href="http://jclouds.apache.org/blog/2009/05/13/catching-exceptions-with-less-keystrokes"/>
>> -    <updated>2009-05-13T00:00:00Z</updated>
>> -    <content type="html"><![CDATA[<p>Some of us hate checked exceptions, but still use them for one reason or another. A common problem we have is unnecessary exception nesting, or runtime swallowing. This often leads to the all to familiar and crufty code with a million catch blocks. jclouds has a slightly different approach that strikes a balance, allowing checked exceptions to be dealt with, but without the pain of so many lines of repetitious code.</p>
>> -
>> -<div class="highlight"><pre><code class="java"><span class="k">try</span> <span class="o">{</span>
>> -<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
>> -    <span class="n">Utils</span><span class="o">.&lt;</span><span class="n">ApplicationException</span><span class="o">&gt;</span><span class="n">rethrowIfRuntimeOrSameType</span><span class="o">(</span><span class="n">e</span><span class="o">);</span>
>> -    <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="o">(</span><span class="s">&quot;Error applying stuff&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> -
>> -
>> -<p>This code does what it says, preventing us from unnecessarily nesting application exceptions or swallowing runtimes.</p>
>> -
>> -<p>Now, this code shouldn't work, as current versions of java hava a generic type erasure problem. The reason it does work is a somewhat hackish line in the rethrowIfRuntimeOrSameType method:</p>
>> -
>> -<div class="highlight"><pre><code class="java"><span class="k">if</span> <span class="o">(</span><span class="n">e</span> <span class="k">instanceof</span> <span class="n">RuntimeException</span><span class="o">)</span> <span class="o">{</span>
>> -    <span class="k">throw</span> <span class="o">(</span><span class="n">RuntimeException</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
>> -<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
>> -    <span class="k">try</span> <span class="o">{</span>
>> -        <span class="k">throw</span> <span class="o">(</span><span class="n">E</span><span class="o">)</span> <span class="n">e</span><span class="o">;</span>
>> -    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ClassCastException</span> <span class="n">throwAway</span><span class="o">)</span> <span class="o">{</span>
>> -        <span class="c1">// using cce as there&#39;s no way to do instanceof E in current java</span>
>> -    <span class="o">}</span>
>> -<span class="o">}</span>
>> -</code></pre></div>
>> -
>> -
>> -<p>The trick is that we try to force the exception we caught into the generic type. If that fails, we know it wasn't that type and that we should wrap, log, etc.</p>
>> -
>> -<p>If nothing else, I hope you enjoy the perspective!</p>
>> -]]></content>
>> -  </entry>
>> -
>>  </feed>
>>
>> Modified: jclouds/site-content/blog/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/index.html (original)
>> +++ jclouds/site-content/blog/index.html Thu Sep  4 15:18:35 2014
>> @@ -150,6 +150,12 @@
>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>
>>
>> +<h3><a class="text-primary" href="/blog/2014/09/03/better-builders">Better Builders with jclouds!</a></h3>
>> +<span class="text-muted">03 September 2014, by Zack Shoylev</span>
>> +<p>If you are a new jclouds developer, or even if you are already developing jclouds support for any of the OpenStack or Rackspace APIs, you have likely seen the domain classes that are used throughout the the jclouds codebase.
>> +These classes are used to represent OpenStack resources, particularly the JSON structures supported by OpenStack APIs.
>> +</p>
>> +
>>  <h3><a class="text-primary" href="/blog/2014/08/04/1-release-2-committers">1 release, 2 committers...a busy week for jclouds!</a></h3>
>>  <span class="text-muted">04 August 2014, by <a href="http://blog.xebialabs.com/author/aphillips/">Andrew Phillips</a></span>
>>  <p>There's a lot going on this week for the jclouds community. Most importantly, we're really pleased to introduce two new committers: Andrea Turli and Chris Custine.
>> @@ -170,11 +176,6 @@
>>  <p>The Google Summer of Code (GSoC) accepted projects have been announced and we will have 3 students working on jclouds related projects!
>>  </p>
>>
>> -<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
>> -<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
>> -<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
>> -</p>
>> -
>>
>>
>>  <ul class="pagination text-center">
>> @@ -189,25 +190,25 @@
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page2">2</a>
>> +                <a class="text-primary" href="blog/page2">2</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page3">3</a>
>> +                <a class="text-primary" href="blog/page3">3</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page4">4</a>
>> +                <a class="text-primary" href="blog/page4">4</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page5">5</a>
>> +                <a class="text-primary" href="blog/page5">5</a>
>>
>>          </li>
>>
>>
>> Modified: jclouds/site-content/blog/page2/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page2/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/page2/index.html (original)
>> +++ jclouds/site-content/blog/page2/index.html Thu Sep  4 15:18:35 2014
>> @@ -150,6 +150,11 @@
>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>
>>
>> +<h3><a class="text-primary" href="/blog/2014/03/04/jclouds-meetup">jclouds Meetup</a></h3>
>> +<span class="text-muted">04 March 2014, by <a href="https://twitter.com/everett_toews">Everett Toews</a></span>
>> +<p>Last night we held a jclouds meetup at Cloudera offices in San Francisco. It was a well attended meetup and there were a number of new faces along with our more regular group of attendees. We recorded the whole thing with Google Hangouts on Air and you can get to know everyone in the first 5 minutes!
>> +</p>
>> +
>>  <h3><a class="text-primary" href="/blog/2014/03/03/joining-the-asf-new-site-and-jclouds-1-7">Joining the ASF, new site, and jclouds 1.7!</a></h3>
>>  <span class="text-muted">03 March 2014, by Ignasi Barrera</span>
>>  <p>It's been a while since our last blog post, and lots has happened since then. There have been many things that have kept us busy, and finally, all the hard work is starting to show up. During this time, we've:
>> @@ -170,11 +175,6 @@
>>  <p>jclouds community is an international group with over 100 contributors since we started in early 2009. The idea of holidays vary, but we decided Mistletoe as an appropriate codename for jclouds 1.5.4. Here's why.
>>  </p>
>>
>> -<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
>> -<span class="text-muted">17 November 2012, by Adrian Cole</span>
>> -<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
>> -</p>
>> -
>>
>>
>>  <ul class="pagination text-center">
>> @@ -191,25 +191,25 @@
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page2">2</a>
>> +                <a class="text-primary" href="blog/page2">2</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page3">3</a>
>> +                <a class="text-primary" href="blog/page3">3</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page4">4</a>
>> +                <a class="text-primary" href="blog/page4">4</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page5">5</a>
>> +                <a class="text-primary" href="blog/page5">5</a>
>>
>>          </li>
>>
>>
>> Modified: jclouds/site-content/blog/page3/index.html
>> URL: http://svn.apache.org/viewvc/jclouds/site-content/blog/page3/index.html?rev=1622496&r1=1622495&r2=1622496&view=diff
>> ==============================================================================
>> --- jclouds/site-content/blog/page3/index.html (original)
>> +++ jclouds/site-content/blog/page3/index.html Thu Sep  4 15:18:35 2014
>> @@ -150,6 +150,11 @@
>>              <p><a href="https://wiki.apache.org/jclouds/How%20to%20Contribute%20Documentation">Write a guest post!</a></p>
>>
>>
>> +<h3><a class="text-primary" href="/blog/2012/11/17/jclouds-1-5-3-out-the-door">jclouds 1.5.3 out the door</a></h3>
>> +<span class="text-muted">17 November 2012, by Adrian Cole</span>
>> +<p>Released on 2012-11-14, jclouds 1.5.3 includes minor fixes, and a few important updates.
>> +</p>
>> +
>>  <h3><a class="text-primary" href="/blog/2012/11/09/500-jclouds-builds-on-buildhive-and-counting">500 jclouds builds on BuildHive and counting...</a></h3>
>>  <span class="text-muted">09 November 2012, by Adrian Cole</span>
>>  <p>At jclouds, we've been running our Jenkins continuous integration jobs in CloudBees' DEV@cloud for a while now (CloudBees has a FOSS programme). We also have an active and ever-increasing contributor community, which amongst others means... lots of pull requests.
>> @@ -170,11 +175,6 @@
>>  <p>We are very near beta, I promise! In the mean time, we just cut a new codebase with a bunch of cool new toys. Here's a few. Thanks to Adam Lowe, we are getting even deeper into OpenStack with more Keystone support than ever. Setup your code to pull org.jclouds.labs/openstack-keystone, and you can do stuff like this.
>>  </p>
>>
>> -<h3><a class="text-primary" href="/blog/2012/03/23/take-a-peek-at-vcloud-director-1-5-openstack-and">Take a peek at vCloud Director 1.5, OpenStack, and VirtualBox</a></h3>
>> -<span class="text-muted">23 March 2012, by Adrian Cole</span>
>> -<p>The jclouds team have been working very hard lately, particularly on a few new apis. We've decided to cage them no longer and cut jclouds 1.5.0-alpha.1. Most notably, we've added the openstack-nova api, and three new providers, all of which discovered via OpenStack Keystone v2.0.
>> -</p>
>> -
>>
>>
>>  <ul class="pagination text-center">
>> @@ -191,25 +191,25 @@
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page2">2</a>
>> +                <a class="text-primary" href="blog/page2">2</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page3">3</a>
>> +                <a class="text-primary" href="blog/page3">3</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page4">4</a>
>> +                <a class="text-primary" href="blog/page4">4</a>
>>
>>          </li>
>>
>>          <li>
>>
>> -                <a class="text-primary" href="/blog/page5">5</a>
>> +                <a class="text-primary" href="blog/page5">5</a>
>>
>>          </li>
>>
>>
>>