You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by km...@apache.org on 2013/09/25 22:43:33 UTC

svn commit: r1526295 [3/3] - in /incubator/knox: site/ site/books/knox-incubating-0-3-0/ trunk/books/0.3.0/ trunk/books/common/ trunk/books/static/

Added: incubator/knox/site/project-info.html
URL: http://svn.apache.org/viewvc/incubator/knox/site/project-info.html?rev=1526295&view=auto
==============================================================================
--- incubator/knox/site/project-info.html (added)
+++ incubator/knox/site/project-info.html Wed Sep 25 20:43:32 2013
@@ -0,0 +1,193 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- Generated by Apache Maven Doxia Site Renderer 1.3 at Sep 25, 2013 -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <title>Knox Gateway - Project Information</title>
+    <style type="text/css" media="all">
+      @import url("./css/maven-base.css");
+      @import url("./css/maven-theme.css");
+      @import url("./css/site.css");
+    </style>
+    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
+    <meta name="Date-Revision-yyyymmdd" content="20130925" />
+    <meta http-equiv="Content-Language" content="en" />
+                                                    
+<script type="text/javascript">var _gaq = _gaq || [];
+                _gaq.push(['_setAccount', 'UA-27188762-1']);
+                _gaq.push(['_trackPageview']);
+
+                (function() {
+                var ga = document.createElement('script');
+                ga.type = 'text/javascript'; ga.async = true;
+                ga.src = ('https:' == document.location.protocol ?
+                'https://ssl' : 'http://www') +
+                '.google-analytics.com/ga.js';
+                var s = document.getElementsByTagName('script')[0];
+                s.parentNode.insertBefore(ga, s);
+                })();</script>
+                      
+        </head>
+  <body class="composite">
+    <div id="banner">
+                                      <a href="./" id="bannerLeft">
+                                                <img src="images/apache-logo.gif" alt="Knox Gateway" />
+                </a>
+                                            <a href=".." id="bannerRight">
+                                                <img src="images/apache-incubator-logo.png" alt="Apache Incubator" />
+                </a>
+            <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+            
+                    
+                <div class="xleft">
+                                  <a href="index.html" title="Knox">Knox</a>
+        &gt;
+    Project Information
+      </div>
+            <div class="xright">                    <a href="https://git-wip-us.apache.org/repos/asf/incubator-knox.git" class="externalLink" title="Git">Git</a>
+            |
+                        <a href="https://svn.apache.org/repos/asf/incubator/knox" class="externalLink" title="Svn">Svn</a>
+            |
+                        <a href="https://issues.apache.org/jira/browse/KNOX" class="externalLink" title="Jira">Jira</a>
+            |
+                        <a href="https://cwiki.apache.org/confluence/display/KNOX/Index" class="externalLink" title="Wiki">Wiki</a>
+              
+                    
+                &nbsp;| <span id="publishDate">Last Published: 2013-09-25</span>
+              &nbsp;| <span id="projectVersion">Version: 0.0.0-SNAPSHOT</span>
+            </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+             
+                    
+                                <h5>Knox</h5>
+                  <ul>
+                  <li class="none">
+                          <a href="index.html" title="Home">Home</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/News" class="externalLink" title="News">News</a>
+            </li>
+                  <li class="none">
+                          <a href="license.html" title="License">License</a>
+            </li>
+          </ul>
+                       <h5>Documentation</h5>
+                  <ul>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Getting+Started" class="externalLink" title="Getting Started">Getting Started</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Examples" class="externalLink" title="Usage Examples">Usage Examples</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Client+Usage" class="externalLink" title="Client (KnoxShell DSL)">Client (KnoxShell DSL)</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Sandbox+Configuration" class="externalLink" title="Sandbox Configuration">Sandbox Configuration</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Dependencies" class="externalLink" title="Dependencies">Dependencies</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Index" class="externalLink" title="Wiki">Wiki</a>
+            </li>
+          </ul>
+                       <h5>Releases</h5>
+                  <ul>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Release+0.2.0" class="externalLink" title="0.2.0">0.2.0</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Roadmap" class="externalLink" title="Roadmap">Roadmap</a>
+            </li>
+          </ul>
+                       <h5>Processes</h5>
+                  <ul>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Build+Process" class="externalLink" title="Build">Build</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Release+Process" class="externalLink" title="Release">Release</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Contribution+Process" class="externalLink" title="Contribute">Contribute</a>
+            </li>
+                  <li class="none">
+                          <a href="https://cwiki.apache.org/confluence/display/KNOX/Site+Maintenance" class="externalLink" title="Site Maintenance">Site Maintenance</a>
+            </li>
+          </ul>
+                       <h5>Resources</h5>
+                  <ul>
+                  <li class="none">
+                          <a href="https://git-wip-us.apache.org/repos/asf/incubator-knox.git" class="externalLink" title="Product Source">Product Source</a>
+            </li>
+                  <li class="none">
+                          <a href="https://svn.apache.org/repos/asf/incubator/knox" class="externalLink" title="Site Source">Site Source</a>
+            </li>
+                  <li class="none">
+                          <a href="team-list.html" title="Project Team">Project Team</a>
+            </li>
+                  <li class="none">
+                          <a href="mail-lists.html" title="Mailing Lists">Mailing Lists</a>
+            </li>
+                  <li class="none">
+                          <a href="issue-tracking.html" title="Issue Tracking">Issue Tracking</a>
+            </li>
+          </ul>
+                       <h5>ASF</h5>
+                  <ul>
+                  <li class="none">
+                          <a href="http://www.apache.org/foundation/how-it-works.html" class="externalLink" title="How Apache Works">How Apache Works</a>
+            </li>
+                  <li class="none">
+                          <a href="http://www.apache.org/foundation/" class="externalLink" title="Foundation">Foundation</a>
+            </li>
+                  <li class="none">
+                          <a href="http://www.apache.org/foundation/sponsorship.html" class="externalLink" title="Sponsoring Apache">Sponsoring Apache</a>
+            </li>
+                  <li class="none">
+                          <a href="http://www.apache.org/foundation/thanks.html" class="externalLink" title="Thanks">Thanks</a>
+            </li>
+          </ul>
+                             <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
+        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
+      </a>
+                   
+                    
+            </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+        <div class="section"><h2>Project Information<a name="Project_Information"></a></h2><p>This document provides an overview of the various documents and links that are part of this project's general information. All of this content is automatically generated by <a class="externalLink" href="http://maven.apache.org">Maven</a> on behalf of the project.</p><div class="section"><h3>Overview<a name="Overview"></a></h3><table border="0" class="bodyTable"><tr class="a"><th>Document</th><th>Description</th></tr><tr class="b"><td><a href="index.html">About</a></td><td>Knox is a gateway for Hadoop clusters.</td></tr><tr class="a"><td><a href="team-list.html">Project Team</a></td><td>This document provides information on the members of this project. These are the individuals who have contributed to the project in one form or another.</td></tr><tr class="b"><td><a href="mail-lists.html">Mailing Lists</a></td><td>This document provides subscription and archive information for this project's
  mailing lists.</td></tr><tr class="a"><td><a href="issue-tracking.html">Issue Tracking</a></td><td>This is a link to the issue management system for this project. Issues (bugs, features, change requests) can be created and queried using this link.</td></tr><tr class="b"><td><a href="license.html">Project License</a></td><td>This is a link to the definitions of project licenses.</td></tr></table></div></div>
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">
+              <?xml version="1.0" encoding="UTF-8"?>
+<footer>
+  <div class="row span12">Apache Knox Gateway, Apache, the Apache feather logo and the Apache Knox Gateway project logos
+                are trademarks of The Apache Software Foundation.
+                All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div>
+  <div class="row span12">
+    <a href="https://cwiki.apache.org/confluence/display/KNOX/Privacy+Policy">Privacy Policy</a>
+  </div>
+</footer>
+            </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>

