<?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>Sonatype Blog &#187; rest</title>
	<atom:link href="http://blog.sonatype.com/people/tag/rest/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sonatype.com/people</link>
	<description>Sonatype is transforming software development with tools, information and services that enable organizations to build better software, faster, using open-source components.</description>
	<lastBuildDate>Thu, 16 May 2013 18:53:09 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>You Don&#8217;t Need A Browser to Use Maven Central</title>
		<link>http://blog.sonatype.com/people/2011/06/you-dont-need-a-browser-to-use-maven-central/</link>
		<comments>http://blog.sonatype.com/people/2011/06/you-dont-need-a-browser-to-use-maven-central/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 15:36:36 +0000</pubDate>
		<dc:creator>Joel Orlina</dc:creator>
				<category><![CDATA[Central]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[Sonatype]]></category>

		<guid isPermaLink="false">http://www.sonatype.com/people/?p=8160</guid>
		<description><![CDATA[Since its release in January, the Maven Central website (http://search.maven.org) has provided Apache Maven users with: Search functionality that allows one to quickly track down artifacts and their dependency details when trying to resolve build problems. Browse functionality that aids in discovery of new artifacts to use in projects. In the intervening months, Sonatype has [...]]]></description>
				<content:encoded><![CDATA[<p>Since its release in January, the Maven Central website (<a href="http://search.maven.org" target="_blank">http://search.maven.org</a>) has provided Apache Maven users with:</p>

<ul>
    <li>Search functionality that allows one to quickly track down artifacts and their dependency details when trying to resolve build problems.</li>
    <li>Browse functionality that aids in discovery of new artifacts to use in projects.</li>
</ul>

<p>In the intervening months, Sonatype has focused its efforts on improving the usability of the Maven Central user interface in the hopes of making it the first place users look when trying to find an artifact.  Recently, users who have reaped the benefits of using the Maven Central website have asked about interacting programmatically with the search functionality.</p>

<p>If you pay attention to your web browser&#8217;s address bar when conducting searches on Maven Central, you can already see that a REST-style API exists.  For example, searching for &#8220;guice&#8221; from the main search box results in the following URL being generated (the following URL&#8217;s are NOT URL-encoded for the sake of readability):</p>

<ul>
    <li><strong><a href="http://search.maven.org/#search|ga|1|guice" target="_blank">http://search.maven.org/#search|ga|1|guice</a></strong></li>
</ul>

<p>Translating the search request into English, that URL requests a basic search for any artifact (irrespective of version) containing the word &#8220;guice&#8221; in either the groupId or artifactId, returning only the first page of results.  Each row of the results shows the latest version of the artifact and the date the artifact was last updated as well as any classifiers associated with the artifact.</p>

<p>You can build up the complete library of search requests simply by paying attention to your web browser&#8217;s address field as you use the Maven Central website.  For the sake of convenience, we&#8217;ve collected all the URLs that make up Maven Central&#8217;s search API in a document available <a href="http://search.maven.org/ajaxsolr/images/MavenCentralAPIGuide.pdf" target="_blank">here</a>.</p>

<p>Sadly, these URL&#8217;s are still only useful when requesting them via web browser.  They are links that can be bookmarked or e-mailed, but they do NOT work when using a non-browser agent like wget or curl.  The Maven Central user interface is essentially a browser-based application that uses Javascript to make asynchronous requests to yet another set of URL&#8217;s.  Once you make a request that looks like the URL above, the browser fires off the actual request to another Maven Central URL responsible for conducting the search and returning results that are formatted by the browser.</p>

<p>The sample request above, when converted to an actual Maven Central search request, looks like this:</p>

<ul>
    <li><strong><a href="http://search.maven.org/solrsearch/select?q=guice&amp;rows=20&amp;wt=json" target="_blank">http://search.maven.org/solrsearch/select?q=guice&amp;rows=20&amp;wt=json</a></strong></li>
</ul>

<p>The actual text of your query goes in the appropriately named &#8220;q&#8221; parameter, the &#8220;rows&#8221; parameter restricts the results to a smaller number than the full result set, and the &#8220;wt&#8221; parameter can be either &#8220;xml&#8221; or &#8220;json,&#8221; depending on how your application prefers to handle results.</p>

<p>Some useful examples appear below.  Again, please refer to the <a href="http://search.maven.org/ajaxsolr/images/MavenCentralAPIGuide.pdf" target="_blank">API Guide</a> for a complete listing:</p>

<ul>
    <li>Fully-qualified classname search &#8211;
<strong><a href="http://search.maven.org/solrsearch/select?q=fc:&quot;org.specs.runner.JUnit&quot;&amp;rows=20&amp;wt=json" target="_blank">http://search.maven.org/solrsearch/select?q=fc:&#8221;org.specs.runner.JUnit&#8221;&amp;rows=20&amp;wt=json</a></strong></li>
    <li>GroupId and artifactId search that returns all available artifact versions &#8211;
<strong><a href="http://search.maven.org/solrsearch/select?q=g:&quot;org.apache.maven.indexer&quot;+AND+a:&quot;maven-indexer&quot;&amp;rows=20&amp;core=gav" target="_blank">http://search.maven.org/solrsearch/select?q=g:&#8221;org.apache.maven.indexer&#8221;+AND+a:&#8221;maven-indexer&#8221;&amp;rows=20&amp;core=gav</a></strong></li>
    <li>SHA1 search (you would need to pre-calculate the SHA1 before sending the request to Maven Central) &#8211;
<strong><a href="http://search.maven.org/solrsearch/select?q=1:&quot;2d3c16092663da9041b171b8d3627cbafa8f0cb1&quot;&amp;rows=20&amp;wt=json" target="_blank">http://search.maven.org/solrsearch/select?q=1:&#8221;2d3c16092663da9041b171b8d3627cbafa8f0cb1&#8243;&amp;rows=20&amp;wt=json</a></strong></li>
</ul>

<p>In an upcoming post, I&#8217;ll describe the architecture behind Maven Central that makes all this functionality possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2011/06/you-dont-need-a-browser-to-use-maven-central/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taking Repos Offline/Online via the Nexus REST API</title>
		<link>http://blog.sonatype.com/people/2010/04/taking-repos-offlineonline-via-the-nexus-rest-api/</link>
		<comments>http://blog.sonatype.com/people/2010/04/taking-repos-offlineonline-via-the-nexus-rest-api/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 06:00:42 +0000</pubDate>
		<dc:creator>Tim O'Brien</dc:creator>
				<category><![CDATA[Nexus]]></category>
		<category><![CDATA[Sonatype]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.sonatype.com/people/?p=5104</guid>
		<description><![CDATA[This post runs through a simple Ruby script that manipulates the offline/online status of hosted Nexus repositories. Such a script would be useful if you need to manipulate the storage of a repository while Nexus is running. Assume you have a script that needs to backup the storage directory of all of your hosted directories [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.sonatype.com/people/wp-content/uploads/2010/01/nexus-small.png"><img class="alignright size-full wp-image-3683" title="nexus-small" src="http://www.sonatype.com/people/wp-content/uploads/2010/01/nexus-small.png" alt="" width="250" height="62" /></a>This post runs through a simple Ruby script that manipulates the offline/online status of hosted Nexus repositories.    Such a script would be useful if you need to manipulate the storage of a repository while Nexus is running.  Assume you have a script that needs to backup the storage directory of all of your hosted directories once a night. If you wanted to make sure that your repository isn&#8217;t altered in the middle of a backup, you would put each hosted repository out of service before the backup job ran.  After the job completed, you would put all of your hosted servers back into service.</p>

<p>While you could do this via the Nexus UI, this wouldn&#8217;t help your automated nightly backup script.   For this script to be easy to run, you&#8217;ll need to script Nexus via the REST interface.   With the Nexus 1.6 release, we&#8217;ve released <a href="https://grid.sonatype.org/ci/view/Nexus/job/Nexus/label=ubuntu/ws/trunk/nexus/nexus-rest-api/target/classes/docs/index.html">full documentation of the Nexus REST services available</a> in every Nexus installation (<a href="https://grid.sonatype.org/ci/view/Nexus/job/Nexus/label=ubuntu/ws/trunk/nexus/nexus-rest-api/target/classes/docs/index.html">REST doc</a>).   Continue reading for an example of how to interact with, authenticate, and manipulate a Nexus instance via the REST APIs.
<span id="more-5104"></span></p>

<p>The following script is written in Ruby and uses the <a href="http://www.ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html">REXML</a> XML processor and the <a href="http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html">Net:HTTP</a> library.  Both of these libraries are available in the Ruby standard library.   I tested these Ruby scripts using a standard Ruby 1.8.7 distribution.  If you want to try these scripts out on your own, they will run in any standard Ruby interpreter without requiring any extra RubyGems.</p>

<p>Here&#8217;s the script, we&#8217;ll walk through some of the highlights after the source:</p>

<script src="http://gist.github.com/374144.js?file=Online+Script"></script>

<p>So, what&#8217;s going on in this script?</p>

<ul>
    <li><strong>Lines 7-15:</strong> Define some simple variables like host, port, the root URL of Nexus.   We also define the status string &#8220;OUT_OF_SERVICE&#8221;.   If we ran this script and then wanted to bring all hosted repositories back online, we would change this string to &#8220;IN_SERVICE&#8221;.</li>
    <li><strong>Lines 17-21:</strong> Get a list of all repositories as an XML document and parse it.   All Nexus REST services can return either XML or JSON, the default response if no &#8220;Content-type&#8221; header is present in the request is &#8220;application/xml&#8221;.   This is a simple HTTP GET which does not require any authentication. You can find detailed documentation for the /service/local/repositories service <a href="https://grid.sonatype.org/ci/view/Nexus/job/Nexus/label=ubuntu/ws/trunk/nexus/nexus-rest-api/target/classes/docs/rest.repositories.html">here</a>.</li>
    <li><strong>Line 24:</strong> We&#8217;re only interested in manipulating hosted repositories.    This line applies the XPath query &#8220;//repositories-item[repoType='hosted']&#8221; to the XML document and passed matching nodes to a large block that operates on each matching repository element.</li>
    <li><strong>Lines 26-29:</strong> Just print out the id of each repository and the URL.</li>
    <li><strong>Lines 31-34:</strong> Retrieve the status of a repository using the repository identifier.   Again, this is a simple HTTP GET that does not require any authentication information. It returns an XML doc that describes the current status of the repository.   Detailed documentation for the &#8220;/service/local/repositories/{repositoryId}/status&#8221; can be found <a href="https://grid.sonatype.org/ci/view/Nexus/job/Nexus/label=ubuntu/ws/trunk/nexus/nexus-rest-api/target/classes/docs/rest.repositories.repositoryId.status.html">here</a>.</li>
    <li><strong>LInes 36-41:</strong> Now here&#8217;s where it gets a bit fancy.   The REST call to get the status was an HTTP GET, which returns an XML document.   The REST call to set the status is an HTTP PUT, which accepts the same XML document.   To set the repository status, we&#8217;re going to use the XML returned by a GET call to the status service and just change the &#8220;localStatus&#8221; element to either &#8220;IN_SERVICE&#8221; or &#8220;OUT_OF_SERVICE&#8221;.   The statement on line 38, simply sets the value of this element in the XML document which was returned by the previous GET.</li>
    <li><strong>Lines 43-50:</strong> Changing the status of a repository requires the proper privileges.  For this call, we&#8217;ll need to supply the credentials set in the initial portion of the script.    We will also need to make an HTTP PUT call and pass the XML document for repository status as the request body.    While Nexus REST defaults to an XML response if no Content-Type is specified for simple HTTP GET calls, our HTTP PUT call to the repository status service must set the request&#8217;s &#8220;Content-Type&#8221; header to &#8220;application/xml&#8221; for status to be updated.   The request body is set to the XML, which was modified on line 38, and the request is made on line 50.</li>
</ul>

<p>That&#8217;s it.  While this particular script isn&#8217;t much, it should provide a template for those of you who are interested in starting to automate common tasks via the Nexus REST API.</p>

<p><strong>OPEN CHALLENGE:</strong> This this script is too verbose?   Create your own Gist on GitHub.com and point to it in the comments.   I&#8217;d love to see what other people could do with this sample.  Expect a lot of follow-up posts to this, as we&#8217;re really interested in developing a large library of scripts for people to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2010/04/taking-repos-offlineonline-via-the-nexus-rest-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Documenting the Nexus REST API with Enunciate</title>
		<link>http://blog.sonatype.com/people/2010/02/documenting-the-nexus-rest-api-with-enunciate/</link>
		<comments>http://blog.sonatype.com/people/2010/02/documenting-the-nexus-rest-api-with-enunciate/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 17:31:15 +0000</pubDate>
		<dc:creator>Tamas Cservenak</dc:creator>
				<category><![CDATA[Nexus]]></category>
		<category><![CDATA[Sonatype]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[enunciate]]></category>
		<category><![CDATA[nexus pro]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://www.sonatype.com/people/?p=4301</guid>
		<description><![CDATA[Nexus OSS Core has more than 120 REST Resources published. And that number is just increasing with new Nexus Plugins. Not to mention Nexus Pro that comes with even more plugins and more REST resources.    Everything you do in Nexus, whether you use the Maven Nexus plugin or the Nexus UI, is interacting with [...]]]></description>
				<content:encoded><![CDATA[<p><strong><a href="http://www.sonatype.com/people/wp-content/uploads/2010/01/nexus-small.png"><img class="alignright size-full wp-image-3683" title="nexus-small" src="http://www.sonatype.com/people/wp-content/uploads/2010/01/nexus-small.png" alt="" width="250" height="62" /></a>Nexus OSS Core has more than 120 REST Resources</strong> published. And that number is just increasing with new Nexus Plugins. Not to mention Nexus Pro that comes with even more plugins and more REST resources.    Everything you do in Nexus, whether you use the Maven Nexus plugin or the Nexus UI, is interacting with a REST service that is available to you if you want to write your own customizations and scripts.   It has been this way since we started the project in 2007.  In this post, I&#8217;m going to discuss how this came to be, how Nexus was developed with REST in mind from the beginning.</p>

<h3>Nexus: A Core of REST Services</h3>

<p>When we started the Nexus project, I called it a &#8220;blind&#8221; application.  A &#8220;blind&#8221; webapp is one with no UI technology whatsoever built-in.   All it publishes is a few static files, and a REST API.   All of the UI that you see in Nexus is Javascript.   Your browser executes Javascript which, in turn, interacts with a set of services.   The only presentation technology on the server side is a trivial Velocity template used to render the initial &#8220;shell&#8221; of the page.<span id="more-4301"></span></p>

<p>The server-side application you call Nexus, doesn&#8217;t generate the UI, that is all Javascript.   It is a completely separate and standalone application, that runs in your browser! A self contained JavaScript application (powered by ExtJS), that communicates with Nexus server, using REST calls only.  This has one very important consequence: whatever Nexus functionality you are able to reach using the Nexus User Interface (and I do mean <em>all</em>), you can do with a plain REST client.     If you want to automate a task, you can use a tool like <tt>curl</tt>, or some Ruby script, or any HTTP capable client.   You can even start to implement your own custom interface if you would like a completely customized UI.</p>

<p>As I said, it was like this since day one. But, we always had one major issue that prevented wider acceptance of Nexus&#8217; REST API: <strong>we had no up-to-date documentation for it</strong>.    It wasn&#8217;t a priority, we spent much of our time trying to integrate the only existing REST framework (restlet.org) with Plexus, and since we were moving so quickly to implement new features, we didn&#8217;t think it made sense to stop and document an ever-changing interface.  We did maintain a <a rel="nofollow" href="https://docs.sonatype.com/display/NX/Nexus+Rest+API">wiki page</a> which described the REST services from the beginning of the project, it always provided stale information given our aggressive development pace.</p>

<h3>REST Documentation: Using Enunciate</h3>

<p>I&#8217;ve been looking at the <a rel="nofollow" href="http://enunciate.codehaus.org/">Enunciate</a> project for some time, and it appears to be the solution to our REST document issues.  Enunciate is a cool project hosted on <a href="http://codehaus.org"><span style="color: #003366;">Codehaus</span></a>, with a bold promise:</p>

<p><em>Enunciate is designed to make your life easier. Enunciate deals with your deployment difficulties, documentation, and client-side code. By using Enunciate to publish your service interfaces, not only will you have all three Web service interfaces (SOAP, REST, and AMF), but you&#8217;ll also have full up-to-date documentation generated, strongly typed ActionScript code that you can use to invoke your remote services from your Flex code, and rich client-side libraries that can be used to access your Web services from a variety of platforms (including Mac/iPhone).</em></p>

<p>Our initial plans are to use Enunciate in a &#8220;lite&#8221; mode to <strong>generate documentation</strong> (and potentially client side code) for our current REST API. Later, we plan to integrate it more closely into new Nexus &#8220;Remoting API&#8221; implementation, and it will be the backbone of our REST services when we will implement version 2.0 of our API.</p>

<p>Here is just a taste of what is to come.  We&#8217;ve used Enunciate to generate documentation for our REST services, and the work is proceeding very quickly.   Here is a snapshot of the documentation we will be releasing soon.</p>

<p><a href="http://www.sonatype.com/people/wp-content/uploads/2010/02/tim1.png"><img class="aligncenter size-medium wp-image-4303" title="Nexus Enunciate Sample #1" src="http://www.sonatype.com/people/wp-content/uploads/2010/02/tim1-300x256.png" alt="" width="300" height="256" /></a></p>

<p><a href="http://www.sonatype.com/people/wp-content/uploads/2010/02/tim2.png"><img class="aligncenter size-medium wp-image-4304" title="Nexus Enunciate Sample #2" src="http://www.sonatype.com/people/wp-content/uploads/2010/02/tim2-300x230.png" alt="" width="300" height="230" /></a></p>

<p><a href="http://www.sonatype.com/people/wp-content/uploads/2010/02/tim3.png"><img class="aligncenter size-medium wp-image-4316" title="Enunciated Nexus REST API Sample #3" src="http://www.sonatype.com/people/wp-content/uploads/2010/02/tim3-300x263.png" alt="" width="300" height="263" /></a></p>

<h3>Remaining Problems to Solve</h3>

<p>When our REST API was concieved in Q4 of 2007 we didn&#8217;t have the rich array of options that we have today.   One major REST library was available, and that was <a rel="nofollow" href="http://www.restlet.org/">Restlet</a>.  JSR311 wasn&#8217;t around back then, so we were forced to code directly to the Restlet API.  Back in 2007, it was very cool to create Plexus components that were then automatically published as REST Resources in Nexus. But today, the same thing looks very cumbersome and is not what one would call a &#8220;state of the art&#8221;. Back then, we had these goals in mind:</p>

<ul>
    <li>have complete REST API published on Nexus</li>
    <li>have a decoupled UI application</li>
    <li>provide XML/JSON serialized transport to REST Resource without any effort, with proper content negotiation (XML was kept as &#8220;Plan B&#8221;)</li>
    <li>make our REST Resources as Plexus components (to enjoy all the benefits of IoC, and later pluggability)</li>
</ul>

<p>While we fulfilled much of these goals above, we did that at a high cost.  For a Nexus core developer (or Nexus plugin developer), it is very cumbersome to create a new REST Resource using our classes, compared to what REST libraries are available today. Current state-of-the-art REST libraries make our initial implementation seem somewhat naive (hence the need to move toward new libraries like Enunciate). Our 1st and biggest mistake was a very deep class hierarchy in our current API.  While all the &#8220;defaults&#8221; are properly configured, it is often difficult to create a non-trivial Resource in the current API if you are not intimately familiar with the system.</p>

<p>Also, in the initial design, we use XStream with a custom driver to produce JSON. Back then, it was a real pain to produce proper JSON out of Java.   Today, we have libraries like Jackson.   In the next interation of refactoring, you&#8217;ll see update the infrastructure used to produce our REST services to bring it up to speed with what is available today.</p>

<h3>The Benefits of &#8220;enunciating&#8221; a REST API</h3>

<p>At first, we will use Enunciate with Nexus during build time only, to generate HTML documentation of our REST API. This documentation will be available publicly, but will also be bundled with every Nexus instance!   Our work to modify our own REST infrastructure is going to require some &#8220;invasive&#8221; work, but I have to emphasize that Enunciate is not invasive if you use it on a modern JSR311 based REST applications. Enunciate is invasive for us only, since we are about to use it on a home grown, non-JSR311 REST application.</p>

<p>Enunciate gathers and builds your services model using your sources and all the metadata it finds (Java5 annotations, Javadoc).  To &#8220;enunciate&#8221; the Nexus REST API, we had to add JSR311 annotations to our existing REST Resources.  There was one more problem to solve: our method signatures are more &#8220;servlet like&#8221;, and they didn&#8217;t fit the model of a JSR311 REST Application. While a JSR311 application method signature completely describes the method expectations about payload, parameters, and response type, our methods – whether GET, PUT, POST or DELETE – have almost same signature: RestRequest, RestResponse, Variant. Hence, we had to add more metainformation describing what a method does: what it expects as input, if any, and what it sends out as response.</p>

<p>Luckily, it turned out that this was the only piece missing, and Enunciate was happy to generate documentation for us. Ryan added the new annotation that describes the &#8220;alternate REST Signature&#8221; of the method, and Enunciate got all the information it needed to generate documentation for us.</p>

<p>Another painful step yet to be completed is &#8220;freeing&#8221; our REST DTOs from Modello. Initially, we knew we wanted to <em>version</em> the DTOs used in REST. Hence, we used Modello to generate the DTOs. Later, problems with Modello and Restlet forced us to always use version 1.0 of our REST DTOs. Since Enunciate requires that DTOs have JAXB2 annotations, we decided to store our DTOs as code and ditch Modello in our builds.</p>

<p>All this looks like a lot of work, but it is actually pretty straightforward.   While this might seem dull to someone not developing Nexus, this work is going to bring real value once it is completed.    In addition to solving our documentation problems, Enunciate is going to open up a world of possibilities once we migrate our REST services over to the framework.</p>

<p>For more information about Enunciate, the <a rel="nofollow" href="http://docs.codehaus.org/display/ENUNCIATE/Enunciate">Enunciate Wiki</a> contains a nice example of how to use Enunciate in case like ours is, without JAX-RS. Example is shown <a rel="nofollow" href="http://docs.codehaus.org/display/ENUNCIATE/Leveraging+Enunciate+Without+JAX-*S">here</a>.  Examples of Enunciate generated documentation can be seen on it&#8217;s <a rel="nofollow" href="http://enunciate.codehaus.org/">site</a>. There is a great walk-through, with <a rel="nofollow" href="http://enunciate.codehaus.org/wannabecool/step4/index.html">static examples</a>.</p>

<h3>Expect More Changes in the Next Few Months</h3>

<p>As Nexus graduated from alphas, betas and now is at a 1.5.0 version, we realize we have to change gears to keep up. Enunciate is the 1st &#8220;newcomer&#8221; technology to Nexus stack.  There will be more to come.   Think of this as the Nexus 100,000 mile checkup.  We&#8217;re taking a look at the stack and taking this as an opportunity to upgrade where necessary.</p>

<p>One last note, this post is not about any deficiencies in Restlet.  Restlet is a great framework, and it served us well.  We – the Nexus Project team – are <strong>very thankful</strong> to Restlet.org project with all the help we got from them and for the great library they made.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2010/02/documenting-the-nexus-rest-api-with-enunciate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Searching with the Sonatype Nexus REST API: Groovy</title>
		<link>http://blog.sonatype.com/people/2008/11/searching-with-the-sonatype-nexus-rest-api-groovy/</link>
		<comments>http://blog.sonatype.com/people/2008/11/searching-with-the-sonatype-nexus-rest-api-groovy/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 21:25:30 +0000</pubDate>
		<dc:creator>Tim O'Brien</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Nexus]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://blogs.sonatype.com/people/book/?p=284</guid>
		<description><![CDATA[This post is a follow-up to the previous post which provided some sample Ruby scripts that can be used to list repositories and search for artifacts in a Nexus instance.   Today, we&#8217;re going to see how to complete the same tasks using the Groovy scripting language.   The Groovy scripting language is a scripting language that [...]]]></description>
				<content:encoded><![CDATA[<p><img class="alignright size-thumbnail wp-image-285" src="http://cms.sonatype.com/wordpress/wp-content/uploads/2008/11/scripting-nexus-groovy.png" alt="" width="115" height="99" />This post is a follow-up to the <a href="http://blogs.sonatype.com/people/book/2008/11/19/searching-with-the-nexus-rest-api-ruby/">previous post</a> which provided some sample Ruby scripts that can be used to list repositories and search for artifacts in a Nexus instance.   Today, we&#8217;re going to see how to complete the same tasks using the Groovy scripting language.   The Groovy scripting language is a scripting language that has gained popularity due to the ease of integration with the JVM.</p>

<p>The following scripts are in Groovy and they can be invoked from the command line using groovy.  For example, if you want to run the QuickSearch.groovy script, you would run &#8220;groovy QuickSearch.groovy activemq&#8221; to search for artfiacts that contain the string &#8220;activemq&#8221;.   I tested these Ruby scripts using the latest Groovy 1.5.7 distribution.  Go to the <a href="http://groovy.codehaus.org">Groovy page</a>, click on Download, and download the Cross-platform Installer, this will install Groovy on your machine and also tell you what you&#8217;ll need to add to your PATH.<span id="more-320"></span></p>

<h2>The Nexus REST API</h2>

<p>The UI of Nexus is written in ExtJS and it makes heavy use of AJAX callbacks to REST services.  In fact, if you load up Nexus in a tool like Firebug, an extension for Firefox which allows you to trace all network activity, you will see that almost every action in Nexus triggers a call to a REST service. For more details about the Nexus REST services and for a pointer to the documentation, read the <a href="http://blogs.sonatype.com/people/book/2008/11/19/searching-with-the-nexus-rest-api-ruby/">previous blog post</a> in this series which was focused on a similar set of Ruby scripts.</p>

<p>If you would like to download the sample scripts in this blog post, you can download this ZIP file which contains four Groovy scripts: <a href="http://books.sonatype.com/tutorial-files/nexus-rest-groovy.zip">http://books.sonatype.com/tutorial-files/nexus-rest-groovy.zip</a></p>

<h2>Listing Repositories</h2>

<p>The first script simply lists all of the repositories in a Nexus installation.  Here it is:</p>


<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> xml <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;http://repository.sonatype.org/service/local/repositories&quot;</span>.<span style="color: #CC0099;">toURL</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> root <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlParser<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parseText</span><span style="color: #66cc66;">&#40;</span> xml <span style="color: #66cc66;">&#41;</span>
root.<span style="color: #006600;">data</span>.<span style="color: #ff0000;">'repositories-item'</span>.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;${it.name.text()} (${it.id.text()})&quot;</span>
  <span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>${it.resourceURI.text()}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>This script sets the pattern for the scripts to follow.  We construct a URL in String, then we call toURL() and get the text attribute from the method call.   In one line we fetch the response body.  then we use the XmlParser in Groovy to print out the Repository name, id, and URL.  This script could not be more straightforward.  This post is simply a pointer to the service and a quick demonstration so I&#8217;m not going to dive into the meaning of every single element in the XML document returned by the repositories service.   If you are interested in see the full set of elements that are available, load up the results of this service in a web browser by click on this: <a href="http://repository.sonatype.org/service/local/repositories">http://repository.sonatype.org/service/local/repositories</a>.</p>

<h2>Performing a &#8220;Quick Search&#8221;</h2>


<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> xml <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;http://repository.sonatype.org/service/local/data_index?q=&quot;</span> <span style="color: #66cc66;">+</span> args<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #CC0099;">toURL</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> root <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlParser<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parseText</span><span style="color: #66cc66;">&#40;</span> xml <span style="color: #66cc66;">&#41;</span>
root.<span style="color: #006600;">data</span>.<span style="color: #006600;">artifact</span>.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;${it.groupId.text()}:${it.artifactId.text()}:${it.version.text()}&quot;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>This script follows the pattern of the previous script to list all repositories with the exception that it reads an argument from the command line.   This script performs a quick search by hitting the <em>data_index</em> service and passing in the <em>q</em> parameter.   This script simply prints out the <em>groupId:artifactId:version</em> of all the artifacts located.</p>

<p>If you would like to see an example of the XML that this service produces click here: <a title="http://repository.sonatype.org/service/local/data_index?q=activemq" href="http://repository.sonatype.org/service/local/data_index?q=activemq">http://repository.sonatype.org/service/local/data_index?q=activemq</a>. In the full results, you&#8217;ll see more information such as the number of search hits available, the resource URL for each artifact found, and the context (or repository) in which the artifact is available.</p>

<h2>Searching by Class Name</h2>


<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> xml <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;http://repository.sonatype.org/service/local/data_index?cn=&quot;</span> <span style="color: #66cc66;">+</span> args<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #CC0099;">toURL</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> root <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlParser<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parseText</span><span style="color: #66cc66;">&#40;</span> xml <span style="color: #66cc66;">&#41;</span>
root.<span style="color: #006600;">data</span>.<span style="color: #006600;">artifact</span>.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;${it.groupId.text()}:${it.artifactId.text()}:${it.version.text()}&quot;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>This script is almost exactly the same as the prior script that performed a quick search.  The difference in this script is that instead of passing the q parameter, this script passes the cn parameter.   Passing the cn parameter causes Nexus to search for artifacts which contain classes that match the given value.   The results are going to look the same as the quick search query script.     To see the XML yourself, search for all artifacts which contain a class named HibernateDaoSupport: <a href="http://repository.sonatype.org/service/local/data_index?cn=HibernateDaoSupport">http://repository.sonatype.org/service/local/data_index?cn=HibernateDaoSupport</a>.</p>

<h2>Performing a GAV Search</h2>


<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> xml <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;http://repository.sonatype.org/service/local/data_index?g=${args[0]}&amp;amp;a=${args[1]}&amp;amp;v=${args[2]}&quot;</span>.<span style="color: #CC0099;">toURL</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">text</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">def</span> root <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlParser<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">parseText</span><span style="color: #66cc66;">&#40;</span> xml <span style="color: #66cc66;">&#41;</span>
root.<span style="color: #006600;">data</span>.<span style="color: #006600;">artifact</span>.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;${it.groupId.text()}:${it.artifactId.text()}:${it.version.text()}&quot;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>


<p>This final script takes three command line arguments: groupId, artifactId, version, and it performs a GAV (groupId, artifactId, version) coordinate search over the repository.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2008/11/searching-with-the-sonatype-nexus-rest-api-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Searching with the Sonatype Nexus REST API: Ruby</title>
		<link>http://blog.sonatype.com/people/2008/11/searching-with-the-nexus-rest-api-ruby/</link>
		<comments>http://blog.sonatype.com/people/2008/11/searching-with-the-nexus-rest-api-ruby/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 16:11:49 +0000</pubDate>
		<dc:creator>Tim O'Brien</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Nexus]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://blogs.sonatype.com/people/book/?p=255</guid>
		<description><![CDATA[When you search for artifacts using http://repository.sonatype.org, the browser is querying the Nexus repository using a REST API.   In this post, I&#8217;m going to show you some simple Ruby scripts which you can use to search the Maven repository without loading up the Nexus web interface.  You might find these scripts more convenient and more [...]]]></description>
				<content:encoded><![CDATA[<p><img class="alignright size-thumbnail wp-image-262" src="http://cms.sonatype.com/wordpress/wp-content/uploads/2008/11/scripting-nexus-ruby.png" alt="" width="103" height="102" />When you search for artifacts using <a href="http://repository.sonatype.org">http://repository.sonatype.org</a>, the browser is querying the Nexus repository using a REST API.   In this post, I&#8217;m going to show you some simple Ruby scripts which you can use to search the Maven repository without loading up the Nexus web interface.  You might find these scripts more convenient and more customizable, and you should feel free to copy and modify them for your own use.</p>

<p>The following scripts are in Ruby and they use the <a href="http://www.ruby-doc.org/stdlib/libdoc/rexml/rdoc/index.html">REXML</a> XML processor and the <a href="http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html">Net:HTTP</a> library.  Both of these libraries are available in the Ruby standard library.   I tested these Ruby scripts using the latest <a href="http://jruby.codehaus.org/">JRuby</a> release.  If you want to try these scripts out on your own, they will run in any standard Ruby interpreter without requiring any extra RubyGems.<span id="more-302"></span></p>

<h2>The Nexus REST API</h2>

<p>The UI of Nexus is written in ExtJS and it makes heavy use of AJAX callbacks to REST services.  In fact, if you load up Nexus in a tool like Firebug, an extension for Firefox which allows you to trace all network activity, you will see that almost every action in Nexus triggers a call to a REST service.  We&#8217;re going to focus on just two services in this post: list repositories and searching for artifacts, but you should know that there are hundreds of things you can do to Nexus via the various REST interfaces that are available.  In fact, you could create a custom UI tailored to your own needs that interfaces with Nexus via this REST backend.    In addition to the REST services in the core Nexus installation, you can extend Nexus and add in your own REST services via a Nexus plugin.  The Nexus UI is completely decoupled from the set of services Nexus provides, and the services which Nexus provides can be extended.</p>

<p><a href="http://cms.sonatype.com/wordpress/wp-content/uploads/2008/11/nexus-rest-arch.png"><img class="aligncenter size-full wp-image-263" src="http://cms.sonatype.com/wordpress/wp-content/uploads/2008/11/nexus-rest-arch.png" alt="" width="386" height="201" /></a>The Nexus REST Services are <a href="https://docs.sonatype.com/display/Nx/Nexus+Rest+API">documented here</a>.  In this post, we&#8217;re going to be writing scripts that hit the public instance of Sonatype Nexus at <a href="http://repository.sonatype.org">http://repository.sonatype.org</a>, our REST URLs are going to look something like this: <a href="http://repository.sonatype.org/service/local/data_index?q=maven">http://repository.sonatype.org/service/local/data_index?q=maven</a>.  If you were attempting to hit the services on your local Nexus installation, your REST URL would look more like this: http://localhost:8081/nexus/service/local/data_index?cn=HibernateDaoSupport.   These REST URLs follow the pattern:  &#8220;http://{host}:{port}/{context}/service/{instance}/{service}?{query_params}&#8221; where the {instance} will almost always be &#8220;local&#8221;.</p>

<p>If you would like to download the sample scripts in this blog post, you can download this ZIP file which contains four Ruby scripts: <a href="http://books.sonatype.com/tutorial-files/nexus-rest-ruby.zip">http://books.sonatype.com/tutorial-files/nexus-rest-ruby.zip</a></p>

<h2>Listing Repositories</h2>

<p>The first script simply lists all of the repositories in a Nexus installation.  Here it is:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rexml/document'</span>
<span style="color:#9966CC; font-weight:bold;">include</span> REXML
&nbsp;
url = <span style="color:#996600;">'http://repository.sonatype.org/service/local/repositories'</span>
resp = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get_response</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span> url <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
doc = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> resp.<span style="color:#9900CC;">body</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
XPath.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#40;</span> doc, <span style="color:#996600;">&quot;//repositories-item&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>r<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{r.elements[&quot;</span>name<span style="color:#996600;">&quot;].text}(#{r.elements[&quot;</span>id<span style="color:#996600;">&quot;].text})&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\t</span>&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> r.<span style="color:#9900CC;">elements</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;resourceURI&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">text</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>This script sets the pattern for the scripts to follow.  We construct a URL in the script (a more general script would read this from a config file), then we make the request using Net::HTTP and we parse the results with REXML by passing it to the Document constructor.  At this point, I use XPath to select all of the repositories and I print out the name, id, and the URL of the repository as served by Nexus.</p>

<p>This post is simply a pointer to the service and a quick demonstration so I&#8217;m not going to dive into the meaning of every single element in the XML document returned by the repositories service.   If you are interested in see the full set of elements that are available, load up the results of this service in a web browser by click on this: <a href="http://repository.sonatype.org/service/local/repositories">http://repository.sonatype.org/service/local/repositories</a>.</p>

<h2>Performing a &#8220;Quick Search&#8221;</h2>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rexml/document'</span>
<span style="color:#9966CC; font-weight:bold;">include</span> REXML
&nbsp;
url = <span style="color:#996600;">'http://repository.sonatype.org/service/local/data_index?q='</span>
resp = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get_response</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span> url <span style="color:#006600; font-weight:bold;">+</span> ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
doc = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> resp.<span style="color:#9900CC;">body</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
XPath.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#40;</span> doc, <span style="color:#996600;">&quot;//data/artifact&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>r<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{r.elements[&quot;</span>groupId<span style="color:#996600;">&quot;].text}:#{r.elements[&quot;</span>artifactId<span style="color:#996600;">&quot;].text}:#{r.elem<span style="color:#000099;">\</span>
ents[&quot;</span>version<span style="color:#996600;">&quot;].text}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>This script follows the pattern of the previous script to list all repositories with the exception that it reads an argument from the command line.   This script performs a quick search by hitting the <em>data_index</em> service and passing in the <em>q</em> parameter.   This script simply prints out the <em>groupId:artifactId:version</em> of all the artifacts located.</p>

<p>If you would like to see an example of the XML that this service produces click here: <a title="http://repository.sonatype.org/service/local/data_index?q=activemq" href="http://repository.sonatype.org/service/local/data_index?q=activemq">http://repository.sonatype.org/service/local/data_index?q=activemq</a>. In the full results, you&#8217;ll see more information such as the number of search hits available, the resource URL for each artifact found, and the context (or repository) in which the artifact is available.</p>

<h2>Searching by Class Name</h2>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rexml/document'</span>
<span style="color:#9966CC; font-weight:bold;">include</span> REXML
&nbsp;
url = <span style="color:#996600;">'http://repository.sonatype.org/service/local/data_index?cn='</span>
resp = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get_response</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span> url <span style="color:#006600; font-weight:bold;">+</span> ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
doc = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> resp.<span style="color:#9900CC;">body</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
XPath.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#40;</span> doc, <span style="color:#996600;">&quot;//data/artifact&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>r<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{r.elements[&quot;</span>groupId<span style="color:#996600;">&quot;].text}:#{r.elements[&quot;</span>artifactId<span style="color:#996600;">&quot;].text}:#{r.elem<span style="color:#000099;">\</span>
ents[&quot;</span>version<span style="color:#996600;">&quot;].text}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>This script is almost exactly the same as the prior script that performed a quick search.  The difference in this script is that instead of passing the q parameter, this script passes the cn parameter.   Passing the cn parameter causes Nexus to search for artifacts which contain classes that match the given value.   The results are going to look the same as the quick search query script.     To see the XML yourself, search for all artifacts which contain a class named HibernateDaoSupport: <a href="http://repository.sonatype.org/service/local/data_index?cn=HibernateDaoSupport">http://repository.sonatype.org/service/local/data_index?cn=HibernateDaoSupport</a>.</p>

<h2>Performing a GAV Search</h2>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rexml/document'</span>
<span style="color:#9966CC; font-weight:bold;">include</span> REXML
&nbsp;
url = <span style="color:#996600;">&quot;http://repository.sonatype.org/service/local/data_index?g=#{ARGV[0]}&amp;amp;a=#<span style="color:#000099;">\</span>
{ARGV[1]}&amp;amp;v=#{ARGV[2]}&quot;</span>
resp = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get_response</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span> url <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
doc = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> resp.<span style="color:#9900CC;">body</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
XPath.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#40;</span> doc, <span style="color:#996600;">&quot;//data/artifact&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>r<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{r.elements[&quot;</span>groupId<span style="color:#996600;">&quot;].text}:#{r.elements[&quot;</span>artifactId<span style="color:#996600;">&quot;].text}:#{r.elem<span style="color:#000099;">\</span>
ents[&quot;</span>version<span style="color:#996600;">&quot;].text}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>This final script takes three command line arguments: groupId, artifactId, version, and it performs a GAV (groupId, artifactId, version) coordinate search over the repository.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2008/11/searching-with-the-nexus-rest-api-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
