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

<channel>
	<title>The Kaptain on ... stuff &#187; REST</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/rest/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kellyrob99.com/blog</link>
	<description>Tales of development, life and the folly that goes along with both</description>
	<lastBuildDate>Sun, 04 Dec 2011 21:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Five Cool Things You Can Do With Groovy Scripts</title>
		<link>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=five-cool-things-you-can-do-with-groovy-scripts</link>
		<comments>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 21:51:34 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Gradle]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[JsonSlurper]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1761</guid>
		<description><![CDATA[1. Ensure all of your Jenkins builds are building the correct branch from source control I manage a large number of builds at work, spread across several build servers. When we release a new version all of the builds need to be updated to point to new working branches. This script takes advantage of the [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<h2>1. Ensure all of your Jenkins builds are building the correct branch from source control</h2>
<p>I manage a large number of builds at work, spread across several build servers. When we release a new version all of the builds need to be updated to point to new working branches. This script takes advantage of the fact that our branches all end in the version number to quickly check that all of the last builds were on the expected version.<br />
Using the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API">Jenkins API</a> is very easy and the new capabilities of Groovy introduced by <a href="http://groovy.codehaus.org/gapi/groovy/json/JsonSlurper.html">JSONSlurper</a> make it easier than ever to consume.<br />
<script src="http://gist.github.com/1430845.js?file=jenkinsSVNVersionChecker.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1430845" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">import</span> <span class="nn">groovy.json.JsonSlurper</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="k">assert</span> <span class="n">args</span> <span class="o">&amp;&amp;</span> <span class="n">args</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">==</span> <span class="mi">2</span></div><div class='line' id='LC4'><span class="n">def</span> <span class="n">urls</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">split</span><span class="o">(</span><span class="sc">&#39;,&#39;</span><span class="o">)</span></div><div class='line' id='LC5'><span class="n">def</span> <span class="n">expectedVersion</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span></div><div class='line' id='LC6'><span class="n">urls</span><span class="o">.</span><span class="na">each</span> <span class="o">{</span> <span class="n">url</span> <span class="o">-&gt;</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;examining url $url&quot;</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">def</span> <span class="n">json</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonSlurper</span><span class="o">().</span><span class="na">parseText</span><span class="o">(</span><span class="n">url</span><span class="o">.</span><span class="na">toURL</span><span class="o">().</span><span class="na">text</span><span class="o">)</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">json</span><span class="o">.</span><span class="na">jobs</span><span class="o">.</span><span class="na">each</span> <span class="o">{</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">def</span> <span class="n">job</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonSlurper</span><span class="o">().</span><span class="na">parseText</span><span class="o">(</span><span class="s">&quot;${it.url}/api/json?depth=1&quot;</span><span class="o">.</span><span class="na">toURL</span><span class="o">().</span><span class="na">text</span><span class="o">)</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="o">(!</span><span class="n">job</span><span class="o">.</span><span class="na">builds</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">changeSet</span><span class="o">.</span><span class="na">revisions</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="na">module</span><span class="o">.</span><span class="na">endsWith</span><span class="o">(</span><span class="n">expectedVersion</span><span class="o">))</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;$it.url fails!&quot;</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">else</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;$it.url passes!&quot;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">catch</span> <span class="o">(</span><span class="n">e</span><span class="o">)</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">{</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="s">&quot;Exception thrown processing $it.url : $e&quot;</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC28'><span class="o">}</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1430845/bbc1beba1dfd59a6fe9925af14d301460202f0d3/jenkinsSVNVersionChecker.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1430845#file_jenkins_svn_version_checker.groovy" style="float:right;margin-right:10px;color:#666">jenkinsSVNVersionChecker.groovy</a>
            <a href="https://gist.github.com/1430845">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript></p>
<h2>2. Look up the artifacts from the last successful Jenkins build</h2>
<p>This is very handy if you want to automate deployment of software from your build system and can replace a lot of error prone manual updating of scripts. In this particular example you can link up quickly with the latest, greatest build of JRuby from <a href="http://ci.jruby.org/">their public CI server</a>.<br />
<script src="http://gist.github.com/1430856.js?file=jenkinsBuildArtifacts.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1430856" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">import</span> <span class="nn">groovy.json.*</span></div><div class='line' id='LC2'><span class="n">def</span> <span class="n">HOSTNAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="nl">http:</span><span class="c1">//ci.jruby.org&#39;</span></div><div class='line' id='LC3'><span class="n">def</span> <span class="n">JOBNAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">jruby</span><span class="o">-</span><span class="n">dist</span><span class="err">&#39;</span></div><div class='line' id='LC4'><span class="n">def</span> <span class="n">JOB_URL</span> <span class="o">=</span> <span class="s">&quot;$HOSTNAME/job/$JOBNAME/lastSuccessfulBuild&quot;</span></div><div class='line' id='LC5'><span class="n">def</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;$JOB_URL/api/json&quot;</span><span class="o">.</span><span class="na">toURL</span><span class="o">().</span><span class="na">text</span></div><div class='line' id='LC6'><span class="n">println</span> <span class="n">JsonOutput</span><span class="o">.</span><span class="na">prettyPrint</span><span class="o">(</span><span class="n">text</span><span class="o">)</span></div><div class='line' id='LC7'><span class="n">def</span> <span class="n">json</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonSlurper</span><span class="o">().</span><span class="na">parseText</span><span class="o">(</span><span class="n">text</span><span class="o">)</span></div><div class='line' id='LC8'><span class="n">json</span><span class="o">.</span><span class="na">artifacts</span><span class="o">.</span><span class="na">each</span><span class="o">{</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">println</span> <span class="n">it</span></div><div class='line' id='LC10'><span class="o">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1430856/cea0186a862217015fb4fc2b63eb0ad3575c06fc/jenkinsBuildArtifacts.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1430856#file_jenkins_build_artifacts.groovy" style="float:right;margin-right:10px;color:#666">jenkinsBuildArtifacts.groovy</a>
            <a href="https://gist.github.com/1430856">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript><br />
Here&#8217;s the sample output at time of writing:</p>
<blockquote><p>[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz, fileName:jruby-bin-1.7.0.dev.tar.gz, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz.md5, fileName:jruby-bin-1.7.0.dev.tar.gz.md5, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.tar.gz.sha1, fileName:jruby-bin-1.7.0.dev.tar.gz.sha1, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip, fileName:jruby-bin-1.7.0.dev.zip, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip.md5, fileName:jruby-bin-1.7.0.dev.zip.md5, displayPath:null]<br />
[relativePath:dist/jruby-bin-1.7.0.dev.zip.sha1, fileName:jruby-bin-1.7.0.dev.zip.sha1, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar, fileName:jruby-complete-1.7.0.dev.jar, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar.md5, fileName:jruby-complete-1.7.0.dev.jar.md5, displayPath:null]<br />
[relativePath:dist/jruby-complete-1.7.0.dev.jar.sha1, fileName:jruby-complete-1.7.0.dev.jar.sha1, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem, fileName:jruby-jars-1.7.0.dev.gem, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem.md5, fileName:jruby-jars-1.7.0.dev.gem.md5, displayPath:null]<br />
[relativePath:dist/jruby-jars-1.7.0.dev.gem.sha1, fileName:jruby-jars-1.7.0.dev.gem.sha1, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz, fileName:jruby-src-1.7.0.dev.tar.gz, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz.md5, fileName:jruby-src-1.7.0.dev.tar.gz.md5, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.tar.gz.sha1, fileName:jruby-src-1.7.0.dev.tar.gz.sha1, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip, fileName:jruby-src-1.7.0.dev.zip, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip.md5, fileName:jruby-src-1.7.0.dev.zip.md5, displayPath:null]<br />
[relativePath:dist/jruby-src-1.7.0.dev.zip.sha1, fileName:jruby-src-1.7.0.dev.zip.sha1, displayPath:null]</p></blockquote>
<h2>3. Read in a CSV file, filter it, and write out the result</h2>
<p>Groovy Grapes and one of my favorite libraries, <a href="http://opencsv.sourceforge.net/">OpenCSV</a>, make it trivial to script &#8216;one off&#8217; solutions for removing work that would normally take place manually in Excel. For me it comes up most often with data import/export from systems I&#8217;m working on and the need to create particular test environments using those import/export mechanisms. For example, using a scripted solution like this you can quickly:</p>
<ul>
<li>Export users from one test system into a CSV file, along with local phone number contact data</li>
<li>Replace the existing phone numbers with a mix of local and international numbers</li>
<li>Import the new data into a different test system</li>
<li>Verify that the system properly deals with international calling concerns</li>
</ul>
<p>This example simply trims out all of the rows where the second column of input contains values less than 100. It&#8217;s also nice to note that OpenCSV is smart enough to let you ignore one or more &#8216;header rows&#8217;, a common attribute of CSV files.<br />
<script src="http://gist.github.com/1430935.js?file=openCsv.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1430935" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nd">@Grab</span><span class="o">(</span><span class="n">group</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">net</span><span class="o">.</span><span class="na">sf</span><span class="o">.</span><span class="na">opencsv</span><span class="err">&#39;</span><span class="o">,</span> <span class="n">module</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">opencsv</span><span class="err">&#39;</span><span class="o">,</span> <span class="n">version</span> <span class="o">=</span> <span class="err">&#39;</span><span class="mf">2.3</span><span class="err">&#39;</span><span class="o">)</span></div><div class='line' id='LC2'><span class="kn">import</span> <span class="nn">au.com.bytecode.opencsv.CSVReader</span></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">au.com.bytecode.opencsv.CSVParser</span></div><div class='line' id='LC4'><span class="kn">import</span> <span class="nn">au.com.bytecode.opencsv.CSVWriter</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="n">def</span> <span class="n">TEST_FILE_NAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">test</span><span class="o">.</span><span class="na">csv</span><span class="err">&#39;</span></div><div class='line' id='LC7'><span class="n">def</span> <span class="n">TEST_OUTPUT_FILE_NAME</span> <span class="o">=</span> <span class="err">&#39;</span><span class="n">testOut</span><span class="o">.</span><span class="na">csv</span><span class="err">&#39;</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">[]&gt;</span> <span class="n">rows</span> <span class="o">=</span> <span class="k">new</span> <span class="n">CSVReader</span><span class="o">(</span><span class="k">new</span> <span class="n">FileReader</span><span class="o">(</span><span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">TEST_FILE_NAME</span><span class="o">)),</span> <span class="n">CSVParser</span><span class="o">.</span><span class="na">DEFAULT_SEPARATOR</span><span class="o">,</span> <span class="n">CSVParser</span><span class="o">.</span><span class="na">DEFAULT_ESCAPE_CHARACTER</span><span class="o">,</span> <span class="n">CSVParser</span><span class="o">.</span><span class="na">DEFAULT_QUOTE_CHARACTER</span><span class="o">,</span> <span class="mi">1</span><span class="o">).</span><span class="na">readAll</span><span class="o">()</span></div><div class='line' id='LC10'><span class="n">def</span> <span class="n">rowsOver100</span> <span class="o">=</span> <span class="n">rows</span><span class="o">.</span><span class="na">findAll</span> <span class="o">{</span><span class="n">it</span><span class="o">[</span><span class="mi">1</span><span class="o">].</span><span class="na">toInteger</span><span class="o">()</span> <span class="o">&gt;</span> <span class="mi">100</span><span class="o">}</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="n">File</span> <span class="n">output</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">TEST_OUTPUT_FILE_NAME</span><span class="o">)</span></div><div class='line' id='LC13'><span class="k">if</span> <span class="o">(</span><span class="n">output</span><span class="o">.</span><span class="na">exists</span><span class="o">())</span></div><div class='line' id='LC14'><span class="o">{</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">output</span><span class="o">.</span><span class="na">delete</span><span class="o">()</span></div><div class='line' id='LC16'><span class="o">}</span></div><div class='line' id='LC17'><span class="n">output</span><span class="o">.</span><span class="na">createNewFile</span><span class="o">()</span></div><div class='line' id='LC18'><span class="n">output</span><span class="o">.</span><span class="na">withWriter</span> <span class="o">{</span> <span class="n">writer</span> <span class="o">-&gt;</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">new</span> <span class="nf">CSVWriter</span><span class="o">(</span><span class="n">writer</span><span class="o">).</span><span class="na">writeAll</span><span class="o">(</span><span class="n">rowsOver100</span><span class="o">)</span></div><div class='line' id='LC20'><br/></div><div class='line' id='LC21'><span class="o">}</span></div><div class='line' id='LC22'><br/></div><div class='line' id='LC23'><span class="c1">//println rows</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1430935/0c21cfe5a273ed552193c3b94e379d3bb941a5e6/openCsv.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1430935#file_open_csv.groovy" style="float:right;margin-right:10px;color:#666">openCsv.groovy</a>
            <a href="https://gist.github.com/1430935">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript></p>
<h2>4. Download, install and run a stand-alone webserver</h2>
<p>This example comes courtesy of a <a href="http://www.ibm.com/developerworks/java/library/j-javadev2-20/index.html">recent article by Andrew Glover</a> about <a href="https://github.com/groovypp/gretty/wiki">Gretty</a>, a lightweight http server. I don&#8217;t have a concrete use-case for this right now, but it&#8217;s easy to note that in this case you can code a large part of the server behaviour directly in the script, unlike, for instance, if you were to use a script to stand up a Jetty server. This should let you publish a script once in a central location and stand up as many Gretty servers providing the declared services as you like. This particular example simply echos back &#8216;Hello&#8217; plus whatever path you append to localhost:8080.<br />
<script src="http://gist.github.com/1431012.js?file=grettyExample.groovy"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-1431012" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">import</span> <span class="nn">org.mbte.gretty.httpserver.*</span> </div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="nd">@GrabResolver</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="err">&#39;</span><span class="n">gretty</span><span class="err">&#39;</span><span class="o">,</span> </div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">root</span><span class="o">=</span><span class="err">&#39;</span><span class="nl">http:</span><span class="c1">//groovypp.artifactoryonline.com/groovypp/libs-releases-local&#39;)</span></div><div class='line' id='LC5'><span class="nd">@Grab</span><span class="o">(</span><span class="err">&#39;</span><span class="n">org</span><span class="o">.</span><span class="na">mbte</span><span class="o">.</span><span class="na">groovypp</span><span class="o">:</span><span class="nl">gretty:</span><span class="mf">0.4</span><span class="o">.</span><span class="mi">279</span><span class="err">&#39;</span><span class="o">)</span> </div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="n">GrettyServer</span> <span class="n">server</span> <span class="o">=</span> <span class="o">[]</span> </div><div class='line' id='LC8'><span class="n">server</span><span class="o">.</span><span class="na">groovy</span> <span class="o">=</span> <span class="o">[</span> </div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">localAddress:</span> <span class="k">new</span> <span class="n">InetSocketAddress</span><span class="o">(</span><span class="s">&quot;localhost&quot;</span><span class="o">,</span> <span class="mi">8080</span><span class="o">),</span> </div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nl">defaultHandler:</span> <span class="o">{</span> </div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span><span class="o">.</span><span class="na">redirect</span> <span class="s">&quot;/&quot;</span> </div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">},</span> </div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="s">&quot;/:name&quot;</span><span class="o">:</span> <span class="o">{</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="o">{</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span><span class="o">.</span><span class="na">text</span> <span class="o">=</span> <span class="s">&quot;Hello ${request.parameters[&#39;name&#39;]}&quot;</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> </div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> </div><div class='line' id='LC18'><span class="o">]</span> </div><div class='line' id='LC19'><span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">()</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1431012/e0bcf55e0b19d2cf070dab3d3797d2ee0b231655/grettyExample.groovy" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1431012#file_gretty_example.groovy" style="float:right;margin-right:10px;color:#666">grettyExample.groovy</a>
            <a href="https://gist.github.com/1431012">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript></p>
<h2>5. Remotely execute any of these scripts by url</h2>
<p>As of <a title="Groovy 1.8.3/1.9-beta-4" href="http://glaforge.appspot.com/article/groovy-1-8-3-and-1-9-beta-4-released" target="_blank">Groovy 1.8.3/1.9-beta-4</a> you can refer to a Groovy script hosted at a remote url and execute it locally. If you work on different machines a lot(as I do) this can really help keep your toolbox of scripts handy, regardless of where you are. Since these scripts are publicly hosted on GitHub(thanks guys!), you can simply copy the url from the &#8216;view raw&#8217; link at the bottom and go to your console to execute them like this:</p>
<pre class="brush: groovy; title: ; notranslate">
$ groovy https://gist.github.com/raw/1430856/cea0186a862217015fb4fc2b63eb0ad3575c06fc/jenkinsBuildArtifacts.groovy
{
    &quot;actions&quot;: [
        {
            &quot;causes&quot;: [
                {
                    &quot;shortDescription&quot;: &quot;Started by timer&quot;
                }
            ]
        },
        {
            &quot;buildsByBranchName&quot;: {
                &quot;origin/master&quot;: {
                    &quot;buildNumber&quot;: 684,
                    &quot;buildResult&quot;: null,
                    &quot;revision&quot;: {
                        &quot;SHA1&quot;: &quot;3419fee4bb9436d3222ff3df8dd7fcf2308a6919&quot;,
                        &quot;branch&quot;: [
                            {
                                &quot;SHA1&quot;: &quot;3419fee4bb9436d3222ff3df8dd7fcf2308a6919&quot;,
                                &quot;name&quot;: &quot;origin/master&quot;
                            }
                        ]
                    }
                }
            },
... and so on
</pre>
<h2>Final note</h2>
<p>Being able to share scripts across a variety of machines has definitely made my professional life a lot easier and I&#8217;m very glad to see the ability to execute code from a URL in Groovy. But what really turned me onto the idea was its usage in Gradle, which supports loading remote Groovy/Gradle scripts using the &#8220;apply from: {url or file}&#8221; syntax. I find that more and more I reference particular tasks remotely in a build, especially for static analysis tools that don&#8217;t necessarily need to be run on a regular basis.<br />
A great example of this is the recently released <a href="http://tellurianring.com/wiki/gradle/templates">Gradle Templates Plugin</a>, which is basically the Gradle answer to the <a href="http://maven.apache.org/archetype/maven-archetype-plugin/">Maven Archetype plugin</a>. Create a build.gradle with the following content:</p>
<pre class="brush: groovy; title: ; notranslate">
apply from: 'http://launchpad.net/gradle-templates/trunk/1.2/+download/apply.groovy'
</pre>
<p>And we have the following tasks available to create new Gradle projects and objects with conventional structure:</p>
<pre class="brush: groovy; title: ; notranslate">
Template tasks
--------------
createGradlePlugin - Creates a new Gradle Plugin project in a new directory named after your project.
createGroovyClass - Creates a new Groovy class in the current project.
createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.
createJavaClass - Creates a new Java class in the current project.
createJavaProject - Creates a new Gradle Java project in a new directory named after your project.
createScalaClass - Creates a new Scala class in the current project.
createScalaObject - Creates a new Scala object in the current project.
createScalaProject - Creates a new Gradle Scala project in a new directory named after your project.
createWebappProject - Creates a new Gradle Webapp project in a new directory named after your project.
exportAllTemplates - Exports all the default template files into the current directory.
exportGroovyTemplates - Exports the default groovy template files into the current directory.
exportJavaTemplates - Exports the default java template files into the current directory.
exportPluginTemplates - Exports the default plugin template files into the current directory.
exportScalaTemplates - Exports the default scala template files into the current directory.
exportWebappTemplates - Exports the default webapp template files into the current directory.
initGradlePlugin - Initializes a new Gradle Plugin project in the current directory.
initGroovyProject - Initializes a new Gradle Groovy project in the current directory.
initJavaProject - Initializes a new Gradle Java project in the current directory.
initScalaProject - Initializes a new Gradle Scala project in the current directory.
initWebappProject - Initializes a new Gradle Webapp project in the current directory.
</pre>
<!-- AdSense Now! V1.95 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="float:right;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-6955914197200080";
/* 728x90, created 8/3/09 */
google_ad_slot = "4051815125";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2011/09/18/using-gradle-to-bootstrap-your-legacy-ant-builds/' rel='bookmark' title='Using Gradle to Bootstrap your Legacy Ant Builds'>Using Gradle to Bootstrap your Legacy Ant Builds</a></li>
<li><a href='http://www.kellyrob99.com/blog/2011/03/27/hooking-into-the-jenkinshudson-api/' rel='bookmark' title='Hooking into the Jenkins(Hudson) API'>Hooking into the Jenkins(Hudson) API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/09/26/groovy-inspecteval-for-externalizing-data/' rel='bookmark' title='Groovy inspect()/Eval for Externalizing Data'>Groovy inspect()/Eval for Externalizing Data</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2011/12/04/five-cool-things-you-can-do-with-groovy-scripts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Grails-UI DataTable using XML for a model</title>
		<link>http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=grails-ui-datatable-using-xml-for-a-model</link>
		<comments>http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 07:06:05 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Crucible]]></category>
		<category><![CDATA[DataTable]]></category>
		<category><![CDATA[Fisheye]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[google-charts]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTPBuilder]]></category>
		<category><![CDATA[HttpClient]]></category>
		<category><![CDATA[Jira]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[RESTClient]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=836</guid>
		<description><![CDATA[I had a great chance to play with some new stuff this weekend, namely Grails 1.2-M3, the new Grails REST plugin and Groovy in general. Awhile back I wrote some Groovy code to explore the various Jira, Fisheye and Crucible REST api&#8217;s using Apache HttpClient directly, and I wanted to see what it would like [...]
Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/' rel='bookmark' title='A Grails App Demoing the StackExchange API'>A Grails App Demoing the StackExchange API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/24/groovy-reverse-map-sort-done-easy/' rel='bookmark' title='Groovy reverse map sort done easy'>Groovy reverse map sort done easy</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Jira Grails Plugin'>Jira Grails Plugin</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I had a great chance to play with some new stuff this weekend, namely <a href="http://grails.org/1.2-M3+Release+Notes">Grails 1.2-M3</a>, the new <a href="http://grails.org/plugin/rest">Grails REST plugin</a> and Groovy in general. Awhile back I wrote some Groovy code to explore the various Jira, Fisheye and Crucible REST api&#8217;s using Apache HttpClient directly, and I wanted to see what it would like abstracted behind <a href="http://groovy.codehaus.org/modules/http-builder/">HTTPBuilder</a>. With the help of the <a href="http://grails.org/GrailsUI+Plugin">Grails-UI</a> and <a href="http://grails.org/plugin/google-chart">Google-charts</a> plugins, I got some pretty nice views of the data as well.</p>
<p>First off, dealing with a RESTful call was about as simple as I&#8217;ve ever seen. This is the entire code that deals with creating the connection, authenticating, executing a GET, and parsing the returned XML into a &#8216;data&#8217; property on the response.</p>
<pre class="brush: groovy; title: ; notranslate">
    private withFisheye(String url, Map args) {
        withRest(uri: url) {
            auth.basic userName, password
            return get(query: args)
        }
    }
</pre>
<p>Getting XML using <a href="http://www.jroller.com/aalmiray/">Andres&#8217;</a> plugin is extremely simple and we can achieve some pretty nice visualizations of the resulting data very easily as well. In particular I wanted to share how to use an XML response as a backing model for DataTable. The excellent examples provided by <a href="http://weblog.dangertree.net/tag/grailsui/">Matthew Taylor on his blog</a> seemed to concentrate on using GORM to load and sort domain objects to utilize as data models. When using XML as an alternative way to represent the data, and using RESTful calls to populate that data, the available sorting options on a DataTable weren&#8217;t able to function properly without a little extra help.</p>
<p>Consider an list of XML elements like this, which represents a single review in Crucible.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;reviewdata&gt;
    &lt;allowreviewerstojoin&gt;false&lt;/allowreviewerstojoin&gt;
    &lt;author&gt;
        &lt;displayname&gt;Kelly Robinson&lt;/displayname&gt;
        &lt;username&gt;TheKaptain&lt;/username&gt;
    &lt;/author&gt;
    &lt;closedate&gt;20010101T00::00.0000000&lt;/closedate&gt;
    &lt;createdate&gt;20010101T00::00.0000000&lt;/createdate&gt;
    &lt;creator&gt;
        &lt;displayname&gt;Kelly Robinson&lt;/displayname&gt;
        &lt;username&gt;TheKaptain&lt;/username&gt;
    &lt;/creator&gt;
    &lt;description&gt;
        Test review
    &lt;/description&gt;
    &lt;moderator&gt;
        &lt;displayname&gt;Kelly Robinson&lt;/displayname&gt;
        &lt;username&gt;TheKaptain&lt;/username&gt;
    &lt;/moderator&gt;
    &lt;name&gt;
        Test review
    &lt;/name&gt;
    &lt;permaid&gt;
        &lt;id&gt;CR1&lt;/id&gt;
    &lt;/permaid&gt;
    &lt;projectkey&gt;CR&lt;/projectkey&gt;
    &lt;state&gt;Closed&lt;/state&gt;
    &lt;summary&gt;
      Test review
    &lt;/summary&gt;
&lt;/reviewdata&gt;
</pre>
<p>You can leverage this list as a DataTable model by extracting specific elements from the XML, and providing a sorting mechanism based on dynamic map value lookups.</p>
<pre class="brush: groovy; title: ; notranslate">
    private def createReviewDataJson(HttpServletResponse response, Map params, reviews) {
        def list = []
        response.setHeader(&quot;Cache-Control&quot;, &quot;no-store&quot;)
       //build a List of Maps, one for each row in the DataTable
        reviews.reviewData.each {
            list &lt;&lt; [
                    id: it.permaId.id.text(),
                    author: it.author.displayName.text(),
                    creator: it.creator.displayName.text(),
                    moderator: it.moderator.displayName.text(),
                    description: it.description.text(),
                    state: it.state.text()
            ]
        }
       //sort by the 'order' and 'sort' parameters passed in by DataTable
        switch (params.order) {
            case 'asc':
                list.sort { it.&quot;${params.sort}&quot; } //sort by value where key == params.sort
                break
            case 'desc':
                list.sort {a, b -&gt; b.&quot;${params.sort}&quot; &lt;=&gt; a.&quot;${params.sort}&quot; } //reverse sort by value
                break
        }
       //the entire model
        def data = [totalRecords: list.size(), results: list]
        render data as JSON
    }
</pre>
<p>This model can then be rendered using the <gui :datatable=""> tag. Note that this is pretty much a direct copy of a provided example, nothing fancy here.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;gui:datatable id=&quot;statDataTable&quot; draggablecolumns=&quot;true&quot; columndefs=&quot;[
        [id:'id', sortable:true, resizeable:true],
        [author:'author', sortable:true, resizeable:true],
        [creator:'creator', sortable:true, resizeable:true],
        [moderator:'moderator',  sortable:true, resizeable:true],
        [description:'description', sortable:true, resizeable:true, formatter:'textarea'],
        [state:'state', sortable:true, resizeable:true]
    ]&quot; paginatorconfig=&quot;[
        template:'{PreviousPageLink} {PageLinks} {NextPageLink} {CurrentPageReport}',
        pageReportTemplate:'{totalRecords} total records'
    ]&quot; sortedby=&quot;id&quot; controller=&quot;fisheye&quot; action=&quot;${action}&quot; resultslist=&quot;results&quot; rowsperpage=&quot;10&quot;&gt;
</pre>
<p>So for very little work you get a sortable, paginated DataTable, complete with column resizing and dragging. The DataTable is also being rendered using a template, allowing it to be used arbitrarily by controller methods that populate the model with different reviews. Pretty cool if you ask me. I also used the same backing XML model to drive some PieCharts, but that&#8217;s perhaps a topic for another post.</p>
<p> <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
</gui></p>
<p>Related posts:<ol>
<li><a href='http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/' rel='bookmark' title='A Grails App Demoing the StackExchange API'>A Grails App Demoing the StackExchange API</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/10/24/groovy-reverse-map-sort-done-easy/' rel='bookmark' title='Groovy reverse map sort done easy'>Groovy reverse map sort done easy</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Jira Grails Plugin'>Jira Grails Plugin</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

