You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2012/06/03 23:59:52 UTC

svn commit: r1345788 [5/10] - in /hbase/trunk: ./ hbase-assembly/ hbase-common/ hbase-server/ hbase-site/ src/ src/assembly/ src/docbkx/ src/site/ src/site/resources/ src/site/resources/css/ src/site/resources/images/ src/site/xdoc/ src/xslt/

Added: hbase/trunk/src/docbkx/developer.xml
URL: http://svn.apache.org/viewvc/hbase/trunk/src/docbkx/developer.xml?rev=1345788&view=auto
==============================================================================
--- hbase/trunk/src/docbkx/developer.xml (added)
+++ hbase/trunk/src/docbkx/developer.xml Sun Jun  3 21:59:50 2012
@@ -0,0 +1,821 @@
+<?xml version="1.0"?>
+    <chapter xml:id="developer"
+      version="5.0" xmlns="http://docbook.org/ns/docbook"
+      xmlns:xlink="http://www.w3.org/1999/xlink"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      xmlns:svg="http://www.w3.org/2000/svg"
+      xmlns:m="http://www.w3.org/1998/Math/MathML"
+      xmlns:html="http://www.w3.org/1999/xhtml"
+      xmlns:db="http://docbook.org/ns/docbook">
+<!--
+/**
+ * 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.
+ */
+-->
+    <title>Building and Developing HBase</title>
+    <para>This chapter will be of interest only to those building and developing HBase (i.e., as opposed to
+    just downloading the latest distribution).
+    </para>
+    <section xml:id="repos">
+      <title>HBase Repositories</title>
+      <para>There are two different repositories for HBase: Subversion (SVN) and Git. The former is the system of record for committers, but the latter is easier to work with to build and contribute. SVN updates get automatically propagated to the Git repo.</para>
+      <section xml:id="svn">
+        <title>SVN</title>
+        <programlisting>
+svn co http://svn.apache.org/repos/asf/hbase/trunk hbase-core-trunk 
+        </programlisting>
+      </section>         
+      <section xml:id="git">
+        <title>Git</title>
+        <programlisting>
+git clone git://git.apache.org/hbase.git
+        </programlisting>
+      </section>         
+    </section>    
+             
+    <section xml:id="ides"> 
+        <title>IDEs</title>
+        <section xml:id="eclipse">
+          <title>Eclipse</title>
+            <section xml:id="eclipse.code.formatting">
+            <title>Code Formatting</title>
+            <para>See <link xlink:href="https://issues.apache.org/jira/browse/HBASE-3678">HBASE-3678 Add Eclipse-based Apache Formatter to HBase Wiki</link>
+              for an Eclipse formatter to help ensure your code conforms to HBase'y coding convention.
+            The issue includes instructions for loading the attached formatter.</para>
+            <para>In addition to the automatic formatting, make sure you follow the style guidelines explained in <xref linkend="common.patch.feedback"/></para>
+            <para>Also, no @author tags - that's a rule.  Quality Javadoc comments are appreciated.  And include the Apache license.</para>
+            </section>         
+            <section xml:id="eclipse.svn">
+            <title>Subversive Plugin</title>
+            <para>Download and install the Subversive plugin.</para>
+            <para>Set up an SVN Repository target from <xref linkend="svn"/>, then check out the code.</para>
+            </section>         
+            <section xml:id="eclipse.git.plugin">
+            <title>Git Plugin</title>
+            <para>If you cloned the project via git, download and install the Git plugin (EGit). Attach to your local git repo (via the Git Repositories window) and you'll be able to see file revision history, generate patches, etc.</para>
+            </section>
+            <section xml:id="eclipse.maven.setup">
+            <title>HBase Project Setup in Eclipse</title>
+            <para>The easiest way is to use the m2eclipse plugin for Eclipse. Eclipse Indigo or newer has m2eclipse built-in, or it can be found here:http://www.eclipse.org/m2e/. M2Eclipse provides Maven integration for Eclipse - it even lets you use the direct Maven commands from within Eclipse to compile and test your project.</para>
+            <para>To import the project, you merely need to go to File->Import...Maven->Existing Maven Projects and then point Eclipse at the HBase root directory; m2eclipse will automatically find all the hbase modules for you.</para>
+            <para>If you install m2eclipse and import HBase in your workspace, you will have to fix your eclipse Build Path.
+            Remove <filename>target</filename> folder, add <filename>target/generated-jamon</filename>
+            and <filename>target/generated-sources/java</filename> folders. You may also remove from your Build Path
+            the exclusions on the <filename>src/main/resources</filename> and <filename>src/test/resources</filename>
+            to avoid error message in the console 'Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.6:run (default) on project hbase: 
+            'An Ant BuildException has occured: Replace: source file .../target/classes/hbase-default.xml doesn't exist'. This will also
+            reduce the eclipse build cycles and make your life easier when developing.</para>
+            </section>
+            <section xml:id="eclipse.commandline">
+            <title>Import into eclipse with the command line</title>
+            <para>For those not inclined to use m2eclipse, you can generate the Eclipse files from the command line. First, run (you should only have to do this once): 
+            <programlisting>mvn clean install -DskipTests</programlisting>
+            and then close Eclipse and execute...
+            <programlisting>mvn eclipse:eclipse</programlisting>
+            ... from your local HBase project directory in your workspace to generate some new <filename>.project</filename> 
+            and <filename>.classpath</filename>files.  Then reopen Eclipse, and import the .project file in the HBase directory to a workspace.
+            </para>
+            </section>
+            <section xml:id="eclipse.maven.class">
+            <title>Maven Classpath Variable</title>
+            <para>The <varname>M2_REPO</varname> classpath variable needs to be set up for the project.  This needs to be set to 
+            your local Maven repository, which is usually <filename>~/.m2/repository</filename></para>
+            If this classpath variable is not configured, you will see compile errors in Eclipse like this...
+            <programlisting>
+Description	Resource	Path	Location	Type
+The project cannot be built until build path errors are resolved	hbase		Unknown	Java Problem 
+Unbound classpath variable: 'M2_REPO/asm/asm/3.1/asm-3.1.jar' in project 'hbase'	hbase		Build path	Build Path Problem
+Unbound classpath variable: 'M2_REPO/com/github/stephenc/high-scale-lib/high-scale-lib/1.1.1/high-scale-lib-1.1.1.jar' in project 'hbase'	hbase		Build path	Build Path Problem 
+Unbound classpath variable: 'M2_REPO/com/google/guava/guava/r09/guava-r09.jar' in project 'hbase'	hbase		Build path	Build Path Problem
+Unbound classpath variable: 'M2_REPO/com/google/protobuf/protobuf-java/2.3.0/protobuf-java-2.3.0.jar' in project 'hbase'	hbase		Build path	Build Path Problem Unbound classpath variable:
+            </programlisting>            
+            </section>
+            <section xml:id="eclipse.issues">
+            <title>Eclipse Known Issues</title>
+            <para>Eclipse will currently complain about <filename>Bytes.java</filename>.  It is not possible to turn these errors off.</para>
+            <programlisting>            
+Description	Resource	Path	Location	Type
+Access restriction: The method arrayBaseOffset(Class) from the type Unsafe is not accessible due to restriction on required library /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar	Bytes.java	/hbase/src/main/java/org/apache/hadoop/hbase/util	line 1061	Java Problem
+Access restriction: The method arrayIndexScale(Class) from the type Unsafe is not accessible due to restriction on required library /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar	Bytes.java	/hbase/src/main/java/org/apache/hadoop/hbase/util	line 1064	Java Problem
+Access restriction: The method getLong(Object, long) from the type Unsafe is not accessible due to restriction on required library /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar	Bytes.java	/hbase/src/main/java/org/apache/hadoop/hbase/util	line 1111	Java Problem
+             </programlisting>   
+             </section>
+             <section xml:id="eclipse.more">
+             <title>Eclipse - More Information</title>
+             <para>For additional information on setting up Eclipse for HBase development on Windows, see 
+             <link xlink:href="http://michaelmorello.blogspot.com/2011/09/hbase-subversion-eclipse-windows.html">Michael Morello's blog</link> on the topic.
+             </para>
+             </section>
+        </section>
+    </section> 
+    
+        <section xml:id="build">
+       <title>Building HBase</title>
+      <section xml:id="build.basic">
+       <title>Basic Compile</title>
+       <para>Thanks to maven, building HBase is easy. You can read about the various maven commands in <xref linkend="maven.build.commands"/>, but the simplest command to compile HBase from its java source code is:
+       <programlisting>
+mvn compile
+       </programlisting>
+       Or, to clean up before compiling:
+       <programlisting>
+mvn clean compile
+       </programlisting>
+       With Eclipse set up as explained above in <xref linkend="eclipse"/>, you can also simply use the build command in Eclipse. To create the full installable HBase package takes a little bit more work, so read on. 
+       </para>
+      </section>
+      <section xml:id="build.snappy">
+        <title>Building in snappy compression support</title>
+        <para>Pass <code>-Dsnappy</code> to trigger the snappy maven profile for building
+            snappy native libs into hbase.</para>
+      </section>
+
+      <section xml:id="build.tgz">
+        <title>Building the HBase tarball</title>
+        <para>Do the following to build the HBase tarball.
+        Passing the -Drelease will generate javadoc and run the RAT plugin to verify licenses on source.
+        <programlisting>% MAVEN_OPTS="-Xmx2g" mvn clean site install assembly:single -DskipTests -Prelease</programlisting>
+</para>
+      </section>
+
+      <section xml:id="mvn_repo">
+        <title>Adding an HBase release to Apache's Maven Repository</title>
+        <para>Follow the instructions at
+        <link xlink:href="http://www.apache.org/dev/publishing-maven-artifacts.html">Publishing Maven Artifacts</link>.
+            The 'trick' to making it all work is answering the questions put to you by the mvn release plugin properly,
+            making sure it is using the actual branch AND before doing the <command>mvn release:perform</command> step,
+            VERY IMPORTANT, check and if necessary hand edit the release.properties file that was put under <varname>${HBASE_HOME}</varname>
+            by the previous step, <command>release:perform</command>. You need to edit it to make it point at
+            right locations in SVN.
+        </para>
+        <para>Use maven 3.0.x.
+        </para>
+        <para>At the <command>mvn release:perform</command> step, before starting, if you are for example
+        releasing hbase 0.92.0, you need to make sure the pom.xml version is 0.92.0-SNAPSHOT.  This needs
+        to be checked in.  Since we do the maven release after actual release, I've been doing this
+        checkin into a particular tag rather than into the actual release tag.  So, say we released
+        hbase 0.92.0 and now we want to do the release to the maven repository, in svn, the 0.92.0
+        release will be tagged 0.92.0.  Making the maven release, copy the 0.92.0 tag to 0.92.0mvn.
+        Check out this tag and change the version therein and commit.
+        </para>
+        <para>Here is how I'd answer the questions at <command>release:prepare</command> time:
+        <programlisting>What is the release version for "HBase"? (org.apache.hbase:hbase) 0.92.0: : 
+What is SCM release tag or label for "HBase"? (org.apache.hbase:hbase) hbase-0.92.0: : 0.92.0mvnrelease
+What is the new development version for "HBase"? (org.apache.hbase:hbase) 0.92.1-SNAPSHOT: : 
+[INFO] Transforming 'HBase'...</programlisting>
+        </para>
+        <para>A strange issue I ran into was the one where the upload into the apache
+        repository was being sprayed across multiple apache machines making it so I could
+        not release.  See <link xlink:href="https://issues.apache.org/jira/browse/INFRA-4482">INFRA-4482 Why is my upload to mvn spread across multiple repositories?</link>.</para>
+
+        <para xml:id="mvn.settings.file">Here is my <filename>~/.m2/settings.xml</filename>.
+        <programlisting>&lt;settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
+                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
+  &lt;servers>
+    &lt;!- To publish a snapshot of some part of Maven -->
+    &lt;server>
+      &lt;id>apache.snapshots.https&lt;/id>
+      &lt;username>YOUR_APACHE_ID
+      &lt;/username>
+      &lt;password>YOUR_APACHE_PASSWORD
+      &lt;/password>
+    &lt;/server>
+    &lt;!-- To publish a website using Maven -->
+    &lt;!-- To stage a release of some part of Maven -->
+    &lt;server>
+      &lt;id>apache.releases.https&lt;/id>
+      &lt;username>YOUR_APACHE_ID
+      &lt;/username>
+      &lt;password>YOUR_APACHE_PASSWORD
+      &lt;/password>
+    &lt;/server>
+  &lt;/servers>
+  &lt;profiles>
+    &lt;profile>
+      &lt;id>apache-release&lt;/id>
+      &lt;properties>
+    &lt;gpg.keyname>YOUR_KEYNAME&lt;/gpg.keyname>
+    &lt;!--Keyname is something like this ... 00A5F21E... do gpg --list-keys to find it-->
+    &lt;gpg.passphrase>YOUR_KEY_PASSWORD
+    &lt;/gpg.passphrase>
+      &lt;/properties>
+    &lt;/profile>
+  &lt;/profiles>
+&lt;/settings>
+        </programlisting>
+        </para>
+        <para>When you run <command>release:perform</command>, pass <command>-Papache-release</command>
+        else it will not 'sign' the artifacts it uploads.
+        </para>
+        <para>If you see run into the below, its because you need to edit version in the pom.xml and add
+        <code>-SNAPSHOT</code> to the version (and commit).
+        <programlisting>[INFO] Scanning for projects...
+[INFO] Searching repository for plugin with prefix: 'release'.
+[INFO] ------------------------------------------------------------------------
+[INFO] Building HBase
+[INFO]    task-segment: [release:prepare] (aggregator-style)
+[INFO] ------------------------------------------------------------------------
+[INFO] [release:prepare {execution: default-cli}]
+[INFO] ------------------------------------------------------------------------
+[ERROR] BUILD FAILURE
+[INFO] ------------------------------------------------------------------------
+[INFO] You don't have a SNAPSHOT project in the reactor projects list.
+[INFO] ------------------------------------------------------------------------
+[INFO] For more information, run Maven with the -e switch
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 3 seconds
+[INFO] Finished at: Sat Mar 26 18:11:07 PDT 2011
+[INFO] Final Memory: 35M/423M
+[INFO] -----------------------------------------------------------------------</programlisting>
+        </para>
+      </section>
+
+      <section xml:id="build.gotchas"><title>Build Gotchas</title>
+			<para>If you see <code>Unable to find resource 'VM_global_library.vm'</code>, ignore it.  
+			Its not an error.  It is <link xlink:href="http://jira.codehaus.org/browse/MSITE-286">officially ugly</link> though.
+           </para>
+      </section>
+    </section> <!--  build -->
+    <section xml:id="hbase.site">
+    <title>Updating hbase.apache.org</title>
+      <section xml:id="hbase.site.contributing">
+      <title>Contributing to hbase.apache.org</title>
+      <para>The HBase apache web site (including this reference guide) is maintained as part of the main HBase source tree, under <filename>/src/docbkx</filename> and <filename>/src/site</filename>. The former is this reference guide; the latter, in most cases, are legacy pages that are in the process of being merged into the docbkx tree.</para>
+      <para>To contribute to the reference guide, edit these files and submit them as a patch (see <xref linkend="submitting.patches"/>). Your Jira should contain a summary of the changes in each section (see <link xlink:href="https://issues.apache.org/jira/browse/HBASE-6081">HBASE-6081</link> for an example).</para>
+      <para>To generate the site locally while you're working on it, run:
+      <programlisting>mvn site</programlisting>
+      Then you can load up the generated HTML files in your browser (file are under <filename>/target/site</filename>).</para>
+      </section>
+      <section xml:id="hbase.site.publishing">
+      <title>Publishing hbase.apache.org</title>
+      <para>If you're a committer with rights to publish the site artifacts: set up your apache credentials and the target site location locally in a place and
+      form that maven can pick it up, in <filename>~/.m2/settings.xml</filename>.  See <xref linked="mvn_repo" /> for an example.
+      Next, run the following:
+      <programlisting>$ mvn -DskipTests -Papache-release site site:deploy</programlisting>
+      You will be asked for your password.  It can take a little time.
+      Remember that it can take a few hours for your site changes to show up.
+      </para>
+      </section>
+    </section>
+    <section xml:id="hbase.tests">
+    <title>Tests</title>
+
+<para> Developers, at a minimum, should familiarize themselves with the unit test detail; unit tests in
+HBase have a character not usually seen in other projects.</para> 
+
+<section xml:id="hbase.moduletests">
+<title>HBase Modules</title>
+<para>As of 0.96, HBase is split into multiple modules which creates "interesting" rules for
+how and where tests are written. If you are writting code for <classname>hbase-server</classname>, see
+<xref linkend="hbase.unittests"/> for how to write your tests; these tests can spin
+up a minicluster and will need to be categorized. For any other module, for example
+<classname>hbase-common</classname>, the tests must be strict unit tests and just test the class
+under test - no use of the HBaseTestingUtility or minicluster is allowed (or even possible
+given the dependency tree).</para>
+  <section xml:id="hbase.moduletest.run">
+  <title>Running Tests in other Modules</title>
+  If the module you are developing in has no other dependencies on other HBase modules, then
+  you can cd into that module and just run:
+  <programlisting>mvn test</programlisting>
+  which will just run the tests IN THAT MODULE. If there are other dependencies on other modules,
+  then you will have run the command from the ROOT HBASE DIRECTORY. This will run the tests in the other
+  modules, unless you specify to skip the tests in that module. For instance, to skip the tests in the hbase-server module,
+  you would run:
+  <programlisting>mvn clean test -Dskip-server-tests</programlisting>
+  from the top level directory to run all the tests in modules other than hbase-server. Note that you
+  can specify to skip tests in multiple modules as well as just for a single module. For example, to skip
+  the tests in <classname>hbase-server</classname> and <classname>hbase-common</classname>, you would run:
+  <programlisting>mvn clean test -Dskip-server-tests -Dskip-common-tests</programlisting>
+  <para>Also, keep in mind that if you are running tests in the <classname>hbase-server</classname> module you will need to 
+  apply the maven profiles discussed in <xref linkend="hbase.unittests.cmds"/> to get the tests to run properly.</para>
+  </section>
+</section>
+
+<section xml:id="hbase.unittests">
+<title>Unit Tests</title>
+<para>HBase unit tests are subdivided into three categories: small, medium and large, with
+corresponding JUnit <link xlink:href="http://www.junit.org/node/581">categories</link>:
+<classname>SmallTests</classname>, <classname>MediumTests</classname>,
+<classname>LargeTests</classname>.  JUnit categories are denoted using java annotations
+and look like this in your unit test code.
+<programlisting>...
+@Category(SmallTests.class)
+public class TestHRegionInfo {
+
+  @Test
+  public void testCreateHRegionInfoName() throws Exception {
+    // ...
+  }
+...
+  @org.junit.Rule
+  public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
+    new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
+}</programlisting>
+The above example shows how to mark a test as belonging to the small category.  The <code>@org.junit.Rule</code>
+lines on the end are also necessary. Add them to each new unit test file.  They are needed by the categorization process.
+HBase uses a patched maven surefire plugin and maven profiles to implement its unit test characterizations.
+</para>
+
+<section xml:id="hbase.unittests.small">
+<title><indexterm><primary>SmallTests</primary></indexterm></title>
+<para>
+<emphasis>Small</emphasis> tests are executed in a shared JVM. We put in this category all the tests that can
+be executed quickly in a shared JVM.  The maximum execution time for a small test is 15 seconds,
+and small tests should not use a (mini)cluster.</para>
+</section>
+
+<section xml:id="hbase.unittests.medium">
+<title><indexterm><primary>MediumTests</primary></indexterm></title>
+<para><emphasis>Medium</emphasis> tests represent tests that must be executed
+before proposing a patch. They are designed to run in less than 30 minutes altogether,
+and are quite stable in their results. They are designed to last less than 50 seconds
+individually. They can use a cluster, and each of them is executed in a separate JVM.
+</para>
+</section>
+
+<section xml:id="hbase.unittests.large">
+<title><indexterm><primary>LargeTests</primary></indexterm></title>
+<para><emphasis>Large</emphasis> tests are everything else. They are typically integration-like
+tests, regression tests for specific bugs, timeout tests, performance tests.
+They are executed before a commit on the pre-integration machines. They can be run on
+the developer machine as well.
+</para>
+</section>
+
+<section xml:id="hbase.unittests.cmds">
+<title>Running tests</title>
+<para>Below we describe how to run the HBase junit categories.</para>
+
+<section xml:id="hbase.unittests.cmds.test">
+<title>Default: small and medium category tests
+</title>
+<para>Running <programlisting>mvn test</programlisting> will execute all small tests in a single JVM
+(no fork) and then medium tests in a separate JVM for each test instance.
+Medium tests are NOT executed if there is an error in a small test.
+Large tests are NOT executed.  There is one report for small tests, and one report for
+medium tests if they are executed. To run small and medium tests with the security
+profile enabled, do <programlisting>mvn test -P security</programlisting>
+</para>
+</section>
+
+<section xml:id="hbase.unittests.cmds.test.runAllTests">
+<title>Running all tests</title>
+<para>Running <programlisting>mvn test -P runAllTests</programlisting>
+will execute small tests in a single JVM then medium and large tests in a separate JVM for each test.
+Medium and large tests are NOT executed if there is an error in a small test.
+Large tests are NOT executed if there is an error in a small or medium test.
+There is one report for small tests, and one report for medium and large tests if they are executed
+</para>
+</section>
+
+<section xml:id="hbase.unittests.cmds.test.localtests.mytest">
+<title>Running a single test or all tests in a package</title>
+<para>To run an individual test, e.g. <classname>MyTest</classname>, do
+<programlisting>mvn test -P localTests -Dtest=MyTest</programlisting>  You can also
+pass multiple, individual tests as a comma-delimited list:
+<programlisting>mvn test -P localTests -Dtest=MyTest1,MyTest2,MyTest3</programlisting>
+You can also pass a package, which will run all tests under the package:
+<programlisting>mvn test -P localTests -Dtest=org.apache.hadoop.hbase.client.*</programlisting>
+To run a single test with the security profile enabled:
+<programlisting>mvn test -P security,localTests -Dtest=TestGet</programlisting>
+</para>
+
+<para>
+The <code>-P localTests</code>  will remove the JUnit category effect (without this specific profile,
+the categories are taken into account).  It will actually use the official release of surefire
+and the old connector (The HBase build uses a patched version of the maven surefire plugin).
+Each junit tests is executed in a separate JVM (A fork per test class).  There is no
+parallelization when <code>localTests</code> profile is set.  You will see a new message at the end of the
+report: "[INFO] Tests are skipped". It's harmless.
+</para>
+</section>
+
+<section xml:id="hbase.unittests.cmds.test.profiles">
+<title>Other test invocation permutations</title>
+<para>Running <programlisting>mvn test -P runSmallTests</programlisting> will execute small tests only, in a single JVM.
+</para>
+<para>Running <programlisting>mvn test -P runMediumTests</programlisting> will execute medium tests in a single JVM.
+</para>
+<para>Running <programlisting>mvn test -P runLargeTests</programlisting> execute medium tests in a single JVM.
+</para>
+</section>
+
+<section xml:id="hbase.unittests.cmds.test.hbasetests">
+<title><command>hbasetests.sh</command></title>
+<para>It's also possible to use the script <command>hbasetests.sh</command>. This script runs the medium and
+large tests in parallel with two maven instances, and provides a single report.  This script does not use
+the hbase version of surefire so no parallelization is being done other than the two maven instances the
+script sets up.
+It must be executed from the directory which contains the <filename>pom.xml</filename>.</para>
+<para>For example running
+<programlisting>./dev-support/hbasetests.sh</programlisting> will execute small and medium tests.
+Running <programlisting>./dev-support/hbasetests.sh runAllTests</programlisting> will execute all tests.
+Running <programlisting>./dev-support/hbasetests.sh replayFailed</programlisting> will rerun the failed tests a
+second time, in a separate jvm and without parallelisation.
+</para>
+</section>
+</section>
+
+<section xml:id="hbase.tests.writing">
+<title>Writing Tests</title>
+<section xml:id="hbase.tests.rules">
+<title>General rules</title>
+<itemizedlist>
+<listitem>
+As much as possible, tests should be written as category small tests.
+</listitem>
+<listitem>
+All tests must be written to support parallel execution on the same machine, hence they should not use shared resources as fixed ports or fixed file names.
+</listitem>
+<listitem>
+Tests should not overlog. More than 100 lines/second makes the logs complex to read and use i/o that are hence not available for the other tests.
+</listitem>
+<listitem>
+Tests can be written with <classname>HBaseTestingUtility</classname>.
+This class offers helper functions to create a temp directory and do the cleanup, or to start a cluster.
+Categories and execution time
+</listitem>
+<listitem>
+All tests must be categorized, if not they could be skipped.
+</listitem>
+<listitem>
+All tests should be written to be as fast as possible.
+</listitem>
+<listitem>
+Small category tests should last less than 15 seconds, and must not have any side effect.
+</listitem>
+<listitem>
+Medium category tests should last less than 50 seconds.
+</listitem>
+<listitem>
+Large category tests should last less than 3 minutes.  This should ensure a good parallelization for people using it, and ease the analysis when the test fails.
+</listitem>
+</itemizedlist>
+</section>
+<section xml:id="hbase.tests.sleeps">
+<title>Sleeps in tests</title>
+<para>Whenever possible, tests should not use <methodname>Thread.sleep</methodname>, but rather waiting for the real event they need. This is faster and clearer for the reader.
+Tests should not do a <methodname>Thread.sleep</methodname> without testing an ending condition. This allows understanding what the test is waiting for. Moreover, the test will work whatever the machine performance is.
+Sleep should be minimal to be as fast as possible. Waiting for a variable should be done in a 40ms sleep loop. Waiting for a socket operation should be done in a 200 ms sleep loop.
+</para>
+</section>
+
+<section xml:id="hbase.tests.cluster">
+<title>Tests using a cluster
+</title>
+
+<para>Tests using a HRegion do not have to start a cluster: A region can use the local file system.
+Start/stopping a cluster cost around 10 seconds. They should not be started per test method but per test class.
+Started cluster must be shutdown using <methodname>HBaseTestingUtility#shutdownMiniCluster</methodname>, which cleans the directories.
+As most as possible, tests should use the default settings for the cluster. When they don't, they should document it. This will allow to share the cluster later.
+</para>
+</section>
+</section>
+</section>
+</section> <!-- tests -->
+    
+    <section xml:id="maven.build.commands"> 
+       <title>Maven Build Commands</title>
+       <para>All commands executed from the local HBase project directory.
+       </para>
+       <para>Note: use Maven 3 (Maven 2 may work but we suggest you use Maven 3).
+       </para>
+       <section xml:id="maven.build.commands.compile"> 
+          <title>Compile</title>
+          <programlisting>
+mvn compile
+          </programlisting>
+       </section>       
+
+       <section xml:id="maven.build.commands.unitall"> 
+          <title>Running all or individual Unit Tests</title>
+          <para>See the <xref linkend="hbase.unittests.cmds" /> section
+          above in <xref linkend="hbase.unittests" /></para>
+       </section>       
+
+       <section xml:id="maven.build.hadoop"> 
+          <title>Building against various hadoop versions.</title>
+          <para>As of 0.96, HBase supports building against hadoop versions: 1.0.3, 2.0.0-alpha and 3.0.0-SNAPSHOT. 
+          By default, we will build with Hadoop-1.0.3. To change the version to run with Hadoop-2.0.0-alpha, you would run:</para>
+         <programlisting>mvn -Dhadoop.profile=2.0 ...</programlisting>
+         <para>
+         That is, designate build with hadoop.profile 2.0.  Pass 2.0 for hadoop.profile to build against hadoop 2.0.
+         Tests may not all pass as of this writing so you may need to pass <code>-DskipTests</code> unless you are inclined
+          to fix the failing tests.</para>
+          <para>
+         Similarly, for 3.0, you would just replace the profile value. Note that Hadoop-3.0.0-SNAPSHOT does not currently have a deployed maven artificat - you will need to build and install your own in your local maven repository if you want to run against this profile.
+         </para>
+         <para>
+         In earilier verions of HBase, you can build against older versions of hadoop, notably, Hadoop 0.22.x and 0.23.x.
+         If you are running, for example HBase-0.94 and wanted to build against Hadoop 0.23.x, you would run with:</para>
+          <programlisting>mvn -Dhadoop.profile=22 ...</programlisting>
+      </section>
+    </section>
+  
+    <section xml:id="getting.involved"> 
+        <title>Getting Involved</title>
+        <para>HBase gets better only when people contribute!
+        </para>
+        <para>As HBase is an Apache Software Foundation project, see <xref linkend="asf"/> for more information about how the ASF functions.
+        </para>
+        <section xml:id="mailing.list">
+          <title>Mailing Lists</title>
+          <para>Sign up for the dev-list and the user-list.  See the 
+          <link xlink:href="http://hbase.apache.org/mail-lists.html">mailing lists</link> page.
+          Posing questions - and helping to answer other people's questions - is encouraged!  
+          There are varying levels of experience on both lists so patience and politeness are encouraged (and please 
+          stay on topic.)  
+          </para>
+        </section>
+        <section xml:id="jira">
+          <title>Jira</title>
+          <para>Check for existing issues in <link xlink:href="https://issues.apache.org/jira/browse/HBASE">Jira</link>.  
+          If it's either a new feature request, enhancement, or a bug, file a ticket.
+          </para>
+          <section xml:id="jira.priorities"><title>Jira Priorities</title>
+          <para>The following is a guideline on setting Jira issue priorities:
+                <itemizedlist>
+                <listitem>Blocker: Should only be used if the issue WILL cause data loss or cluster instability reliably.</listitem>
+                <listitem>Critical: The issue described can cause data loss or cluster instability in some cases.</listitem>
+                <listitem>Major: Important but not tragic issues, like updates to the client API that will add a lot of much-needed functionality or significant
+                bugs that need to be fixed but that don't cause data loss.</listitem>
+                <listitem>Minor: Useful enhancements and annoying but not damaging bugs.</listitem> 
+                <listitem>Trivial: Useful enhancements but generally cosmetic.</listitem> 
+                </itemizedlist>  
+             </para> 
+        </section>
+        <section xml:id="submitting.patches.jira.code">
+          <title>Code Blocks in Jira Comments</title>
+          <para>A commonly used macro in Jira is {code}. If you do this in a Jira comment...
+<programlisting>
+{code}
+   code snippet
+{code}
+</programlisting>
+              ... Jira will format the code snippet like code, instead of a regular comment.  It improves readability.
+          </para>
+        </section>
+       </section>  <!--  jira -->
+      </section>  <!--  getting involved -->
+      
+      <section xml:id="developing">
+        <title>Developing</title>
+        <section xml:id="codelines"><title>Codelines</title>
+          <para>Most development is done on TRUNK.  However, there are branches for minor releases (e.g., 0.90.1, 0.90.2, and 0.90.3 are on the 0.90 branch).</para>
+          <para>If you have any questions on this just send an email to the dev dist-list.</para>
+        </section>
+  
+        <section xml:id="unit.tests"> 
+          <title>Unit Tests</title>
+          <para>In HBase we use <link xlink:href="http://junit.org">JUnit</link> 4.
+            If you need to run miniclusters of HDFS, ZooKeeper, HBase, or MapReduce testing,
+            be sure to checkout the <classname>HBaseTestingUtility</classname>.
+            Alex Baranau of Sematext describes how it can be used in
+            <link xlink:href="http://blog.sematext.com/2010/08/30/hbase-case-study-using-hbasetestingutility-for-local-testing-development/">HBase Case-Study: Using HBaseTestingUtility for Local Testing and Development</link> (2010).
+          </para>
+          <section xml:id="mockito">
+           <title>Mockito</title>
+           <para>Sometimes you don't need a full running server
+              unit testing.  For example, some methods can make do with a
+              a <classname>org.apache.hadoop.hbase.Server</classname> instance
+              or a <classname>org.apache.hadoop.hbase.master.MasterServices</classname>
+              Interface reference rather than a full-blown
+              <classname>org.apache.hadoop.hbase.master.HMaster</classname>.
+              In these cases, you maybe able to get away with a mocked
+              <classname>Server</classname> instance.  For example:
+              <programlisting>
+              TODO...
+              </programlisting>
+           </para>
+         </section>
+        </section>   <!--  unit tests  -->       
+
+          <section xml:id="code.standards">
+           <title>Code Standards</title>
+           <para>See <xref linkend="eclipse.code.formatting"/> and <xref linkend="common.patch.feedback"/>.
+           </para>
+           <para>Also, please pay attention to the interface stability/audience classifications that you
+           will see all over our code base.   They look like this at the head of the class:
+           <programlisting>@InterfaceAudience.Public
+@InterfaceStability.Stable</programlisting>
+           </para>
+           <para>If the <classname>InterfaceAudience</classname> is <varname>Private</varname>,
+           we can change the class (and we do not need to include a <classname>InterfaceStability</classname> mark).
+           If a class is marked <varname>Public</varname> but its <classname>InterfaceStability</classname>
+           is marked <varname>Unstable</varname>, we can change it. If it's 
+           marked <varname>Public</varname>/<varname>Evolving</varname>, we're allowed to change it
+           but should try not to. If it's <varname>Public</varname> and <varname>Stable</varname>
+           we can't change it without a deprecation path or with a really GREAT reason.</para>
+           <para>When you add new classes, mark them with the annotations above if publically accessible.
+           If you are not cleared on how to mark your additions, ask up on the dev list.
+           </para>
+           <para>This convention comes from our parent project Hadoop.</para>
+           </section> <!-- code.standards -->
+
+          <section xml:id="run.insitu">
+           <title>Running In-Situ</title>
+           <para>If you are developing HBase, frequently it is useful to test your changes against a more-real cluster than what you find in unit tests. In this case, HBase can be run directly from the source in local-mode.
+           All you need to do is run:
+           </para>
+           <programlisting>${HBASE_HOME}/bin/start-hbase.sh</programlisting>
+           <para>
+           This will spin up a full local-cluster, just as if you had packaged up HBase and installed it on your machine.
+           </para>
+           <para>Keep in mind that you will need to have installed HBase into your local maven repository for the in-situ cluster to work properly. That is, you will need to run:</para>
+           <programlisting>mvn clean install -DskipTests</programlisting>
+           <para>to ensure that maven can find the correct classpath and dependencies. Generally, the above command
+           is just a good thing to try running first, if maven is acting oddly.</para>
+           </section> <!-- run.insitu -->
+
+      </section>  <!--  developing -->
+
+       <section xml:id="submitting.patches">
+          <title>Submitting Patches</title>
+          <section xml:id="submitting.patches.create">
+            <title>Create Patch</title>
+          <para>Patch files can be easily generated from Eclipse, for example by selecting "Team -&gt; Create Patch".
+          Patches can also be created by git diff and svn diff.
+          </para>
+          <para>Please submit one patch-file per Jira.  For example, if multiple files are changed make sure the 
+          selected resource when generating the patch is a directory.  Patch files can reflect changes in multiple files. </para>
+          <para>Make sure you review <xref linkend="eclipse.code.formatting"/> for code style. </para>
+          </section>
+          <section xml:id="submitting.patches.naming">
+            <title>Patch File Naming</title>
+          <para>The patch file should have the HBase Jira ticket in the name.  For example, if a patch was submitted for <filename>Foo.java</filename>, then
+          a patch file called <filename>Foo_HBASE_XXXX.patch</filename> would be acceptable where XXXX is the HBase Jira number.
+          </para>
+          <para>If you generating from a branch, then including the target branch in the filename is advised, e.g., <filename>HBASE-XXXX-0.90.patch</filename>.
+          </para>
+          </section>
+          <section xml:id="submitting.patches.tests">
+            <title>Unit Tests</title>
+            <para>Yes, please.  Please try to include unit tests with every code patch (and especially new classes and large changes).
+            Make sure unit tests pass locally before submitting the patch.</para>
+            <para>Also, see <xref linkend="mockito"/>.</para>
+            <para>If you are creating a new unit test class, notice how other unit test classes have classification/sizing
+            annotations at the top and a static method on the end.  Be sure to include these in any new unit test files
+            you generate.  See <xref linkend="hbase.tests" /> for more on how the annotations work. 
+            </para>
+          </section>
+          <section xml:id="submitting.patches.jira">
+            <title>Attach Patch to Jira</title>
+            <para>The patch should be attached to the associated Jira ticket "More Actions -&gt; Attach Files".  Make sure you click the
+            ASF license inclusion, otherwise the patch can't be considered for inclusion.
+            </para>
+            <para>Once attached to the ticket, click "Submit Patch" and 
+            the status of the ticket will change.  Committers will review submitted patches for inclusion into the codebase.  Please
+            understand that not every patch may get committed, and that feedback will likely be provided on the patch.  Fear not, though,
+            because the HBase community is helpful!
+            </para>
+         </section>
+          
+        <section xml:id="common.patch.feedback">
+            <title>Common Patch Feedback</title>
+          <para>The following items are representative of common patch feedback. Your patch process will go faster if these are
+          taken into account <emphasis>before</emphasis> submission.
+          </para>
+          <para>
+          See the <link xlink:href="http://www.oracle.com/technetwork/java/codeconv-138413.html">Java coding standards</link> 
+          for more information on coding conventions in Java.
+          </para>
+          <section xml:id="common.patch.feedback.space.invaders">
+            <title>Space Invaders</title>
+            <para>Rather than do this...
+<programlisting>
+if ( foo.equals( bar ) ) {     // don't do this
+</programlisting>
+			... do this instead...        
+<programlisting>
+if (foo.equals(bar)) {
+</programlisting>
+          </para>
+          <para>Also, rather than do this...
+<programlisting>
+foo = barArray[ i ];     // don't do this
+</programlisting>
+			... do this instead...        
+<programlisting>
+foo = barArray[i];   
+</programlisting>
+          </para>
+          </section>
+          <section xml:id="common.patch.feedback.autogen">
+            <title>Auto Generated Code</title>
+            <para>Auto-generated code in Eclipse often looks like this...
+<programlisting>
+ public void readFields(DataInput arg0) throws IOException {    // don't do this
+   foo = arg0.readUTF();                                       // don't do this
+</programlisting>
+			... do this instead ...        
+<programlisting>
+ public void readFields(DataInput di) throws IOException {
+   foo = di.readUTF();
+</programlisting>
+           See the difference?  'arg0' is what Eclipse uses for arguments by default.
+           </para>
+          </section>
+          <section xml:id="common.patch.feedback.longlines">
+            <title>Long Lines</title>
+            <para>
+            Keep lines less than 100 characters.
+<programlisting>
+Bar bar = foo.veryLongMethodWithManyArguments(argument1, argument2, argument3, argument4, argument5, argument6, argument7, argument8, argument9);  // don't do this
+</programlisting>
+			... do something like this instead ...        
+<programlisting>
+Bar bar = foo.veryLongMethodWithManyArguments(
+ argument1, argument2, argument3,argument4, argument5, argument6, argument7, argument8, argument9); 
+</programlisting>
+           </para>
+          </section>
+          <section xml:id="common.patch.feedback.trailingspaces">
+            <title>Trailing Spaces</title>
+            <para>
+            This happens more than people would imagine.
+<programlisting>
+Bar bar = foo.getBar();     &lt;--- imagine there's an extra space(s) after the semicolon instead of a line break.
+</programlisting>
+            Make sure there's a line-break after the end of your code, and also avoid lines that have nothing
+            but whitespace. 
+            </para>
+         </section> 
+          <section xml:id="common.patch.feedback.writable">
+            <title>Implementing Writable</title>
+            <para>Every class returned by RegionServers must implement <code>Writable</code>.  If you
+            are creating a new class that needs to implement this interface, don't forget the default constructor.
+            </para>
+          </section>
+          <section xml:id="common.patch.feedback.javadoc">
+            <title>Javadoc</title>
+            <para>This is also a very common feedback item.  Don't forget Javadoc!
+            </para>
+          </section>
+          <section xml:id="common.patch.feedback.javadoc.defaults">
+            <title>Javadoc - Useless Defaults</title>
+            <para>Don't just leave the @param arguments the way your IDE generated them.  Don't do this...
+<programlisting>
+  /**
+   * 
+   * @param bar             &lt;---- don't do this!!!!
+   * @return                &lt;---- or this!!!!
+   */
+  public Foo getFoo(Bar bar);
+</programlisting> 
+            ... either add something descriptive to the @param and @return lines, or just remove them. 
+            But the preference is to add something descriptive and useful.          
+            </para>
+          </section>
+          <section xml:id="common.patch.feedback.onething">
+            <title>One Thing At A Time, Folks</title>
+            <para>If you submit a patch for one thing, don't do auto-reformatting or unrelated reformatting of code on a completely
+            different area of code. 
+            </para>
+            <para>Likewise, don't add unrelated cleanup or refactorings outside the scope of your Jira. 
+            </para>
+          </section>
+          <section xml:id="common.patch.feedback.tests">
+            <title>Ambigious Unit Tests</title>
+            <para>Make sure that you're clear about what you are testing in your unit tests and why. 
+            </para>
+          </section>
+
+        </section>   <!--  patch feedback -->
+ 
+         <section xml:id="reviewboard">
+            <title>ReviewBoard</title>
+          <para>Larger patches should go through <link xlink:href="http://reviews.apache.org">ReviewBoard</link>.
+          </para>
+          <para>For more information on how to use ReviewBoard, see
+           <link xlink:href="http://www.reviewboard.org/docs/manual/1.5/">the ReviewBoard documentation</link>.
+          </para>
+        </section> 
+        <section xml:id="committing.patches">
+          <title>Committing Patches</title>
+          <para>
+          Committers do this.  See <link xlink:href="http://wiki.apache.org/hadoop/Hbase/HowToCommit">How To Commit</link> in the HBase wiki.
+          </para>
+          <para>Commiters will also resolve the Jira, typically after the patch passes a build.
+          </para>
+        </section>
+
+       </section>   <!--  submitting patches -->
+       
+    
+    </chapter>

Added: hbase/trunk/src/docbkx/external_apis.xml
URL: http://svn.apache.org/viewvc/hbase/trunk/src/docbkx/external_apis.xml?rev=1345788&view=auto
==============================================================================
--- hbase/trunk/src/docbkx/external_apis.xml (added)
+++ hbase/trunk/src/docbkx/external_apis.xml Sun Jun  3 21:59:50 2012
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="external_apis"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:svg="http://www.w3.org/2000/svg"
+         xmlns:m="http://www.w3.org/1998/Math/MathML"
+         xmlns:html="http://www.w3.org/1999/xhtml"
+         xmlns:db="http://docbook.org/ns/docbook">
+<!--
+/**
+ * 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.
+ */
+-->
+  <title>External APIs</title>
+  This chapter will cover access to HBase either through non-Java languages, or through custom protocols.
+  
+  <section xml:id="nonjava.jvm">
+    <title>Non-Java Languages Talking to the JVM</title>
+    <para>Currently the documentation on this topic in the 
+      <link xlink:href="http://wiki.apache.org/hadoop/Hbase">HBase Wiki</link>.
+      See also the <link xlink:href="http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/thrift/package-summary.html#package_description">Thrift API Javadoc</link>.
+    </para>
+  </section>
+
+  <section xml:id="rest">
+    <title>REST</title>
+    <para>Currently most of the documentation on REST exists in the 
+      <link xlink:href="http://wiki.apache.org/hadoop/Hbase/Stargate">HBase Wiki on REST</link>.
+    </para>
+  </section>   <!-- rest -->
+
+  <section xml:id="thrift">
+    <title>Thrift</title>
+      <para>Currently most of the documentation on Thrift exists in the 
+      <link xlink:href="http://wiki.apache.org/hadoop/Hbase/ThriftApi">HBase Wiki on Thrift</link>.
+    </para>
+          <section xml:id="thrift.filter-language"><title>Filter Language</title>
+             <section xml:id="use-case"><title>Use Case</title>
+               <para>Note:  this feature was introduced in HBase 0.92</para>
+               <para>This allows the user to perform server-side filtering when accessing HBase over Thrift. The user specifies a filter via a string. The string is parsed on the server to construct the filter</para>
+             </section>
+
+             <section xml:id="general-syntax"><title>General Filter String Syntax</title>
+               <para>A simple filter expression is expressed as: <code>“FilterName (argument, argument, ... , argument)”</code></para>
+               <para>You must specify the name of the filter followed by the argument list in parenthesis. Commas separate the individual arguments</para>
+               <para>If the argument represents a string, it should be enclosed in single quotes.</para>
+               <para>If it represents a boolean, an integer or a comparison operator like &lt;,
+                 >, != etc. it should not be enclosed in quotes</para>
+               <para>The filter name must be one word. All ASCII characters are allowed except for whitespace, single quotes and parenthesis.</para>
+               <para>The filter’s arguments can contain any ASCII character. <code>If single quotes are present in the argument, they must be escaped by a
+                   preceding single quote</code></para>
+             </section>
+
+             <section xml:id="compound-filters-and-operators"><title>Compound Filters and Operators</title>
+               <para>Currently, two binary operators – AND/OR and two unary operators – WHILE/SKIP are supported.</para>
+               <para>Note: the operators are all in uppercase</para>
+               <para><emphasis role="bold">AND</emphasis> – as the name suggests, if this
+                 operator is used, the key-value must pass both the filters</para>
+               <para><emphasis role="bold">OR</emphasis> – as the name suggests, if this operator
+                 is used, the key-value must pass at least one of the filters</para>
+               <para><emphasis role="bold">SKIP</emphasis> – For a particular row, if any of the
+                 key-values don’t pass the filter condition, the entire row is skipped</para>
+               <para><emphasis role="bold">WHILE</emphasis> - For a particular row, it continues
+                 to emit key-values until a key-value is reached that fails the filter condition</para>
+               <para><emphasis role="bold">Compound Filters:</emphasis> Using these operators, a
+                 hierarchy of filters can be created. For example: <code>“(Filter1 AND Filter2) OR (Filter3 AND Filter4)”</code></para>
+             </section>
+
+             <section xml:id="order-of-evaluation"><title>Order of Evaluation</title>
+               <para>Parenthesis have the highest precedence. The SKIP and WHILE operators are next and have the same precedence.The AND operator has the next highest precedence followed by the OR operator.</para>
+               <para>For example:</para>
+               <para>A filter string of the form:<code>“Filter1 AND Filter2 OR Filter3”</code>
+                 will be evaluated as:<code>“(Filter1 AND Filter2) OR Filter3”</code></para>
+               <para>A filter string of the form:<code>“Filter1 AND SKIP Filter2 OR Filter3”</code>
+                 will be evaluated as:<code>“(Filter1 AND (SKIP Filter2)) OR Filter3”</code></para>
+             </section>
+
+             <section xml:id="compare-operator"><title>Compare Operator</title>
+               <para>A compare operator can be any of the following:</para>
+               <orderedlist>
+                 <listitem>
+                   <para>LESS (&lt;)</para>
+                 </listitem>
+                 <listitem>
+                   <para>LESS_OR_EQUAL (&lt;=)</para>
+                 </listitem>
+                 <listitem>
+                   <para>EQUAL (=)</para>
+                 </listitem>
+                 <listitem>
+                   <para>NOT_EQUAL (!=)</para>
+                 </listitem>
+                 <listitem>
+                   <para>GREATER_OR_EQUAL (&gt;=)</para>
+                 </listitem>
+                 <listitem>
+                   <para>GREATER (&gt;)</para>
+                 </listitem>
+                 <listitem>
+                   <para>NO_OP (no operation)</para>
+                 </listitem>
+               </orderedlist>
+               <para>The client should use the symbols (&lt;, &lt;=, =, !=, >, >=) to express
+                 compare operators.</para>
+             </section>
+
+             <section xml:id="comparator"><title>Comparator</title>
+               <para>A comparator can be any of the following:</para>
+               <orderedlist>
+                 <listitem>
+                   <para><emphasis role="bold">BinaryComparator</emphasis> - This
+                     lexicographically compares against the specified byte array using
+                     Bytes.compareTo(byte[], byte[])</para>
+                 </listitem>
+                 <listitem>
+                   <para><emphasis role="bold">BinaryPrefixComparator</emphasis> - This
+                     lexicographically compares against a specified byte array. It only compares up to
+                     the length of this byte array.</para>
+                 </listitem>
+                 <listitem>
+                   <para><emphasis role="bold">RegexStringComparator</emphasis> - This compares
+                     against the specified byte array using the given regular expression. Only EQUAL
+                     and NOT_EQUAL comparisons are valid with this comparator</para>
+                 </listitem>
+                 <listitem>
+                   <para><emphasis role="bold">SubStringComparator</emphasis> - This tests if
+                     the given substring appears in a specified byte array. The comparison is case
+                     insensitive. Only EQUAL and NOT_EQUAL comparisons are valid with this
+                     comparator</para>
+                 </listitem>
+               </orderedlist>
+               <para>The general syntax of a comparator is:<code> ComparatorType:ComparatorValue</code></para>
+               <para>The ComparatorType for the various comparators is as follows:</para>
+               <orderedlist>
+                 <listitem>
+                   <para><emphasis role="bold">BinaryComparator</emphasis> - binary</para>
+                 </listitem>
+                 <listitem>
+                   <para><emphasis role="bold">BinaryPrefixComparator</emphasis> - binaryprefix</para>
+                 </listitem>
+                 <listitem>
+                   <para><emphasis role="bold">RegexStringComparator</emphasis> - regexstring</para>
+                 </listitem>
+                 <listitem>
+                   <para><emphasis role="bold">SubStringComparator</emphasis> - substring</para>
+                 </listitem>
+               </orderedlist>
+               <para>The ComparatorValue can be any value.</para>
+               <para>Example1:<code> >, 'binary:abc' </code>will match everything that is lexicographically greater than "abc" </para>
+               <para>Example2:<code> =, 'binaryprefix:abc' </code>will match everything whose first 3 characters are lexicographically equal to "abc"</para>
+               <para>Example3:<code> !=, 'regexstring:ab*yz' </code>will match everything that doesn't begin with "ab" and ends with "yz"</para>
+               <para>Example4:<code> =, 'substring:abc123' </code>will match everything that begins with the substring "abc123"</para>
+             </section>
+
+             <section xml:id="example PHP Client Program"><title>Example PHP Client Program that uses the Filter Language</title>
+               <programlisting>
+&lt;? $_SERVER['PHP_ROOT'] = realpath(dirname(__FILE__).'/..');
+   require_once $_SERVER['PHP_ROOT'].'/flib/__flib.php';
+   flib_init(FLIB_CONTEXT_SCRIPT);
+   require_module('storage/hbase');
+   $hbase = new HBase('&lt;server_name_running_thrift_server&gt;', &lt;port on which thrift server is running&gt;);
+   $hbase->open();
+   $client = $hbase->getClient();
+   $result = $client-&gt;scannerOpenWithFilterString('table_name', "(PrefixFilter ('row2') AND (QualifierFilter (&gt;=, 'binary:xyz'))) AND (TimestampsFilter ( 123, 456))");
+   $to_print = $client-&gt;scannerGetList($result,1);
+   while ($to_print) {
+      print_r($to_print);
+      $to_print = $client-&gt;scannerGetList($result,1);
+    }
+   $client-&gt;scannerClose($result);
+?>
+        </programlisting>
+      </section>
+
+      <section xml:id="example-filter-strings"><title>Example Filter Strings</title>
+        <para>
+          <itemizedlist>
+            <listitem>
+              <para><code>“PrefixFilter (‘Row’) AND PageFilter (1) AND FirstKeyOnlyFilter ()”</code> will return all key-value pairs that match the following conditions:</para>
+              <para>1) The row containing the key-value should have prefix “Row” </para>
+              <para>2) The key-value must be located in the first row of the table </para>
+              <para>3) The key-value pair must be the first key-value in the row </para>
+            </listitem>
+          </itemizedlist>
+        </para>
+
+        <orderedlist>
+          <para>
+            <itemizedlist>
+              <listitem>
+                <para><code>“(RowFilter (=, ‘binary:Row 1’) AND TimeStampsFilter (74689, 89734)) OR
+                    ColumnRangeFilter (‘abc’, true, ‘xyz’, false))”</code> will return all key-value pairs that match both the following conditions:</para>
+                <para>1) The key-value is in a row having row key “Row 1” </para>
+                <para>2) The key-value must have a timestamp of either 74689 or 89734.</para>
+                <para>Or it must match the following condition:</para>
+                <para>1) The key-value pair must be in a column that is lexicographically >= abc and &lt; xyz </para>
+              </listitem>
+            </itemizedlist>
+          </para>
+        </orderedlist>
+
+        <para>
+          <itemizedlist>
+            <listitem>
+              <para><code>“SKIP ValueFilter (0)”</code> will skip the entire row if any of the values in the row is not 0</para>
+            </listitem>
+          </itemizedlist>
+        </para>
+      </section>
+
+      <section xml:id="Individual Filter Syntax"><title>Individual Filter Syntax</title>
+        <orderedlist>
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">KeyOnlyFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter doesn’t take any
+              arguments. It returns only the key component of each key-value. </para>
+            <para><emphasis role="bold">Syntax:</emphasis> KeyOnlyFilter () </para>
+            <para><emphasis role="bold">Example:</emphasis> "KeyOnlyFilter ()"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">FirstKeyOnlyFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter doesn’t take any
+              arguments. It returns only the first key-value from each row. </para>
+            <para><emphasis role="bold">Syntax:</emphasis> FirstKeyOnlyFilter () </para>
+            <para><emphasis role="bold">Example:</emphasis> "FirstKeyOnlyFilter ()" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">PrefixFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes one argument – a prefix of a
+              row key. It returns only those key-values present in a row that starts with the
+              specified row prefix</para>
+            <para><emphasis role="bold">Syntax:</emphasis> PrefixFilter (‘&lt;row_prefix>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "PrefixFilter (‘Row’)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">
+                  ColumnPrefixFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes one argument
+              – a column prefix. It returns only those key-values present in a column that starts
+              with the specified column prefix. The column prefix must be of the form: <code>“qualifier” </code></para>
+            <para><emphasis role="bold">Syntax:</emphasis>ColumnPrefixFilter(‘&lt;column_prefix>’)</para>
+            <para><emphasis role="bold">Example:</emphasis> "ColumnPrefixFilter(‘Col’)"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="underline"><emphasis role="bold">MultipleColumnPrefixFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a list of
+              column prefixes. It returns key-values that are present in a column that starts with
+              any of the specified column prefixes. Each of the column prefixes must be of the form: <code>“qualifier”</code></para>
+            <para><emphasis role="bold">Syntax:</emphasis>MultipleColumnPrefixFilter(‘&lt;column_prefix>’, ‘&lt;column_prefix>’, …, ‘&lt;column_prefix>’)</para>
+            <para><emphasis role="bold">Example:</emphasis> "MultipleColumnPrefixFilter(‘Col1’, ‘Col2’)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">ColumnCountGetFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes one argument
+              – a limit. It returns the first limit number of columns in the table</para>
+            <para><emphasis role="bold">Syntax:</emphasis> ColumnCountGetFilter (‘&lt;limit>’)</para>
+            <para><emphasis role="bold">Example:</emphasis> "ColumnCountGetFilter (4)"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">PageFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes one argument
+              – a page size. It returns page size number of rows from the table. </para>
+            <para><emphasis role="bold">Syntax:</emphasis> PageFilter (‘&lt;page_size>’)</para>
+            <para><emphasis role="bold">Example:</emphasis> "PageFilter (2)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">ColumnPaginationFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes two
+              arguments – a limit and offset. It returns limit number of columns after offset number
+              of columns. It does this for all the rows</para>
+            <para><emphasis role="bold">Syntax:</emphasis> ColumnPaginationFilter(‘&lt;limit>’, ‘&lt;offest>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "ColumnPaginationFilter (3, 5)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">InclusiveStopFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes one argument
+              – a row key on which to stop scanning. It returns all key-values present in rows up to
+              and including the specified row</para>
+            <para><emphasis role="bold">Syntax:</emphasis> InclusiveStopFilter(‘&lt;stop_row_key>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "InclusiveStopFilter ('Row2')" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">TimeStampsFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a list of
+              timestamps. It returns those key-values whose timestamps matches any of the specified
+              timestamps</para>
+            <para> <emphasis role="bold">Syntax:</emphasis> TimeStampsFilter (&lt;timestamp>, &lt;timestamp>, ... ,&lt;timestamp>) </para>
+            <para> <emphasis role="bold">Example:</emphasis> "TimeStampsFilter (5985489, 48895495, 58489845945)"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">RowFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a compare
+              operator and a comparator. It compares each row key with the comparator using the
+              compare operator and if the comparison returns true, it returns all the key-values in
+              that row</para>
+            <para><emphasis role="bold">Syntax:</emphasis> RowFilter (&lt;compareOp>, ‘&lt;row_comparator>’) </para>
+            <para><emphasis role="bold">Example: </emphasis>"RowFilter (&lt;=, ‘xyz)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">Family Filter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a compare
+              operator and a comparator. It compares each qualifier name with the comparator using
+              the compare operator and if the comparison returns true, it returns all the key-values
+              in that column</para>
+            <para><emphasis role="bold">Syntax:</emphasis> QualifierFilter (&lt;compareOp&gt;, ‘&lt;qualifier_comparator>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "QualifierFilter (=, ‘Column1’)"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">QualifierFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a compare
+              operator and a comparator. It compares each qualifier name with the comparator using
+              the compare operator and if the comparison returns true, it returns all the key-values
+              in that column</para>
+            <para><emphasis role="bold">Syntax:</emphasis> QualifierFilter (&lt;compareOp>,‘&lt;qualifier_comparator>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "QualifierFilter (=,‘Column1’)"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">ValueFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a compare operator and a
+              comparator. It compares each value with the comparator using the compare operator and
+              if the comparison returns true, it returns that key-value</para>
+            <para><emphasis role="bold">Syntax:</emphasis> ValueFilter (&lt;compareOp>,‘&lt;value_comparator>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "ValueFilter (!=, ‘Value’)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">DependentColumnFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes two arguments – a family
+              and a qualifier. It tries to locate this column in each row and returns all key-values
+              in that row that have the same timestamp. If the row doesn’t contain the specified
+              column – none of the key-values in that row will be returned.</para>
+            <para>The filter can also take an optional boolean argument – dropDependentColumn. If set to true, the column we were depending on doesn’t get returned.</para>
+            <para>The filter can also take two more additional optional arguments – a compare operator and a value comparator, which are further checks in addition to the family and qualifier. If the dependent column is found, its value should also pass the value check and then only is its timestamp taken into consideration</para>
+            <para><emphasis role="bold">Syntax:</emphasis> DependentColumnFilter (‘&lt;family>’, ‘&lt;qualifier>’, &lt;boolean>, &lt;compare operator>, ‘&lt;value comparator’)</para>
+            <para><emphasis role="bold">Syntax:</emphasis> DependentColumnFilter (‘&lt;family>’, ‘&lt;qualifier>’, &lt;boolean>) </para>
+            <para><emphasis role="bold">Syntax:</emphasis> DependentColumnFilter (‘&lt;family>’, ‘&lt;qualifier>’) </para>
+            <para><emphasis role="bold">Example:</emphasis> "DependentColumnFilter (‘conf’, ‘blacklist’, false, >=, ‘zebra’)" </para>
+            <para><emphasis role="bold">Example:</emphasis> "DependentColumnFilter (‘conf’, 'blacklist', true)"</para>
+            <para><emphasis role="bold">Example:</emphasis> "DependentColumnFilter (‘conf’, 'blacklist')"</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">SingleColumnValueFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes a column family, a
+              qualifier, a compare operator and a comparator. If the specified column is not found –
+              all the columns of that row will be emitted. If the column is found and the comparison
+              with the comparator returns true, all the columns of the row will be emitted. If the
+              condition fails, the row will not be emitted. </para>
+            <para>This filter also takes two additional optional boolean arguments – filterIfColumnMissing and setLatestVersionOnly</para>
+            <para>If the filterIfColumnMissing flag is set to true the columns of the row will not be emitted if the specified column to check is not found in the row. The default value is false.</para>
+            <para>If the setLatestVersionOnly flag is set to false, it will test previous versions (timestamps) too. The default value is true.</para>
+            <para>These flags are optional and if you must set neither or both</para>
+            <para><emphasis role="bold">Syntax:</emphasis> SingleColumnValueFilter(&lt;compare operator>, ‘&lt;comparator>’, ‘&lt;family>’, ‘&lt;qualifier>’,&lt;filterIfColumnMissing_boolean>, &lt;latest_version_boolean>) </para>
+            <para><emphasis role="bold">Syntax:</emphasis> SingleColumnValueFilter(&lt;compare operator>, ‘&lt;comparator>’, ‘&lt;family>’, ‘&lt;qualifier>) </para>
+            <para><emphasis role="bold">Example:</emphasis> "SingleColumnValueFilter (&lt;=, ‘abc’,‘FamilyA’, ‘Column1’, true, false)" </para>
+            <para><emphasis role="bold">Example:</emphasis> "SingleColumnValueFilter (&lt;=, ‘abc’,‘FamilyA’, ‘Column1’)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">SingleColumnValueExcludeFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter takes the same arguments and
+              behaves same as SingleColumnValueFilter – however, if the column is found and the
+              condition passes, all the columns of the row will be emitted except for the tested
+              column value. </para>
+            <para><emphasis role="bold">Syntax:</emphasis> SingleColumnValueExcludeFilter(&lt;compare operator>, '&lt;comparator>', '&lt;family>', '&lt;qualifier>',&lt;latest_version_boolean>, &lt;filterIfColumnMissing_boolean>)</para>
+            <para><emphasis role="bold">Syntax:</emphasis> SingleColumnValueExcludeFilter(&lt;compare operator>, '&lt;comparator>', '&lt;family>', '&lt;qualifier>') </para>
+            <para><emphasis role="bold">Example:</emphasis> "SingleColumnValueExcludeFilter (‘&lt;=’, ‘abc’,‘FamilyA’, ‘Column1’, ‘false’, ‘true’)"</para>
+            <para><emphasis role="bold">Example:</emphasis> "SingleColumnValueExcludeFilter (‘&lt;=’, ‘abc’, ‘FamilyA’, ‘Column1’)" </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis role="bold"><emphasis role="underline">ColumnRangeFilter</emphasis></emphasis></para>
+            <para><emphasis role="bold">Description:</emphasis> This filter is used for selecting only those
+              keys with columns that are between minColumn and maxColumn. It also takes two boolean
+              variables to indicate whether to include the minColumn and maxColumn or not.</para>
+            <para>If you don’t want to set the minColumn or the maxColumn – you can pass in an empty argument.</para>
+            <para><emphasis role="bold">Syntax:</emphasis> ColumnRangeFilter (‘&lt;minColumn>’, &lt;minColumnInclusive_bool>, ‘&lt;maxColumn>’, &lt;maxColumnInclusive_bool>)</para>
+            <para><emphasis role="bold">Example:</emphasis> "ColumnRangeFilter (‘abc’, true, ‘xyz’, false)"</para>
+          </listitem>
+
+          </orderedlist>
+        </section>
+        
+        </section>
+    
+  </section>  <!-- thrift -->
+
+
+</chapter>

Added: hbase/trunk/src/docbkx/getting_started.xml
URL: http://svn.apache.org/viewvc/hbase/trunk/src/docbkx/getting_started.xml?rev=1345788&view=auto
==============================================================================
--- hbase/trunk/src/docbkx/getting_started.xml (added)
+++ hbase/trunk/src/docbkx/getting_started.xml Sun Jun  3 21:59:50 2012
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="getting_started"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:svg="http://www.w3.org/2000/svg"
+         xmlns:m="http://www.w3.org/1998/Math/MathML"
+         xmlns:html="http://www.w3.org/1999/xhtml"
+         xmlns:db="http://docbook.org/ns/docbook">
+<!--
+/**
+ * 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.
+ */
+-->
+  <title>Getting Started</title>
+
+  <section>
+    <title>Introduction</title>
+
+    <para><xref linkend="quickstart" /> will get you up and
+    running on a single-node instance of HBase using the local filesystem. 
+    <xref linkend="configuration" /> describes setup
+    of HBase in distributed mode running on top of HDFS.</para>
+  </section>
+
+  <section xml:id="quickstart">
+    <title>Quick Start</title>
+
+    <para>This guide describes setup of a standalone HBase instance that uses
+    the local filesystem. It leads you through creating a table, inserting
+    rows via the HBase <command>shell</command>, and then cleaning
+    up and shutting down your standalone HBase instance. The below exercise
+    should take no more than ten minutes (not including download time).</para>
+
+    <section>
+      <title>Download and unpack the latest stable release.</title>
+
+      <para>Choose a download site from this list of <link
+      xlink:href="http://www.apache.org/dyn/closer.cgi/hbase/">Apache Download
+      Mirrors</link>. Click on suggested top link. This will take you to a
+      mirror of <emphasis>HBase Releases</emphasis>. Click on the folder named
+      <filename>stable</filename> and then download the file that ends in
+      <filename>.tar.gz</filename> to your local filesystem; e.g.
+      <filename>hbase-<?eval ${project.version}?>.tar.gz</filename>.</para>
+
+      <para>Decompress and untar your download and then change into the
+      unpacked directory.</para>
+
+      <para><programlisting>$ tar xfz hbase-<?eval ${project.version}?>.tar.gz
+$ cd hbase-<?eval ${project.version}?>
+</programlisting></para>
+
+      <para>At this point, you are ready to start HBase. But before starting
+      it, you might want to edit <filename>conf/hbase-site.xml</filename> and
+      set the directory you want HBase to write to,
+      <varname>hbase.rootdir</varname>. <programlisting>
+
+&lt;?xml version="1.0"?&gt;
+&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;
+&lt;configuration&gt;
+  &lt;property&gt;
+    &lt;name&gt;hbase.rootdir&lt;/name&gt;
+    &lt;value&gt;file:///DIRECTORY/hbase&lt;/value&gt;
+  &lt;/property&gt;
+&lt;/configuration&gt;
+
+</programlisting> Replace <varname>DIRECTORY</varname> in the above with a
+      path to a directory where you want HBase to store its data. By default,
+      <varname>hbase.rootdir</varname> is set to
+      <filename>/tmp/hbase-${user.name}</filename> which means you'll lose all
+      your data whenever your server reboots (Most operating systems clear
+      <filename>/tmp</filename> on restart).</para>
+    </section>
+
+    <section xml:id="start_hbase">
+      <title>Start HBase</title>
+
+      <para>Now start HBase:<programlisting>$ ./bin/start-hbase.sh
+starting Master, logging to logs/hbase-user-master-example.org.out</programlisting></para>
+
+      <para>You should now have a running standalone HBase instance. In
+      standalone mode, HBase runs all daemons in the the one JVM; i.e. both
+      the HBase and ZooKeeper daemons. HBase logs can be found in the
+      <filename>logs</filename> subdirectory. Check them out especially if
+      HBase had trouble starting.</para>
+
+      <note>
+        <title>Is <application>java</application> installed?</title>
+
+        <para>All of the above presumes a 1.6 version of Oracle
+        <application>java</application> is installed on your machine and
+        available on your path; i.e. when you type
+        <application>java</application>, you see output that describes the
+        options the java program takes (HBase requires java 6). If this is not
+        the case, HBase will not start. Install java, edit
+        <filename>conf/hbase-env.sh</filename>, uncommenting the
+        <envar>JAVA_HOME</envar> line pointing it to your java install. Then,
+        retry the steps above.</para>
+      </note>
+    </section>
+
+    <section xml:id="shell_exercises">
+      <title>Shell Exercises</title>
+
+      <para>Connect to your running HBase via the <command>shell</command>.</para>
+
+      <para><programlisting>$ ./bin/hbase shell
+HBase Shell; enter 'help&lt;RETURN&gt;' for list of supported commands.
+Type "exit&lt;RETURN&gt;" to leave the HBase Shell
+Version: 0.90.0, r1001068, Fri Sep 24 13:55:42 PDT 2010
+
+hbase(main):001:0&gt; </programlisting></para>
+
+      <para>Type <command>help</command> and then
+      <command>&lt;RETURN&gt;</command> to see a listing of shell commands and
+      options. Browse at least the paragraphs at the end of the help emission
+      for the gist of how variables and command arguments are entered into the
+      HBase shell; in particular note how table names, rows, and columns,
+      etc., must be quoted.</para>
+
+  <para>Create a table named <varname>test</varname> with a single column family named <varname>cf</varname>.
+      Verify its creation by listing all tables and then insert some
+      values.</para>
+
+      <para><programlisting>hbase(main):003:0&gt; create 'test', 'cf'
+0 row(s) in 1.2200 seconds
+hbase(main):003:0&gt; list 'test'
+..
+1 row(s) in 0.0550 seconds
+hbase(main):004:0&gt; put 'test', 'row1', 'cf:a', 'value1'
+0 row(s) in 0.0560 seconds
+hbase(main):005:0&gt; put 'test', 'row2', 'cf:b', 'value2'
+0 row(s) in 0.0370 seconds
+hbase(main):006:0&gt; put 'test', 'row3', 'cf:c', 'value3'
+0 row(s) in 0.0450 seconds</programlisting></para>
+
+      <para>Above we inserted 3 values, one at a time. The first insert is at
+      <varname>row1</varname>, column <varname>cf:a</varname> with a value of
+      <varname>value1</varname>. Columns in HBase are comprised of a column family prefix --
+      <varname>cf</varname> in this example -- followed by a colon and then a
+      column qualifier suffix (<varname>a</varname> in this case).</para>
+
+      <para>Verify the data insert.</para>
+
+      <para>Run a scan of the table by doing the following</para>
+
+      <para><programlisting>hbase(main):007:0&gt; scan 'test'
+ROW        COLUMN+CELL
+row1       column=cf:a, timestamp=1288380727188, value=value1
+row2       column=cf:b, timestamp=1288380738440, value=value2
+row3       column=cf:c, timestamp=1288380747365, value=value3
+3 row(s) in 0.0590 seconds</programlisting></para>
+
+      <para>Get a single row as follows</para>
+
+      <para><programlisting>hbase(main):008:0&gt; get 'test', 'row1'
+COLUMN      CELL
+cf:a        timestamp=1288380727188, value=value1
+1 row(s) in 0.0400 seconds</programlisting></para>
+
+      <para>Now, disable and drop your table. This will clean up all done
+      above.</para>
+
+      <para><programlisting>hbase(main):012:0&gt; disable 'test'
+0 row(s) in 1.0930 seconds
+hbase(main):013:0&gt; drop 'test'
+0 row(s) in 0.0770 seconds </programlisting></para>
+
+      <para>Exit the shell by typing exit.</para>
+
+      <para><programlisting>hbase(main):014:0&gt; exit</programlisting></para>
+    </section>
+
+    <section xml:id="stopping">
+      <title>Stopping HBase</title>
+
+      <para>Stop your hbase instance by running the stop script.</para>
+
+      <para><programlisting>$ ./bin/stop-hbase.sh
+stopping hbase...............</programlisting></para>
+    </section>
+
+    <section>
+      <title>Where to go next</title>
+
+      <para>The above described standalone setup is good for testing and
+          experiments only. Next move on to <xref linkend="configuration" /> where we'll go into
+      depth on the different HBase run modes, requirements and critical
+      configurations needed setting up a distributed HBase deploy.</para>
+    </section>
+  </section>
+
+</chapter>