Modified: incubator/knox/trunk/books/0.3.0/book.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/book.md?rev=1526295&r1=1526294&r2=1526295&view=diff
==============================================================================
--- incubator/knox/trunk/books/0.3.0/book.md (original)
+++ incubator/knox/trunk/books/0.3.0/book.md Wed Sep 25 20:43:32 2013
@@ -33,6 +33,8 @@ Table Of Contents
 * [Gateway Details](#Gateway+Details)
     * [Authentication](#Authentication)
     * [Authorization](#Authorization)
+    * [Configuration](#Configuration)
+* [Client Details](#Client+Details)
 * [Service Details](#Service+Details)
     * [WebHDFS](#WebHDFS)
     * [WebHCat/Templeton](#WebHCat)
@@ -51,14 +53,39 @@ Table Of Contents
 TODO
 
 
+{{Requirements}}
+----------------
+
+### Java ###
+
+Java 1.6 or later is required for the Knox Gateway runtime.
+Use the command below to check the version of Java installed on the system where Knox will be running.
+
+{code}
+java -version
+{code}
+
+### Hadoop ###
+
+An an existing Hadoop 1.x or 2.x cluster is required for Knox to protect.
+One of the easiest ways to ensure this it to utilize a HDP Sandbox VM.
+It is possible to use a Hadoop cluster deployed on EC2 but this will require additional configuration.
+Currently if this Hadoop cluster is secured with Kerberos only WebHDFS will work and additional configuration is required.
+
+The Hadoop cluster should be ensured to have at least WebHDFS, WebHCat (i.e. Templeton) and Oozie configured, deployed and running.
+HBase/Stargate and Hive can also be accessed via the Knox Gateway given the proper versions and configuration.
+
+The instructions that follow assume that the Gateway is *not* collocated with the Hadoop clusters themselves and (most importantly) that the hostnames and IP addresses of the cluster services are accessible by the gateway where ever it happens to be running.
+All of the instructions and samples are tailored to work "out of the box" against a Hortonworks Sandbox 2.x VM.
+
+This release of the Apache Knox Gateway has been tested against the [Hortonworks Sandbox 2.0](http://hortonworks.com/products/hortonworks-sandbox/).
+
+
 {{Download}}
 ------------
 
-TODO
-
-| ![$] Important |
-| -------------- |
-| Please ensure that you validate the integrity of any downloaded files as described [below](#Release+Verification). |
+Download and extract the knox-\{VERSION\}.zip}} file into the installation directory that will contain your {{\{GATEWAY_HOME\}}}.
+You can find the downloads for Knox releases on the [Apache mirrors|http://www.apache.org/dyn/closer.cgi/incubator/knox/].
 
 * Source archive: [knox-incubating-0.3.0-src.zip][src-zip] ([PGP signature][src-pgp], [SHA1 digest][src-sha], [MD5 digest][src-md5])
 * Binary archive: [knox-incubating-0.3.0.zip][bin-zip] ([PGP signature][bin-pgp], [SHA1 digest][bin-sha], [MD5 digest][bin-md5])
@@ -72,32 +99,16 @@ TODO
 [bin-sha]: http://www.apache.org/dist/incubator/knox/0.3.0/knox-incubating-0.3.0.zip.sha
 [bin-md5]: http://www.apache.org/dist/incubator/knox/0.3.0/knox-incubating-0.3.0.zip.md5
 
+| ![$] Important |
+| -------------- |
+| Please ensure that you validate the integrity of any downloaded files as described [below](#Release+Verification). |
+
 Apache Knox Gateway releases are available under the [Apache License, Version 2.0][asl].
 See the NOTICE file contained in each release artifact for applicable copyright attribution notices.
 
 
-{{Installation}}
-----------------
-
-### ZIP ###
-
-TODO
-
-
-### RPM ###
-
-TODO
-
-
-### Layout ###
-
-TODO - Describe the purpose of all of the directories
-
-
-{{Getting Started}}
--------------------
-
-TODO
+<<install.md>>
+<<using.md>>
 
 
 {{Supported Services}}
@@ -128,15 +139,17 @@ These examples provide more detail about
 * [HBase](#HBase+Examples)
 * [Hive](#Hive+Examples)
 
+<<config.md>>
 
 {{Gateway Details}}
 -------------------
 
 TODO
 
+<<config.md>>
 <<authn.md>>
 <<authz.md>>
-
+<<client.md>>
 
 {{Service Details}}
 -------------------

Added: incubator/knox/trunk/books/0.3.0/client.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/client.md?rev=1526295&view=auto
==============================================================================
--- incubator/knox/trunk/books/0.3.0/client.md (added)
+++ incubator/knox/trunk/books/0.3.0/client.md Wed Sep 25 20:43:32 2013
@@ -0,0 +1,660 @@
+<!---
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+--->
+
+{{Client Details}}
+------------------
+
+Hadoop requires a client that can be used to interact remotely with the services provided by Hadoop cluster.
+This will also be true when using the Apache Knox Gateway to provide perimeter security and centralized access for these services.
+The two primary existing clients for Hadoop are the CLI (i.e. Command Line Interface, hadoop) and HUE (i.e. Hadoop User Environment).
+for several reasons however, neither of these clients can _currently_ be used to access Hadoop services via the Apache Knox Gateway.
+
+This lead to thinking about a very simple client that could help people use and evaluate the gateway.
+The list below outline the general requirements for such a client.
+
+* Promote the evaluation and adoption of the Apache Knox Gateway
+* Simple to deploy and use on data worker desktops to access to remote Hadoop clusters
+* Simple to extend with new commands both by other Hadoop projects and by the end user
+* Support the notion of a SSO session for multiple Hadoop interactions
+* Support the multiple authentication and federation token capabilities of the Apache Knox Gateway
+* Promote the use of REST APIs as the dominant remote client mechanism for Hadoop services
+* Promote the the sense of Hadoop as a single unified product
+* Aligned with the Apache Knox Gateway's overall goals for security
+
+The result is a very simple DSL ([Domain Specific Language](http://en.wikipedia.org/wiki/Domain-specific_language)) of sorts that is used via [Groovy](http://groovy.codehaus.org) scripts.
+Here is an example of a command that copies a file from the local file system to HDFS.
+_Note: The variables session, localFile and remoteFile are assumed to be defined._
+
+    Hdfs.put( session ).file( localFile ).to( remoteFile ).now()
+
+*This work is very early in development but is also very useful in its current state.*
+*We are very interested in receiving feedback about how to improve this feature and the DSL in particular.*
+
+A note of thanks to [REST-assured](https://code.google.com/p/rest-assured/) which provides a [Fluent interface](http://en.wikipedia.org/wiki/Fluent_interface) style DSL for testing REST services.
+It served as the initial inspiration for the creation of this DSL.
+
+
+### Assumptions ###
+
+This document assumes a few things about your environment in order to simplify the examples.
+
+* The JVM is executable as simply java.
+* The Apache Knox Gateway is installed and functional.
+* The example commands are executed within the context of the GATEWAY_HOME current directory.
+The GATEWAY_HOME directory is the directory within the Apache Knox Gateway installation that contains the README file and the bin, conf and deployments directories.
+* A few examples require the use of commands from a standard Groovy installation.  These examples are optional but to try them you will need Groovy [installed](http://groovy.codehaus.org/Installing+Groovy).
+
+
+### Assumptions ###
+
+The DSL requires a shell to interpret the Groovy script.
+The shell can either be used interactively or to execute a script file.
+To simplify use, the distribution contains an embedded version of the Groovy shell.
+
+The shell can be run interactively.  Use the command `exit` to exit.
+
+    java -jar bin/shell.jar
+
+When running interactively it may be helpful to reduce some of the output generated by the shell console.
+Use the following command in the interactive shell to reduce that output.
+This only needs to be done once as these preferences are persisted.
+
+    set verbosity QUIET
+    set show-last-result false
+
+Also when running interactively use the `exit` command to terminate the shell.
+Using `^C` to exit can sometimes leaves the parent shell in a problematic state.
+
+The shell can also be used to execute a script by passing a single filename argument.
+
+    java -jar bin/shell.jar samples/ExamplePutFile.groovy
+
+
+### Examples ###
+
+Once the shell can be launched the DSL can be used to interact with the gateway and Hadoop.
+Below is a very simple example of an interactive shell session to upload a file to HDFS.
+
+    java -jar bin/shell.jar
+    knox:000> hadoop = Hadoop.login( "https://localhost:8443/gateway/sample", "bob", "bob-password" )
+    knox:000> Hdfs.put( hadoop ).file( "README" ).to( "/tmp/example/README" ).now()
+
+The `knox:000>` in the example above is the prompt from the embedded Groovy console.
+If you output doesn't look like this you may need to set the verbosity and show-last-result preferences as described above in the Usage section.
+
+If you relieve an error `HTTP/1.1 403 Forbidden` it may be because that file already exists.
+Try deleting it with the following command and then try again.
+
+    knox:000> Hdfs.rm(hadoop).file("/tmp/example/README").now()
+
+Without using some other tool to browse HDFS it is hard to tell that that this command did anything.
+Execute this to get a bit more feedback.
+
+    knox:000> println "Status=" + Hdfs.put( hadoop ).file( "README" ).to( "/tmp/example/README2" ).now().statusCode
+    Status=201
+
+Notice that a different filename is used for the destination.
+Without this an error would have resulted.
+Of course the DSL also provides a command to list the contents of a directory.
+
+    knox:000> println Hdfs.ls( hadoop ).dir( "/tmp/example" ).now().string
+    {"FileStatuses":{"FileStatus":[{"accessTime":1363711366977,"blockSize":134217728,"group":"hdfs","length":19395,"modificationTime":1363711366977,"owner":"bob","pathSuffix":"README","permission":"644","replication":1,"type":"FILE"},{"accessTime":1363711375617,"blockSize":134217728,"group":"hdfs","length":19395,"modificationTime":1363711375617,"owner":"bob","pathSuffix":"README2","permission":"644","replication":1,"type":"FILE"}]}}
+
+It is a design decision of the DSL to not provide type safe classes for various request and response payloads.
+Doing so would provide an undesirable coupling between the DSL and the service implementation.
+It also would make adding new commands much more difficult.
+See the Groovy section below for a variety capabilities and tools for working with JSON and XML to make this easy.
+The example below shows the use of JsonSlurper and GPath to extract content from a JSON response.
+
+    knox:000> import groovy.json.JsonSlurper
+    knox:000> text = Hdfs.ls( hadoop ).dir( "/tmp/example" ).now().string
+    knox:000> json = (new JsonSlurper()).parseText( text )
+    knox:000> println json.FileStatuses.FileStatus.pathSuffix
+    [README, README2]
+
+*In the future, "built-in" methods to slurp JSON and XML may be added to make this a bit easier.*
+*This would allow for this type if single line interaction.*
+
+    println Hdfs.ls(hadoop).dir("/tmp").now().json().FileStatuses.FileStatus.pathSuffix
+
+Shell session should always be ended with shutting down the session.
+The examples above do not touch on it but the DSL supports the simple execution of commands asynchronously.
+The shutdown command attempts to ensures that all asynchronous commands have completed before existing the shell.
+
+    knox:000> hadoop.shutdown()
+    knox:000> exit
+
+All of the commands above could have been combined into a script file and executed as a single line.
+
+    java -jar bin/shell.jar samples/ExamplePutFile.groovy
+
+This script file is available in the distribution but for convenience, this is the content.
+
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.hadoop.gateway.shell.hdfs.Hdfs
+    import groovy.json.JsonSlurper
+    
+    gateway = "https://localhost:8443/gateway/sample"
+    username = "bob"
+    password = "bob-password"
+    dataFile = "README"
+    
+    hadoop = Hadoop.login( gateway, username, password )
+    Hdfs.rm( hadoop ).file( "/tmp/example" ).recursive().now()
+    Hdfs.put( hadoop ).file( dataFile ).to( "/tmp/example/README" ).now()
+    text = Hdfs.ls( hadoop ).dir( "/tmp/example" ).now().string
+    json = (new JsonSlurper()).parseText( text )
+    println json.FileStatuses.FileStatus.pathSuffix
+    hadoop.shutdown()
+    exit
+
+Notice the `Hdfs.rm` command.  This is included simply to ensure that the script can be rerun.
+Without this an error would result the second time it is run.
+
+
+### Futures ###
+
+The DSL supports the ability to invoke commands asynchronously via the later() invocation method.
+The object returned from the later() method is a java.util.concurrent.Future parametrized with the response type of the command.
+This is an example of how to asynchronously put a file to HDFS.
+
+    future = Hdfs.put(hadoop).file("README").to("tmp/example/README").later()
+    println future.get().statusCode
+
+The future.get() method will block until the asynchronous command is complete.
+To illustrate the usefulness of this however multiple concurrent commands are required.
+
+    readmeFuture = Hdfs.put(hadoop).file("README").to("tmp/example/README").later()
+    licenseFuture = Hdfs.put(hadoop).file("LICENSE").to("tmp/example/LICENSE").later()
+    hadoop.waitFor( readmeFuture, licenseFuture )
+    println readmeFuture.get().statusCode
+    println licenseFuture.get().statusCode
+
+The hadoop.waitFor() method will wait for one or more asynchronous commands to complete.
+
+
+### Closures ###
+
+Futures alone only provide asynchronous invocation of the command.
+What if some processing should also occur asynchronously once the command is complete.
+Support for this is provided by closures.
+Closures are blocks of code that are passed into the later() invocation method.
+In Groovy these are contained within {} immediately after a method.
+These blocks of code are executed once the asynchronous command is complete.
+
+    Hdfs.put(hadoop).file("README").to("tmp/example/README").later(){ println it.statusCode }
+
+In this example the put() command is executed on a separate thread and once complete the `println it.statusCode` block is executed on that thread.
+The it variable is automatically populated by Groovy and is a reference to the result that is returned from the future or now() method.
+The future example above can be rewritten to illustrate the use of closures.
+
+    readmeFuture = Hdfs.put(hadoop).file("README").to("tmp/example/README").later() { println it.statusCode }
+    licenseFuture = Hdfs.put(hadoop).file("LICENSE").to("tmp/example/LICENSE").later() { println it.statusCode }
+    hadoop.waitFor( readmeFuture, licenseFuture )
+
+Again, the hadoop.waitFor() method will wait for one or more asynchronous commands to complete.
+
+
+### Constructs ###
+
+In order to understand the DSL there are three primary constructs that need to be understood.
+
+
+### Hadoop ###
+
+This construct encapsulates the client side session state that will be shared between all command invocations.
+In particular it will simplify the management of any tokens that need to be presented with each command invocation.
+It also manages a thread pool that is used by all asynchronous commands which is why it is important to call one of the shutdown methods.
+
+The syntax associated with this is expected to change we expect that credentials will not need to be provided to the gateway.
+Rather it is expected that some form of access token will be used to initialize the session.
+
+
+### Services ###
+
+Services are the primary extension point for adding new suites of commands.
+The built in examples are: Hdfs, Job and Workflow.
+The desire for extensibility is the reason for the slightly awkward Hdfs.ls(hadoop) syntax.
+Certainly something more like `hadoop.hdfs().ls()` would have been preferred but this would prevent adding new commands easily.
+At a minimum it would result in extension commands with a different syntax from the "built-in" commands.
+
+The service objects essentially function as a factory for a suite of commands.
+
+
+### Commands ###
+
+Commands provide the behavior of the DSL.
+They typically follow a Fluent interface style in order to allow for single line commands.
+There are really three parts to each command: Request, Invocation, Response
+
+
+### Request ###
+
+The request is populated by all of the methods following the "verb" method and the "invoke" method.
+For example in `Hdfs.rm(hadoop).ls(dir).now()` the request is populated between the "verb" method `rm()` and the "invoke" method `now()`.
+
+
+### Invocation ###
+
+The invocation method controls how the request is invoked.
+Currently supported synchronous and asynchronous invocation.
+The now() method executes the request and returns the result immediately.
+The later() method submits the request to be executed later and returns a future from which the result can be retrieved.
+In addition later() invocation method can optionally be provided a closure to execute when the request is complete.
+See the Futures and Closures sections below for additional detail and examples.
+
+
+### Response ###
+
+The response contains the results of the invocation of the request.
+In most cases the response is a thin wrapper over the HTTP response.
+In fact many commands will share a single BasicResponse type that only provides a few simple methods.
+
+    public int getStatusCode()
+    public long getContentLength()
+    public String getContentType()
+    public String getContentEncoding()
+    public InputStream getStream()
+    public String getString()
+    public byte[] getBytes()
+    public void close();
+
+Thanks to Groovy these methods can be accessed as attributes.
+In the some of the examples the staticCode was retrieved for example.
+
+    println Hdfs.put(hadoop).rm(dir).now().statusCode
+
+Groovy will invoke the getStatusCode method to retrieve the statusCode attribute.
+
+The three methods getStream(), getBytes() and getString deserve special attention.
+Care must be taken that the HTTP body is read only once.
+Therefore one of these methods (and only one) must be called once and only once.
+Calling one of these more than once will cause an error.
+Failing to call one of these methods once will result in lingering open HTTP connections.
+The close() method may be used if the caller is not interested in reading the result body.
+Most commands that do not expect a response body will call close implicitly.
+If the body is retrieved via getBytes() or getString(), the close() method need not be called.
+When using getStream(), care must be taken to consume the entire body otherwise lingering open HTTP connections will result.
+The close() method may be called after reading the body partially to discard the remainder of the body.
+
+
+### Services ###
+
+There are three basic DSL services and commands bundled with the shell.
+
+
+#### HDFS ####
+
+Provides basic HDFS commands.
+*Using these DSL commands requires that WebHDFS be running in the Hadoop cluster.*
+
+#### Jobs (Templeton/WebHCat) ####
+
+Provides basic job submission and status commands.
+*Using these DSL commands requires that Templeton/WebHCat be running in the Hadoop cluster.*
+
+
+#### Workflow (Oozie) ####
+
+Provides basic workflow submission and status commands.
+*Using these DSL commands requires that Oozie be running in the Hadoop cluster.*
+
+
+### HDFS Commands (WebHDFS) ###
+
+#### ls() - List the contents of a HDFS directory.
+
+* Request
+    * dir (String) - The HDFS directory to list.
+* Response
+    * BasicResponse
+* Example
+    * `Hdfs.ls(hadoop).ls().dir("/").now()`
+
+#### rm() - Remove a HDFS file or directory.
+
+* Request
+    * file (String) - The HDFS file or directory to remove.
+    * recursive (Boolean) - If the file is a directory also remove any contained files and directories. Optional: default=false
+* Response
+    * EmptyResponse - Implicit close().
+* Example
+    * `Hdfs.rm(hadoop).file("/tmp/example").recursive().now()`
+
+#### put() - Copy a file from the local file system to HDFS.
+
+* Request
+    * text (String) - The text to copy to the remote file.
+    * file (String) - The name of a local file to copy to the remote file.
+    * to (String) - The name of the remote file create.
+* Response
+    * EmptyResponse - Implicit close().
+* Example
+    * `Hdfs.put(hadoop).file("localFile").to("/tmp/example/remoteFile").now()`
+
+#### get() - Copy a file from HDFS to the local file system.
+
+* Request
+    * file (String) - The name of the local file to create from the remote file.  If this isn't specified the file content must be read from the response.
+    * from (String) - The name of the remote file to copy.
+* Response
+    * BasicResponse
+* Example
+    * `Hdfs.get(hadoop).file("localFile").from("/tmp/example/remoteFile").now()`
+
+#### mkdir() - Create a directory in HDFS.
+
+* Request
+    * dir (String) - The name of the remote directory to create.
+    * perm (String) - The permissions to create the remote directory with.  Optional: default="777"
+* Response
+    * EmptyResponse - Implicit close().
+* Example
+    * `Hdfs.mkdir(hadoop).dir("/tmp/example").perm("777").now()`
+
+
+### Job Commands (WebHCat/Templeton)
+
+#### submitJava() - Submit a Java MapReduce job.
+
+* Request
+    * jar (String) - The remote file name of the JAR containing the app to execute.
+    * app (String) - The app name to execute.  This is wordcount for example not the class name.
+    * input (String) - The remote directory name to use as input for the job.
+    * output (String) - The remote directory name to store output from the job.
+* Response
+    * jobId : String - The job ID of the submitted job.  Consumes body.
+* Example
+    * `Job.submitJava(hadoop).jar(remoteJarName).app(appName).input(remoteInputDir).output(remoteOutputDir).now().jobId`
+
+#### submitPig() - Submit a Pig job.
+
+* Request
+    * file (String) - The remote file name of the pig script.
+    * arg (String) - An argument to pass to the script.
+    * statusDir (String) - The remote directory to store status output.
+* Response
+    * jobId : String - The job ID of the submitted job.  Consumes body.
+* Example
+    * `Job.submitPig(hadoop).file(remotePigFileName).arg("-v").statusDir(remoteStatusDir).now()`
+
+#### submitHive() - Submit a Hive job.
+
+* Request
+    * file (String) - The remote file name of the hive script.
+    * arg (String) - An argument to pass to the script.
+    * statusDir (String) - The remote directory to store status output.
+* Response
+    * jobId : String - The job ID of the submitted job.  Consumes body.
+* Example
+    * `Job.submitHive(hadoop).file(remoteHiveFileName).arg("-v").statusDir(remoteStatusDir).now()`
+
+#### queryQueue() - Return a list of all job IDs registered to the user.
+
+* Request
+    * No request parameters.
+* Response
+    * BasicResponse
+* Example
+    * `Job.queryQueue(hadoop).now().string`
+
+#### queryStatus() - Check the status of a job and get related job information given its job ID.
+
+* Request
+    * jobId (String) - The job ID to check. This is the ID received when the job was created.
+* Response
+    * BasicResponse
+* Example
+    * `Job.queryStatus(hadoop).jobId(jobId).now().string`
+
+
+### Workflow Commands (Oozie) ###
+
+#### submit() - Submit a workflow job.
+
+* Request
+    * text (String) - XML formatted workflow configuration string.
+    * file (String) - A filename containing XML formatted workflow configuration.
+    * action (String) - The initial action to take on the job.  Optional: Default is "start".
+* Response
+    * BasicResponse
+* Example
+    * `Workflow.submit(hadoop).file(localFile).action("start").now()`
+
+#### status() - Query the status of a workflow job.
+
+* Request
+    * jobId (String) - The job ID to check. This is the ID received when the job was created.
+* Response
+    * BasicResponse
+* Example
+    * `Workflow.status(hadoop).jobId(jobId).now().string`
+
+
+### Extension ###
+
+Extensibility is a key design goal of the KnoxShell and DSL.
+There are two ways to provide extended functionality for use with the shell.
+The first is to simply create Groovy scripts that use the DSL to perform a useful task.
+The second is to add new services and commands.
+In order to add new service and commands new classes must be written in either Groovy or Java and added to the classpath of the shell.
+Fortunately there is a very simple way to add classes and JARs to the shell classpath.
+The first time the shell is executed it will create a configuration file in the same directory as the JAR with the same base name and a `.cfg` extension.
+
+    bin/shell.jar
+    bin/shell.cfg
+
+That file contains both the main class for the shell as well as a definition of the classpath.
+Currently that file will by default contain the following.
+
+    main.class=org.apache.hadoop.gateway.shell.Shell
+    class.path=../lib; ../lib/*.jar; ../ext; ../ext/*.jar
+
+Therefore to extend the shell you should copy any new service and command class either to the `ext` directory or if they are packaged within a JAR copy the JAR to the `ext` directory.
+The `lib` directory is reserved for JARs that may be delivered with the product.
+
+Below are samples for the service and command classes that would need to be written to add new commands to the shell.
+These happen to be Groovy source files but could with very minor changes be Java files.
+The easiest way to add these to the shell is to compile them directory into the `ext` directory.
+*Note: This command depends upon having the Groovy compiler installed and available on the execution path.*
+
+    groovyc \-d ext \-cp bin/shell.jar samples/SampleService.groovy samples/SampleSimpleCommand.groovy samples/SampleComplexCommand.groovy
+
+These source files are available in the samples directory of the distribution but these are included here for convenience.
+
+#### Sample Service (Groovy)
+
+    import org.apache.hadoop.gateway.shell.Hadoop
+
+    class SampleService {
+
+        static String PATH = "/namenode/api/v1"
+
+        static SimpleCommand simple( Hadoop hadoop ) {
+            return new SimpleCommand( hadoop )
+        }
+
+        static ComplexCommand.Request complex( Hadoop hadoop ) {
+            return new ComplexCommand.Request( hadoop )
+        }
+
+    }
+
+#### Sample Simple Command (Groovy)
+
+    import org.apache.hadoop.gateway.shell.AbstractRequest
+    import org.apache.hadoop.gateway.shell.BasicResponse
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.http.client.methods.HttpGet
+    import org.apache.http.client.utils.URIBuilder
+
+    import java.util.concurrent.Callable
+
+    class SimpleCommand extends AbstractRequest<BasicResponse> {
+
+        SimpleCommand( Hadoop hadoop ) {
+            super( hadoop )
+        }
+
+        private String param
+        SimpleCommand param( String param ) {
+            this.param = param
+            return this
+        }
+
+        @Override
+        protected Callable<BasicResponse> callable() {
+            return new Callable<BasicResponse>() {
+                @Override
+                BasicResponse call() {
+                    URIBuilder uri = uri( SampleService.PATH, param )
+                    addQueryParam( uri, "op", "LISTSTATUS" )
+                    HttpGet get = new HttpGet( uri.build() )
+                    return new BasicResponse( execute( get ) )
+                }
+            }
+        }
+
+    }
+
+#### Sample Complex Command (Groovy)
+
+    import com.jayway.jsonpath.JsonPath
+    import org.apache.hadoop.gateway.shell.AbstractRequest
+    import org.apache.hadoop.gateway.shell.BasicResponse
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.http.HttpResponse
+    import org.apache.http.client.methods.HttpGet
+    import org.apache.http.client.utils.URIBuilder
+
+    import java.util.concurrent.Callable
+
+    class ComplexCommand {
+
+        static class Request extends AbstractRequest<Response> {
+
+            Request( Hadoop hadoop ) {
+                super( hadoop )
+            }
+
+            private String param;
+            Request param( String param ) {
+                this.param = param;
+                return this;
+            }
+
+            @Override
+            protected Callable<Response> callable() {
+                return new Callable<Response>() {
+                    @Override
+                    Response call() {
+                        URIBuilder uri = uri( SampleService.PATH, param )
+                        addQueryParam( uri, "op", "LISTSTATUS" )
+                        HttpGet get = new HttpGet( uri.build() )
+                        return new Response( execute( get ) )
+                    }
+                }
+            }
+
+        }
+
+        static class Response extends BasicResponse {
+
+            Response(HttpResponse response) {
+                super(response)
+            }
+
+            public List<String> getNames() {
+                return JsonPath.read( string, "\$.FileStatuses.FileStatus[*].pathSuffix" )
+            }
+
+        }
+
+    }
+
+### Groovy
+
+The shell included in the distribution is basically an unmodified packaging of the Groovy shell.
+The distribution does however provide a wrapper that makes it very easy to setup the class path for the shell.
+In fact the JARs required to execute the DSL are included on the class path by default.
+Therefore these command are functionally equivalent if you have Groovy [installed][15].
+See below for a description of what is required for JARs required by the DSL from `lib` and `dep` directories.
+
+    java -jar bin/shell.jar samples/ExamplePutFile.groovy
+    groovy -classpath {JARs required by the DSL from lib and dep} samples/ExamplePutFile.groovy
+
+The interactive shell isn't exactly equivalent.
+However the only difference is that the shell.jar automatically executes some additional imports that are useful for the KnoxShell DSL.
+So these two sets of commands should be functionality equivalent.
+*However there is currently a class loading issue that prevents the groovysh command from working propertly.*
+
+    java -jar bin/shell.jar
+
+    groovysh -classpath {JARs required by the DSL from lib and dep}
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.hadoop.gateway.shell.hdfs.Hdfs
+    import org.apache.hadoop.gateway.shell.job.Job
+    import org.apache.hadoop.gateway.shell.workflow.Workflow
+    import java.util.concurrent.TimeUnit
+
+Alternatively, you can use the Groovy Console which does not appear to have the same class loading issue.
+
+    groovyConsole -classpath {JARs required by the DSL from lib and dep}
+
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.hadoop.gateway.shell.hdfs.Hdfs
+    import org.apache.hadoop.gateway.shell.job.Job
+    import org.apache.hadoop.gateway.shell.workflow.Workflow
+    import java.util.concurrent.TimeUnit
+
+The list of JARs currently required by the DSL is
+
+    lib/gateway-shell-${gateway-version}.jar
+    dep/httpclient-4.2.3.jar
+    dep/httpcore-4.2.2.jar
+    dep/commons-lang3-3.1.jar
+    dep/commons-codec-1.7.jar
+
+So on Linux/MacOS you would need this command
+
+    groovy -cp lib/gateway-shell-0.2.0-SNAPSHOT.jar:dep/httpclient-4.2.3.jar:dep/httpcore-4.2.2.jar:dep/commons-lang3-3.1.jar:dep/commons-codec-1.7.jar samples/ExamplePutFile.groovy
+
+and on Windows you would need this command
+
+    groovy -cp lib/gateway-shell-0.2.0-SNAPSHOT.jar;dep/httpclient-4.2.3.jar;dep/httpcore-4.2.2.jar;dep/commons-lang3-3.1.jar;dep/commons-codec-1.7.jar samples/ExamplePutFile.groovy
+
+The exact list of required JARs is likely to change from release to release so it is recommended that you utilize the wrapper `bin/shell.jar`.
+
+In addition because the DSL can be used via standard Groovy, the Groovy integrations in many popular IDEs (e.g. IntelliJ , Eclipse) can also be used.
+This makes it particularly nice to develop and execute scripts to interact with Hadoop.
+The code-completion feature in particular provides immense value.
+All that is required is to add the shell-0.2.0.jar to the projects class path.
+
+There are a variety of Groovy tools that make it very easy to work with the standard interchange formats (i.e. JSON and XML).
+In Groovy the creation of XML or JSON is typically done via a "builder" and parsing done via a "slurper".
+In addition once JSON or XML is "slurped" the GPath, an XPath like feature build into Groovy can be used to access data.
+
+* XML
+    * Markup Builder [Overview]http://groovy.codehaus.org/Creating+XML+using+Groovy's+MarkupBuilder), [API](http://groovy.codehaus.org/api/groovy/xml/MarkupBuilder.html)
+    * XML Slurper [Overview]http://groovy.codehaus.org/Reading+XML+using+Groovy's+XmlSlurper), [API](http://groovy.codehaus.org/api/groovy/util/XmlSlurper.html)
+    * XPath [Overview]http://groovy.codehaus.org/GPath), [API](http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/xpath/XPath.html)
+* JSON
+    * JSON Builder [API](http://groovy.codehaus.org/gapi/groovy/json/JsonBuilder.html)
+    * JSON Slurper [API](http://groovy.codehaus.org/gapi/groovy/json/JsonSlurper.html)
+    * JSON Path [API](https://code.google.com/p/json-path/)
+    * GPath [Overview](http://groovy.codehaus.org/GPath)
+

Added: incubator/knox/trunk/books/0.3.0/config.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/config.md?rev=1526295&view=auto
==============================================================================
--- incubator/knox/trunk/books/0.3.0/config.md (added)
+++ incubator/knox/trunk/books/0.3.0/config.md Wed Sep 25 20:43:32 2013
@@ -0,0 +1,78 @@
+<!---
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+--->
+
+{{Configuration}}
+-----------------
+
+### Enabling logging ###
+
+If necessary you can enable additional logging by editing the `log4j.properties` file in the `conf` directory.
+Changing the rootLogger value from `ERROR` to `DEBUG` will generate a large amount of debug logging.
+A number of useful, more fine loggers are also provided in the file.
+
+
+### Management of Security Artifacts ###
+
+There are a number of artifacts that are used by the gateway in ensuring the security of wire level communications, access to protected resources and the encryption of sensitive data.
+These artifacts can be managed from outside of the gateway instances or generated and populated by the gateway instance itself.
+
+The following is a description of how this is coordinated with both standalone (development, demo, etc) gateway instances and instances as part of a cluster of gateways in mind.
+
+Upon start of the gateway server we:
+
+1. Look for an identity store at `conf/security/keystores/gateway.jks`.
+The identity store contains the certificate and private key used to represent the identity of the server for SSL connections and signature creation.
+
+* If there is no identity store we create one and generate a self-signed certificate for use in standalone/demo mode.
+The certificate is stored with an alias of gateway-identity.
+* If there is an identity store found than we ensure that it can be loaded using the provided master secret and that there is an alias with called gateway-identity.
+
+2. Look for a credential store at `conf/security/keystores/__gateway-credentials.jceks`.
+This credential store is used to store secrets/passwords that are used by the gateway.
+For instance, this is where the pass-phrase for accessing the gateway-identity certificate is kept.
+
+* If there is no credential store found then we create one and populate it with a generated pass-phrase for the alias `gateway-identity-passphrase`.
+This is coordinated with the population of the self-signed cert into the identity-store.
+* If a credential store is found then we ensure that it can be loaded using the provided master secret and that the expected aliases have been populated with secrets.
+
+Upon deployment of a Hadoop cluster topology within the gateway we:
+
+1. Look for a credential store for the topology. For instance, we have a sample topology that gets deployed out of the box.  We look for `conf/security/keystores/sample-credentials.jceks`. This topology specific credential store is used for storing secrets/passwords that are used for encrypting sensitive data with topology specific keys.
+
+* If no credential store is found for the topology being deployed then one is created for it.
+Population of the aliases is delegated to the configured providers within the system that will require the use of a  secret for a particular task.
+They may programmatic set the value of the secret or choose to have the value for the specified alias generated through the AliasService.
+* If a credential store is found then we ensure that it can be loaded with the provided master secret and the configured providers have the opportunity to ensure that the aliases are populated and if not to populate them.
+
+By leveraging the algorithm described above we can provide a window of opportunity for management of these artifacts in a number of ways.
+
+1. Using a single gateway instance as a master instance the artifacts can be generated or placed into the expected location and then replicated across all of the slave instances before startup.
+2. Using an NFS mount as a central location for the artifacts would provide a single source of truth without the need to replicate them over the network. Of course, NFS mounts have their own challenges.
+
+Summary of Secrets to be Managed:
+
+1. Master secret - the same for all gateway instances in a cluster of gateways
+2. All security related artifacts are protected with the master secret
+3. Secrets used by the gateway itself are stored within the gateway credential store and are the same across all gateway instances in the cluster of gateways
+4. Secrets used by providers within cluster topologies are stored in topology specific credential stores and are the same for the same topology across the cluster of gateway instances.
+However, they are specific to the topology - so secrets for one hadoop cluster are different from those of another.
+This allows for fail-over from one gateway instance to another even when encryption is being used while not allowing the compromise of one encryption key to expose the data for all clusters.
+
+NOTE: the SSL certificate will need special consideration depending on the type of certificate. Wildcard certs may be able to be shared across all gateway instances in a cluster.
+When certs are dedicated to specific machines the gateway identity store will not be able to be blindly replicated as hostname verification problems will ensue.
+Obviously, trust-stores will need to be taken into account as well.
+

Added: incubator/knox/trunk/books/0.3.0/install.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/install.md?rev=1526295&view=auto
==============================================================================
--- incubator/knox/trunk/books/0.3.0/install.md (added)
+++ incubator/knox/trunk/books/0.3.0/install.md Wed Sep 25 20:43:32 2013
@@ -0,0 +1,40 @@
+<!---
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+--->
+
+{{Installation}}
+----------------
+
+### ZIP ###
+
+Download and extract the `knox-{VERSION}.zip` file into the installation directory that will contain your `{GATEWAY_HOME}`.
+You can find the downloads for Knox releases on the [Apache mirrors](http://www.apache.org/dyn/closer.cgi/incubator/knox/).
+
+    jar xf knox-{VERSION}.zip
+
+This will create a directory `knox-{VERSION}` in your current directory.
+
+
+### RPM ###
+
+TODO
+
+
+### Layout ###
+
+TODO - Describe the purpose of all of the directories
+
+

Modified: incubator/knox/trunk/books/0.3.0/oozie.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/oozie.md?rev=1526295&r1=1526294&r2=1526295&view=diff
==============================================================================
--- incubator/knox/trunk/books/0.3.0/oozie.md (original)
+++ incubator/knox/trunk/books/0.3.0/oozie.md Wed Sep 25 20:43:32 2013
@@ -26,3 +26,243 @@ TODO
 #### {{Oozie Examples}} ####
 
 TODO
+
+##### Assumptions
+
+This document assumes a few things about your environment in order to simplify the examples.
+
+* The JVM is executable as simply java.
+* The Apache Knox Gateway is installed and functional.
+* The example commands are executed within the context of the GATEWAY_HOME current directory.
+The GATEWAY_HOME directory is the directory within the Apache Knox Gateway installation that contains the README file and the bin, conf and deployments directories.
+* A few examples optionally require the use of commands from a standard Groovy installation.
+These examples are optional but to try them you will need Groovy [installed](http://groovy.codehaus.org/Installing+Groovy).
+
+#### Customization
+
+These examples may need to be tailored to the execution environment.
+In particular hostnames and ports may need to be changes to match your environment.
+In particular there are two example files in the distribution that may need to be customized.
+Take a moment to review these files.
+All of the values that may need to be customized can be found together at the top of each file.
+
+* samples/ExampleSubmitJob.groovy
+* samples/ExampleSubmitWorkflow.groovy
+
+If you are using the Sandbox VM for your Hadoop cluster you may want to review [these configuration tips](#Sandbox+Configuration).
+
+#### Example #2: WebHDFS & Oozie via KnoxShell DSL
+
+This example will also submit the familiar WordCount Java MapReduce job to the Hadoop cluster via the gateway using the KnoxShell DSL.
+However in this case the job will be submitted via a Oozie workflow.
+There are several ways to do this depending upon your preference.
+
+You can use the "embedded" Groovy interpreter provided with the distribution.
+
+    java -jar bin/shell.jar samples/ExampleSubmitWorkflow.groovy
+
+You can manually type in the KnoxShell DSL script into the "embedded" Groovy interpreter provided with the distribution.
+
+    java -jar bin/shell.jar
+
+Each line from the file below will need to be typed or copied into the interactive shell.
+
+##### samples/ExampleSubmitWorkflow.groovy #####
+
+    import com.jayway.jsonpath.JsonPath
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.hadoop.gateway.shell.hdfs.Hdfs
+    import org.apache.hadoop.gateway.shell.workflow.Workflow
+
+    import static java.util.concurrent.TimeUnit.SECONDS
+
+    gateway = "https://localhost:8443/gateway/sample"
+    jobTracker = "sandbox:50300";
+    nameNode = "sandbox:8020";
+    username = "bob"
+    password = "bob-password"
+    inputFile = "LICENSE"
+    jarFile = "samples/hadoop-examples.jar"
+
+    definition = """\
+    <workflow-app xmlns="uri:oozie:workflow:0.2" name="wordcount-workflow">
+        <start to="root-node"/>
+        <action name="root-node">
+            <java>
+                <job-tracker>$jobTracker</job-tracker>
+                <name-node>hdfs://$nameNode</name-node>
+                <main-class>org.apache.hadoop.examples.WordCount</main-class>
+                <arg>/tmp/test/input</arg>
+                <arg>/tmp/test/output</arg>
+            </java>
+            <ok to="end"/>
+            <error to="fail"/>
+        </action>
+        <kill name="fail">
+            <message>Java failed</message>
+        </kill>
+        <end name="end"/>
+    </workflow-app>
+    """
+
+    configuration = """\
+    <configuration>
+        <property>
+            <name>user.name</name>
+            <value>$username</value>
+        </property>
+        <property>
+            <name>oozie.wf.application.path</name>
+            <value>hdfs://$nameNode/tmp/test</value>
+        </property>
+    </configuration>
+    """
+
+    hadoop = Hadoop.login( gateway, username, password )
+
+    println "Delete /tmp/test " + Hdfs.rm(hadoop).file( "/tmp/test" ).recursive().now().statusCode
+    println "Mkdir /tmp/test " + Hdfs.mkdir(hadoop).dir( "/tmp/test").now().statusCode
+    putWorkflow = Hdfs.put(hadoop).text( definition ).to( "/tmp/test/workflow.xml" ).later() {
+        println "Put /tmp/test/workflow.xml " + it.statusCode }
+    putData = Hdfs.put(hadoop).file( inputFile ).to( "/tmp/test/input/FILE" ).later() {
+        println "Put /tmp/test/input/FILE " + it.statusCode }
+    putJar = Hdfs.put(hadoop).file( jarFile ).to( "/tmp/test/lib/hadoop-examples.jar" ).later() {
+        println "Put /tmp/test/lib/hadoop-examples.jar " + it.statusCode }
+    hadoop.waitFor( putWorkflow, putData, putJar )
+
+    jobId = Workflow.submit(hadoop).text( configuration ).now().jobId
+    println "Submitted job " + jobId
+
+    status = "UNKNOWN";
+    count = 0;
+    while( status != "SUCCEEDED" && count++ < 60 ) {
+      sleep( 1000 )
+      json = Workflow.status(hadoop).jobId( jobId ).now().string
+      status = JsonPath.read( json, "${SDS}.status" )
+    }
+    println "Job status " + status;
+
+    println "Shutdown " + hadoop.shutdown( 10, SECONDS )
+
+    exit
+
+#### Example #3: WebHDFS & Templeton/WebHCat via cURL
+
+The example below illustrates the sequence of curl commands that could be used to run a "word count" map reduce job.
+It utilizes the hadoop-examples.jar from a Hadoop install for running a simple word count job.
+A copy of that jar has been included in the samples directory for convenience.
+Take care to follow the instructions below for steps 4/5 and 6/7 where the Location header returned by the call to the NameNode is copied for use with the call to the DataNode that follows it.
+These replacement values are identified with { } markup.
+
+    # 0. Optionally cleanup the test directory in case a previous example was run without cleaning up.
+    curl -i -k -u bob:bob-password -X DELETE \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test?op=DELETE&recursive=true'
+
+    # 1. Create a test input directory /tmp/test/input
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/input?op=MKDIRS'
+
+    # 2. Create a test output directory /tmp/test/input
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/output?op=MKDIRS'
+
+    # 3. Create the inode for hadoop-examples.jar in /tmp/test
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/hadoop-examples.jar?op=CREATE'
+
+    # 4. Upload hadoop-examples.jar to /tmp/test.  Use a hadoop-examples.jar from a Hadoop install.
+    curl -i -k -u bob:bob-password -T samples/hadoop-examples.jar -X PUT '{Value Location header from command above}'
+
+    # 5. Create the inode for a sample file README in /tmp/test/input
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/input/README?op=CREATE'
+
+    # 6. Upload readme.txt to /tmp/test/input.  Use the readme.txt in {GATEWAY_HOME}.
+    curl -i -k -u bob:bob-password -T README -X PUT '{Value of Location header from command above}'
+
+    # 7. Submit the word count job via WebHCat/Templeton.
+    # Take note of the Job ID in the JSON response as this will be used in the next step.
+    curl -v -i -k -u bob:bob-password -X POST \
+        -d jar=/tmp/test/hadoop-examples.jar -d class=wordcount \
+        -d arg=/tmp/test/input -d arg=/tmp/test/output \
+        'https://localhost:8443/gateway/sample/templeton/api/v1/mapreduce/jar'
+
+    # 8. Look at the status of the job
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/templeton/api/v1/queue/{Job ID returned in JSON body from previous step}'
+
+    # 9. Look at the status of the job queue
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/templeton/api/v1/queue'
+
+    # 10. List the contents of the output directory /tmp/test/output
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/output?op=LISTSTATUS'
+
+    # 11. Optionally cleanup the test directory
+    curl -i -k -u bob:bob-password -X DELETE \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test?op=DELETE&recursive=true'
+
+#### Example #4: WebHDFS & Oozie via cURL
+
+The example below illustrates the sequence of curl commands that could be used to run a "word count" map reduce job via an Oozie workflow.
+It utilizes the hadoop-examples.jar from a Hadoop install for running a simple word count job.
+A copy of that jar has been included in the samples directory for convenience.
+Take care to follow the instructions below where replacement values are required.
+These replacement values are identified with { } markup.
+
+    # 0. Optionally cleanup the test directory in case a previous example was run without cleaning up.
+    curl -i -k -u bob:bob-password -X DELETE \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test?op=DELETE&recursive=true'
+
+    # 1. Create the inode for workflow definition file in /tmp/test
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/workflow.xml?op=CREATE'
+
+    # 2. Upload the workflow definition file.  This file can be found in {GATEWAY_HOME}/templates
+    curl -i -k -u bob:bob-password -T templates/workflow-definition.xml -X PUT \
+        '{Value Location header from command above}'
+
+    # 3. Create the inode for hadoop-examples.jar in /tmp/test/lib
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/lib/hadoop-examples.jar?op=CREATE'
+
+    # 4. Upload hadoop-examples.jar to /tmp/test/lib.  Use a hadoop-examples.jar from a Hadoop install.
+    curl -i -k -u bob:bob-password -T samples/hadoop-examples.jar -X PUT \
+        '{Value Location header from command above}'
+
+    # 5. Create the inode for a sample input file readme.txt in /tmp/test/input.
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/input/README?op=CREATE'
+
+    # 6. Upload readme.txt to /tmp/test/input.  Use the readme.txt in {GATEWAY_HOME}.
+    # The sample below uses this README file found in {GATEWAY_HOME}.
+    curl -i -k -u bob:bob-password -T README -X PUT \
+        '{Value of Location header from command above}'
+
+    # 7. Create the job configuration file by replacing the {NameNode host:port} and {JobTracker host:port}
+    # in the command below to values that match your Hadoop configuration.
+    # NOTE: The hostnames must be resolvable by the Oozie daemon.  The ports are the RPC ports not the HTTP ports.
+    # For example {NameNode host:port} might be sandbox:8020 and {JobTracker host:port} sandbox:50300
+    # The source workflow-configuration.xml file can be found in {GATEWAY_HOME}/templates
+    # Alternatively, this file can copied and edited manually for environments without the sed utility.
+    sed -e s/REPLACE.NAMENODE.RPCHOSTPORT/{NameNode host:port}/ \
+        -e s/REPLACE.JOBTRACKER.RPCHOSTPORT/{JobTracker host:port}/ \
+        <templates/workflow-configuration.xml >workflow-configuration.xml
+
+    # 8. Submit the job via Oozie
+    # Take note of the Job ID in the JSON response as this will be used in the next step.
+    curl -i -k -u bob:bob-password -T workflow-configuration.xml -H Content-Type:application/xml -X POST \
+        'https://localhost:8443/gateway/sample/oozie/api/v1/jobs?action=start'
+
+    # 9. Query the job status via Oozie.
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/oozie/api/v1/job/{Job ID returned in JSON body from previous step}'
+
+    # 10. List the contents of the output directory /tmp/test/output
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/output?op=LISTSTATUS'
+
+    # 11. Optionally cleanup the test directory
+    curl -i -k -u bob:bob-password -X DELETE \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test?op=DELETE&recursive=true'

Modified: incubator/knox/trunk/books/0.3.0/trouble.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/trouble.md?rev=1526295&r1=1526294&r2=1526295&view=diff
==============================================================================
--- incubator/knox/trunk/books/0.3.0/trouble.md (original)
+++ incubator/knox/trunk/books/0.3.0/trouble.md Wed Sep 25 20:43:32 2013
@@ -30,3 +30,13 @@ There are various useful loggers pre-pop
     log4j.logger.org.apache.http.headers=DEBUG   # Use this logger to increase the debugging of Apache HTTP header.
     log4j.logger.org.apache.http.wire=DEBUG      # Use this logger to increase the debugging of Apache HTTP wire traffic.
 
+### Filing Bugs ###
+
+h2. Filing bugs
+
+Bugs can be filed using [Jira](https://issues.apache.org/jira/browse/KNOX).
+Please include the results of this command below in the Environment section.
+Also include the version of Hadoop being used.
+
+    java -jar bin/server.jar -version
+

Added: incubator/knox/trunk/books/0.3.0/using.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/using.md?rev=1526295&view=auto
==============================================================================
--- incubator/knox/trunk/books/0.3.0/using.md (added)
+++ incubator/knox/trunk/books/0.3.0/using.md Wed Sep 25 20:43:32 2013
@@ -0,0 +1,141 @@
+<!---
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+--->
+
+{{Getting Started}}
+-------------------
+
+### 2. Enter the `{GATEWAY_HOME}` directory
+
+    cd knox-{VERSION}
+
+The fully qualified name of this directory will be referenced as {{\{GATEWAY_HOME\}}} throughout the remainder of this document.
+
+### 3. Start the demo LDAP server (ApacheDS)
+
+First, understand that the LDAP server provided here is for demonstration purposes.
+You may configure the LDAP specifics within the topology descriptor for the cluster as described in step 5 below, in order to customize what LDAP instance to use.
+The assumption is that most users will leverage the demo LDAP server while evaluating this release and should therefore continue with the instructions here in step 3.
+
+Edit {{\{GATEWAY_HOME\}/conf/users.ldif}} if required and add your users and groups to the file.
+A sample end user "bob" has been already included.
+Note that the passwords in this file are "fictitious" and have nothing to do with the actual accounts on the Hadoop cluster you are using.
+There is also a copy of this file in the templates directory that you can use to start over if necessary.
+
+Start the LDAP server - pointing it to the config dir where it will find the users.ldif file in the conf directory.
+
+    java -jar bin/ldap.jar conf &
+
+There are a number of log messages of the form {{Created null.}} that can safely be ignored.  Take note of the port on which it was started as this needs to match later configuration.
+
+### 4. Start the Gateway server
+
+    java -jar bin/server.jar
+
+Take note of the port identified in the logging output as you will need this for accessing the gateway.
+
+The server will prompt you for the master secret (password). This secret is used to secure artifacts used to secure artifacts used by the gateway server for things like SSL, credential/password aliasing. This secret will have to be entered at startup unless you choose to persist it. Remember this secret and keep it safe.  It represents the keys to the kingdom. See the Persisting the Master section for more information.
+
+### 5. Configure the Gateway with the topology of your Hadoop cluster
+
+Edit the file {{\{GATEWAY_HOME\}/deployments/sample.xml}}
+
+Change the host and port in the urls of the {{<service>}} elements for NAMENODE, TEMPLETON and OOZIE services to match your Hadoop cluster
+deployment.
+
+The default configuration contains the LDAP URL for a LDAP server.  By default that file is configured to access the demo ApacheDS based LDAP
+server and its default configuration. By default, this server listens on port 33389.  Optionally, you can change the LDAP URL for the LDAP server to be used for authentication.  This is set via the main.ldapRealm.contextFactory.url property in the {{<gateway><provider><authentication>}} section.
+
+Save the file.  The directory {{\{GATEWAY_HOME\}/deployments}} is monitored by the Gateway server and reacts to the discovery of a new or changed cluster topology descriptor by provisioning the endpoints and required filter chains to serve the needs of each cluster as described by the topology file.  Note that the name of the file excluding the extension is also used as the path for that cluster in the URL.  So for example
+the sample.xml file will result in Gateway URLs of the form {{\[http://\]}}{{{}{gateway-host\}:\{gateway-port\}/gateway/sample/namenode/api/v1}}
+
+### 6. Test the installation and configuration of your Gateway
+
+Invoke the LISTSATUS operation on HDFS represented by your configured NAMENODE by using your web browser or curl:
+
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/?op=LISTSTATUS'
+
+The results of the above command should result in something to along the lines of the output below.  The exact information returned is subject to the content within HDFS in your Hadoop cluster.
+
+    HTTP/1.1 200 OK
+    Content-Type: application/json
+    Content-Length: 760
+    Server: Jetty(6.1.26)
+
+    {"FileStatuses":{"FileStatus":[
+    {"accessTime":0,"blockSize":0,"group":"hdfs","length":0,"modificationTime":1350595859762,"owner":"hdfs","pathSuffix":"apps","permission":"755","replication":0,"type":"DIRECTORY"},
+    {"accessTime":0,"blockSize":0,"group":"mapred","length":0,"modificationTime":1350595874024,"owner":"mapred","pathSuffix":"mapred","permission":"755","replication":0,"type":"DIRECTORY"},
+    {"accessTime":0,"blockSize":0,"group":"hdfs","length":0,"modificationTime":1350596040075,"owner":"hdfs","pathSuffix":"tmp","permission":"777","replication":0,"type":"DIRECTORY"},
+    {"accessTime":0,"blockSize":0,"group":"hdfs","length":0,"modificationTime":1350595857178,"owner":"hdfs","pathSuffix":"user","permission":"755","replication":0,"type":"DIRECTORY"}
+    ]}}
+
+For additional information on WebHDFS, Templeton/WebHCat and Oozie REST APIs, see the following URLs respectively:
+
+* WebHDFS - [http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/WebHDFS.html]
+* Templeton/WebHCat - [http://people.apache.org/~thejas/templeton_doc_v1/]
+* Oozie - [http://oozie.apache.org/docs/3.3.1/WebServicesAPI.html]
+
+
+### Examples
+
+More examples can be found [here|Examples].
+
+
+###. Persisting the Master Secret
+
+The master secret is required to start the server.
+This secret is used to access secured artifacts by the gateway instance.
+Keystore, trust stores and credential stores are all protected with the master secret.
+
+You may persist the master secret by supplying the *\-persist-master* switch at startup.
+This will result in a warning indicating that persisting the secret is less secure than providing it at startup.
+We do make some provisions in order to protect the persisted password.
+
+It is encrypted with AES 128 bit encryption and where possible the file permissions are set to only be accessible by the user that the gateway is running as.
+
+After persisting the secret, ensure that the file at config/security/master has the appropriate permissions set for your environment.
+This is probably the most important layer of defense for master secret.
+Do not assume that the encryption if sufficient protection.
+
+A specific user should be created to run the gateway this will protect a persisted master file.
+
+
+### Mapping Gateway URLs to Hadoop cluster URLs
+
+The Gateway functions much like a reverse proxy.
+As such it maintains a mapping of URLs that are exposed externally by the Gateway to URLs that are provided by the Hadoop cluster.
+Examples of mappings for the NameNode and Templeton are shown below.
+These mapping are generated from the combination of the Gateway configuration file (i.e. {{\{GATEWAY_HOME\}/conf/gateway-site.xml}}) and the cluster topology descriptors (e.g. {{\{GATEWAY_HOME\}/deployments/\{cluster-name\}.xml}}).
+
+* HDFS (NameNode)
+    * Gateway: {nolink:http://\{gateway-host\}:\{gateway-port\}/\{gateway-path\}/\{cluster-name\}/namenode/api/v1}
+    * Cluster: {nolink:http://\{namenode-host\}:50070/webhdfs/v1}
+* WebHCat (Templeton)
+    * Gateway: {nolink:http://\{gateway-host\}:\{gateway-port\}/\{gateway-path\}/\{cluster-name\}/templeton/api/v1}
+    * Cluster: {nolink:http://\{templeton-host\}:50111/templeton/v1}
+* Oozie
+    * Gateway: {nolink:http://\{gateway-host\}:\{gateway-port\}/\{gateway-path\}/\{cluster-name\}/oozie/api/v1}
+    * Cluster: {nolink:http://\{templeton-host\}:11000/oozie/v1}
+
+The values for {{\{gateway-host\}}}, {{\{gateway-port\}}}, {{\{gateway-path\}}} are provided via the Gateway configuration file (i.e. `{GATEWAY_HOME\}/conf/gateway-site.xml`).
+
+The value for {{\{cluster-name\}}} is derived from the name of the cluster topology descriptor (e.g. {{\{GATEWAY_HOME\}/deployments/\{cluster-name\}.xml}}).
+
+The value for {{\{namenode-host\}}} and {{\{templeton-host\}}} is provided via the cluster topology descriptor (e.g. {{\{GATEWAY_HOME\}/deployments/\{cluster-name\}.xml}}).
+
+Note: The ports 50070, 50111 and 11000 are the defaults for NameNode, Templeton and Oozie respectively.
+Their values can also be provided via the cluster topology descriptor if your Hadoop cluster uses different ports.

Modified: incubator/knox/trunk/books/0.3.0/webhcat.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/webhcat.md?rev=1526295&r1=1526294&r2=1526295&view=diff
==============================================================================
--- incubator/knox/trunk/books/0.3.0/webhcat.md (original)
+++ incubator/knox/trunk/books/0.3.0/webhcat.md Wed Sep 25 20:43:32 2013
@@ -25,4 +25,91 @@ TODO
 
 #### {{WebHCat Examples}} ####
 
-TODO
\ No newline at end of file
+TODO
+
+#### Assumptions
+
+This document assumes a few things about your environment in order to simplify the examples.
+
+* The JVM is executable as simply java.
+* The Apache Knox Gateway is installed and functional.
+* The example commands are executed within the context of the GATEWAY_HOME current directory.
+The GATEWAY_HOME directory is the directory within the Apache Knox Gateway installation that contains the README file and the bin, conf and deployments directories.
+* A few examples optionally require the use of commands from a standard Groovy installation.
+These examples are optional but to try them you will need Groovy [installed|http://groovy.codehaus.org/Installing+Groovy].
+
+#### Customization
+
+These examples may need to be tailored to the execution environment.
+In particular hostnames and ports may need to be changes to match your environment.
+In particular there are two example files in the distribution that may need to be customized.
+Take a moment to review these files.
+All of the values that may need to be customized can be found together at the top of each file.
+
+* samples/ExampleSubmitJob.groovy
+* samples/ExampleSubmitWorkflow.groovy
+
+If you are using the Sandbox VM for your Hadoop cluster you may want to review [these configuration tips|Sandbox Configuration].
+
+
+#### Example #1: WebHDFS & Templeton/WebHCat via KnoxShell DSL
+
+This example will submit the familiar WordCount Java MapReduce job to the Hadoop cluster via the gateway using the KnoxShell DSL.
+There are several ways to do this depending upon your preference.
+
+You can use the "embedded" Groovy interpreter provided with the distribution.
+
+    java -jar bin/shell.jar samples/ExampleSubmitJob.groovy
+
+You can manually type in the KnoxShell DSL script into the "embedded" Groovy interpreter provided with the distribution.
+
+    java -jar bin/shell.jar
+
+Each line from the file below will need to be typed or copied into the interactive shell.
+
+##### samples/ExampleSubmitJob
+
+    import com.jayway.jsonpath.JsonPath
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.hadoop.gateway.shell.hdfs.Hdfs
+    import org.apache.hadoop.gateway.shell.job.Job
+
+    import static java.util.concurrent.TimeUnit.SECONDS
+
+    gateway = "https://localhost:8443/gateway/sample"
+    username = "bob"
+    password = "bob-password"
+    dataFile = "LICENSE"
+    jarFile = "samples/hadoop-examples.jar"
+
+    hadoop = Hadoop.login( gateway, username, password )
+
+    println "Delete /tmp/test " + Hdfs.rm(hadoop).file( "/tmp/test" ).recursive().now().statusCode
+    println "Create /tmp/test " + Hdfs.mkdir(hadoop).dir( "/tmp/test").now().statusCode
+
+    putData = Hdfs.put(hadoop).file( dataFile ).to( "/tmp/test/input/FILE" ).later() {
+        println "Put /tmp/test/input/FILE " + it.statusCode }
+    putJar = Hdfs.put(hadoop).file( jarFile ).to( "/tmp/test/hadoop-examples.jar" ).later() {
+         println "Put /tmp/test/hadoop-examples.jar " + it.statusCode }
+    hadoop.waitFor( putData, putJar )
+
+    jobId = Job.submitJava(hadoop) \
+        .jar( "/tmp/test/hadoop-examples.jar" ) \
+        .app( "wordcount" ) \
+        .input( "/tmp/test/input" ) \
+        .output( "/tmp/test/output" ) \
+        .now().jobId
+    println "Submitted job " + jobId
+
+    done = false
+    count = 0
+    while( !done && count++ < 60 ) {
+        sleep( 1000 )
+        json = Job.queryStatus(hadoop).jobId(jobId).now().string
+        done = JsonPath.read( json, "${SDS}.status.jobComplete" )
+    }
+    println "Done " + done
+
+    println "Shutdown " + hadoop.shutdown( 10, SECONDS )
+
+    exit

Modified: incubator/knox/trunk/books/0.3.0/webhdfs.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/0.3.0/webhdfs.md?rev=1526295&r1=1526294&r2=1526295&view=diff
==============================================================================
--- incubator/knox/trunk/books/0.3.0/webhdfs.md (original)
+++ incubator/knox/trunk/books/0.3.0/webhdfs.md Wed Sep 25 20:43:32 2013
@@ -26,3 +26,84 @@ TODO
 #### WebHDFS Examples ####
 
 TODO
+
+
+#### Assumptions
+
+This document assumes a few things about your environment in order to simplify the examples.
+
+* The JVM is executable as simply java.
+* The Apache Knox Gateway is installed and functional.
+* The example commands are executed within the context of the GATEWAY_HOME current directory.
+The GATEWAY_HOME directory is the directory within the Apache Knox Gateway installation that contains the README file and the bin, conf and deployments directories.
+* A few examples optionally require the use of commands from a standard Groovy installation.
+These examples are optional but to try them you will need Groovy [installed|http://groovy.codehaus.org/Installing+Groovy].
+
+h2. Customization
+
+These examples may need to be tailored to the execution environment.
+In particular hostnames and ports may need to be changes to match your environment.
+In particular there are two example files in the distribution that may need to be customized.
+Take a moment to review these files.
+All of the values that may need to be customized can be found together at the top of each file.
+
+* samples/ExampleWebHDFS.groovy
+
+
+#### WebHDFS via KnoxShell DSL
+
+You can use the Groovy interpreter provided with the distribution.
+
+    java -jar bin/shell.jar samples/ExampleWebHDFS.groovy
+
+You can manually type in the KnoxShell DSL script into the interactive Groovy interpreter provided with the distribution.
+
+    java -jar bin/shell.jar
+
+Each line from the file below will need to be typed or copied into the interactive shell.
+
+##### samples/ExampleHdfs.groovy
+
+    import groovy.json.JsonSlurper
+    import org.apache.hadoop.gateway.shell.Hadoop
+    import org.apache.hadoop.gateway.shell.hdfs.Hdfs
+
+    gateway = "https://localhost:8443/gateway/sample"
+    username = "bob"
+    password = "bob-password"
+    dataFile = "README"
+
+    session = Hadoop.login( gateway, username, password )
+    Hdfs.rm( session ).file( "/tmp/example" ).recursive().now()
+    Hdfs.put( session ).file( dataFile ).to( "/tmp/example/README" ).now()
+    text = Hdfs.ls( session ).dir( "/tmp/example" ).now().string
+    json = (new JsonSlurper()).parseText( text )
+    println json.FileStatuses.FileStatus.pathSuffix
+    text = Hdfs.get( session ).from( "/tmp/example/README" ).now().string
+    println text
+    Hdfs.rm( session ).file( "/tmp/example" ).recursive().now()
+    session.shutdown()
+
+
+#### WebHDFS via cURL
+
+    # 1. Optionally cleanup the sample directory in case a previous example was run without cleaning up.
+    curl -i -k -u bob:bob-password -X DELETE \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test?op=DELETE&recursive=true'
+
+    # 2. Create the inode for a sample input file readme.txt in /tmp/test/input.
+    curl -i -k -u bob:bob-password -X PUT \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/input/README?op=CREATE'
+
+    # 3. Upload readme.txt to /tmp/test/input.  Use the readme.txt in {GATEWAY_HOME}.
+    # The sample below uses this README file found in {GATEWAY_HOME}.
+    curl -i -k -u bob:bob-password -T README -X PUT \
+        '{Value of Location header from command above}'
+
+    # 4. List the contents of the output directory /tmp/test/output
+    curl -i -k -u bob:bob-password -X GET \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test/input?op=LISTSTATUS'
+
+    # 5. Optionally cleanup the test directory
+    curl -i -k -u bob:bob-password -X DELETE \
+        'https://localhost:8443/gateway/sample/namenode/api/v1/tmp/test?op=DELETE&recursive=true'

Modified: incubator/knox/trunk/books/common/header.md
URL: http://svn.apache.org/viewvc/incubator/knox/trunk/books/common/header.md?rev=1526295&r1=1526294&r2=1526295&view=diff
==============================================================================
--- incubator/knox/trunk/books/common/header.md (original)
+++ incubator/knox/trunk/books/common/header.md Wed Sep 25 20:43:32 2013
@@ -15,7 +15,7 @@
    limitations under the License.
 --->
 
-<link href="markdown.css" rel="stylesheet"/>
+<link href="book.css" rel="stylesheet"/>
 
 [asl]: http://www.apache.org/licenses/LICENSE-2.0
 [y]: check.png "Yes"