Repository: zookeeper
Updated Branches:
refs/heads/branch-3.4 4a8cceb93 -> c1efa954d
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/content/xdocs/zookeeperStarted.xml
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/content/xdocs/zookeeperStarted.xml b/zookeeper-docs/src/documentation/content/xdocs/zookeeperStarted.xml
new file mode 100644
index 0000000..70c227f
--- /dev/null
+++ b/zookeeper-docs/src/documentation/content/xdocs/zookeeperStarted.xml
@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed 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.
+-->
+
+<!DOCTYPE article PUBLIC "-//OASIS//DTD Simplified DocBook XML V1.0//EN"
+"http://www.oasis-open.org/docbook/xml/simple/1.0/sdocbook.dtd">
+<article id="bk_GettStartedGuide">
+ <title>ZooKeeper Getting Started Guide</title>
+
+ <articleinfo>
+ <legalnotice>
+ <para>Licensed 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 <ulink
+ url="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</ulink>.</para>
+
+ <para>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.</para>
+ </legalnotice>
+
+ <abstract>
+ <para>This guide contains detailed information about creating
+ distributed applications that use ZooKeeper. It discusses the basic
+ operations ZooKeeper supports, and how these can be used to build
+ higher-level abstractions. It contains solutions to common tasks, a
+ troubleshooting guide, and links to other information.</para>
+ </abstract>
+ </articleinfo>
+
+ <section id="ch_GettingStarted">
+ <title>Getting Started: Coordinating Distributed Applications with
+ ZooKeeper</title>
+
+ <para>This document contains information to get you started quickly with
+ ZooKeeper. It is aimed primarily at developers hoping to try it out, and
+ contains simple installation instructions for a single ZooKeeper server, a
+ few commands to verify that it is running, and a simple programming
+ example. Finally, as a convenience, there are a few sections regarding
+ more complicated installations, for example running replicated
+ deployments, and optimizing the transaction log. However for the complete
+ instructions for commercial deployments, please refer to the <ulink
+ url="zookeeperAdmin.html">ZooKeeper
+ Administrator's Guide</ulink>.</para>
+
+ <section id="sc_Prerequisites">
+ <title>Pre-requisites</title>
+
+ <para>See <ulink url="zookeeperAdmin.html#sc_systemReq">
+ System Requirements</ulink> in the Admin guide.</para>
+ </section>
+
+ <section id="sc_Download">
+ <title>Download</title>
+
+ <para>To get a ZooKeeper distribution, download a recent
+ <ulink url="http://zookeeper.apache.org/releases.html">
+ stable</ulink> release from one of the Apache Download
+ Mirrors.</para>
+ </section>
+
+ <section id="sc_InstallingSingleMode">
+ <title>Standalone Operation</title>
+
+ <para>Setting up a ZooKeeper server in standalone mode is
+ straightforward. The server is contained in a single JAR file,
+ so installation consists of creating a configuration.</para>
+
+ <para>Once you've downloaded a stable ZooKeeper release unpack
+ it and cd to the root</para>
+
+ <para>To start ZooKeeper you need a configuration file. Here is a sample,
+ create it in <emphasis role="bold">conf/zoo.cfg</emphasis>:</para>
+
+<programlisting>
+tickTime=2000
+dataDir=/var/lib/zookeeper
+clientPort=2181
+</programlisting>
+
+ <para>This file can be called anything, but for the sake of this
+ discussion call
+ it <emphasis role="bold">conf/zoo.cfg</emphasis>. Change the
+ value of <emphasis role="bold">dataDir</emphasis> to specify an
+ existing (empty to start with) directory. Here are the meanings
+ for each of the fields:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><emphasis role="bold">tickTime</emphasis></term>
+
+ <listitem>
+ <para>the basic time unit in milliseconds used by ZooKeeper. It is
+ used to do heartbeats and the minimum session timeout will be
+ twice the tickTime.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <varlistentry>
+ <term><emphasis role="bold">dataDir</emphasis></term>
+
+ <listitem>
+ <para>the location to store the in-memory database snapshots and,
+ unless specified otherwise, the transaction log of updates to the
+ database.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis role="bold">clientPort</emphasis></term>
+
+ <listitem>
+ <para>the port to listen for client connections</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Now that you created the configuration file, you can start
+ ZooKeeper:</para>
+
+ <programlisting>bin/zkServer.sh start</programlisting>
+
+ <para>ZooKeeper logs messages using log4j -- more detail
+ available in the
+ <ulink url="zookeeperProgrammers.html#Logging">Logging</ulink>
+ section of the Programmer's Guide. You will see log messages
+ coming to the console (default) and/or a log file depending on
+ the log4j configuration.</para>
+
+ <para>The steps outlined here run ZooKeeper in standalone mode. There is
+ no replication, so if ZooKeeper process fails, the service will go down.
+ This is fine for most development situations, but to run ZooKeeper in
+ replicated mode, please see <ulink
+ url="#sc_RunningReplicatedZooKeeper">Running Replicated
+ ZooKeeper</ulink>.</para>
+ </section>
+
+ <section id="sc_FileManagement">
+ <title>Managing ZooKeeper Storage</title>
+ <para>For long running production systems ZooKeeper storage must
+ be managed externally (dataDir and logs). See the section on
+ <ulink
+ url="zookeeperAdmin.html#sc_maintenance">maintenance</ulink> for
+ more details.</para>
+ </section>
+
+ <section id="sc_ConnectingToZooKeeper">
+ <title>Connecting to ZooKeeper</title>
+
+ <programlisting>$ bin/zkCli.sh -server 127.0.0.1:2181</programlisting>
+
+ <para>This lets you perform simple, file-like operations.</para>
+
+ <para>Once you have connected, you should see something like:
+ </para>
+ <programlisting>
+<![CDATA[
+Connecting to localhost:2181
+log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper).
+log4j:WARN Please initialize the log4j system properly.
+Welcome to ZooKeeper!
+JLine support is enabled
+[zkshell: 0]
+]]> </programlisting>
+ <para>
+ From the shell, type <command>help</command> to get a listing of commands that can be executed from the client, as in:
+ </para>
+ <programlisting>
+<![CDATA[
+[zkshell: 0] help
+ZooKeeper host:port cmd args
+ get path [watch]
+ ls path [watch]
+ set path data [version]
+ delquota [-n|-b] path
+ quit
+ printwatches on|off
+ createpath data acl
+ stat path [watch]
+ listquota path
+ history
+ setAcl path acl
+ getAcl path
+ sync path
+ redo cmdno
+ addauth scheme auth
+ delete path [version]
+ setquota -n|-b val path
+
+]]> </programlisting>
+ <para>From here, you can try a few simple commands to get a feel for this simple command line interface. First, start by issuing the list command, as
+ in <command>ls</command>, yielding:
+ </para>
+ <programlisting>
+<![CDATA[
+[zkshell: 8] ls /
+[zookeeper]
+]]> </programlisting>
+ <para>Next, create a new znode by running <command>create /zk_test my_data</command>. This creates a new znode and associates the string "my_data" with the node.
+ You should see:</para>
+ <programlisting>
+<![CDATA[
+[zkshell: 9] create /zk_test my_data
+Created /zk_test
+]]> </programlisting>
+ <para> Issue another <command>ls /</command> command to see what the directory looks like:
+ </para>
+ <programlisting>
+<![CDATA[
+[zkshell: 11] ls /
+[zookeeper, zk_test]
+
+]]> </programlisting><para>
+ Notice that the zk_test directory has now been created.
+ </para>
+ <para>Next, verify that the data was associated with the znode by running the <command>get</command> command, as in:
+ </para>
+ <programlisting>
+<![CDATA[
+[zkshell: 12] get /zk_test
+my_data
+cZxid = 5
+ctime = Fri Jun 05 13:57:06 PDT 2009
+mZxid = 5
+mtime = Fri Jun 05 13:57:06 PDT 2009
+pZxid = 5
+cversion = 0
+dataVersion = 0
+aclVersion = 0
+ephemeralOwner = 0
+dataLength = 7
+numChildren = 0
+]]> </programlisting>
+ <para>We can change the data associated with zk_test by issuing the <command>set</command> command, as in:
+ </para>
+ <programlisting>
+<![CDATA[
+[zkshell: 14] set /zk_test junk
+cZxid = 5
+ctime = Fri Jun 05 13:57:06 PDT 2009
+mZxid = 6
+mtime = Fri Jun 05 14:01:52 PDT 2009
+pZxid = 5
+cversion = 0
+dataVersion = 1
+aclVersion = 0
+ephemeralOwner = 0
+dataLength = 4
+numChildren = 0
+[zkshell: 15] get /zk_test
+junk
+cZxid = 5
+ctime = Fri Jun 05 13:57:06 PDT 2009
+mZxid = 6
+mtime = Fri Jun 05 14:01:52 PDT 2009
+pZxid = 5
+cversion = 0
+dataVersion = 1
+aclVersion = 0
+ephemeralOwner = 0
+dataLength = 4
+numChildren = 0
+]]> </programlisting>
+ <para>
+ (Notice we did a <command>get</command> after setting the data and it did, indeed, change.</para>
+ <para>Finally, let's <command>delete</command> the node by issuing:
+ </para>
+ <programlisting>
+<![CDATA[
+[zkshell: 16] delete /zk_test
+[zkshell: 17] ls /
+[zookeeper]
+[zkshell: 18]
+]]></programlisting>
+ <para>That's it for now. To explore more, continue with the rest of this document and see the <ulink url="zookeeperProgrammers.html">Programmer's Guide</ulink>. </para>
+ </section>
+
+ <section id="sc_ProgrammingToZooKeeper">
+ <title>Programming to ZooKeeper</title>
+
+ <para>ZooKeeper has a Java bindings and C bindings. They are
+ functionally equivalent. The C bindings exist in two variants: single
+ threaded and multi-threaded. These differ only in how the messaging loop
+ is done. For more information, see the <ulink
+ url="zookeeperProgrammers.html#ch_programStructureWithExample">Programming
+ Examples in the ZooKeeper Programmer's Guide</ulink> for
+ sample code using of the different APIs.</para>
+ </section>
+
+ <section id="sc_RunningReplicatedZooKeeper">
+ <title>Running Replicated ZooKeeper</title>
+
+ <para>Running ZooKeeper in standalone mode is convenient for evaluation,
+ some development, and testing. But in production, you should run
+ ZooKeeper in replicated mode. A replicated group of servers in the same
+ application is called a <emphasis>quorum</emphasis>, and in replicated
+ mode, all servers in the quorum have copies of the same configuration
+ file.</para>
+ <note>
+ <para>
+ For replicated mode, a minimum of three servers are required,
+ and it is strongly recommended that you have an odd number of
+ servers. If you only have two servers, then you are in a
+ situation where if one of them fails, there are not enough
+ machines to form a majority quorum. Two servers is inherently
+ <emphasis role="bold">less</emphasis>
+ stable than a single server, because there are two single
+ points of failure.
+ </para>
+ </note>
+ <para>
+ The required
+ <emphasis role="bold">conf/zoo.cfg</emphasis>
+ file for replicated mode is similar to the one used in standalone
+ mode, but with a few differences. Here is an example:
+ </para>
+
+<programlisting>
+tickTime=2000
+dataDir=/var/lib/zookeeper
+clientPort=2181
+initLimit=5
+syncLimit=2
+server.1=zoo1:2888:3888
+server.2=zoo2:2888:3888
+server.3=zoo3:2888:3888
+</programlisting>
+
+ <para>The new entry, <emphasis role="bold">initLimit</emphasis> is
+ timeouts ZooKeeper uses to limit the length of time the ZooKeeper
+ servers in quorum have to connect to a leader. The entry <emphasis
+ role="bold">syncLimit</emphasis> limits how far out of date a server can
+ be from a leader.</para>
+
+ <para>With both of these timeouts, you specify the unit of time using
+ <emphasis role="bold">tickTime</emphasis>. In this example, the timeout
+ for initLimit is 5 ticks at 2000 milleseconds a tick, or 10
+ seconds.</para>
+
+ <para>The entries of the form <emphasis>server.X</emphasis> list the
+ servers that make up the ZooKeeper service. When the server starts up,
+ it knows which server it is by looking for the file
+ <emphasis>myid</emphasis> in the data directory. That file has the
+ contains the server number, in ASCII.</para>
+
+ <para>Finally, note the two port numbers after each server
+ name: " 2888" and "3888". Peers use the former port to connect
+ to other peers. Such a connection is necessary so that peers
+ can communicate, for example, to agree upon the order of
+ updates. More specifically, a ZooKeeper server uses this port
+ to connect followers to the leader. When a new leader arises, a
+ follower opens a TCP connection to the leader using this
+ port. Because the default leader election also uses TCP, we
+ currently require another port for leader election. This is the
+ second port in the server entry.
+ </para>
+
+ <note>
+ <para>If you want to test multiple servers on a single
+ machine, specify the servername
+ as <emphasis>localhost</emphasis> with unique quorum &
+ leader election ports (i.e. 2888:3888, 2889:3889, 2890:3890 in
+ the example above) for each server.X in that server's config
+ file. Of course separate <emphasis>dataDir</emphasis>s and
+ distinct <emphasis>clientPort</emphasis>s are also necessary
+ (in the above replicated example, running on a
+ single <emphasis>localhost</emphasis>, you would still have
+ three config files).</para>
+ <para>Please be aware that setting up multiple servers on a single
+ machine will not create any redundancy. If something were to
+ happen which caused the machine to die, all of the zookeeper
+ servers would be offline. Full redundancy requires that each
+ server have its own machine. It must be a completely separate
+ physical server. Multiple virtual machines on the same physical
+ host are still vulnerable to the complete failure of that host.</para>
+ </note>
+ </section>
+
+ <section>
+ <title>Other Optimizations</title>
+
+ <para>There are a couple of other configuration parameters that can
+ greatly increase performance:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>To get low latencies on updates it is important to
+ have a dedicated transaction log directory. By default
+ transaction logs are put in the same directory as the data
+ snapshots and <emphasis>myid</emphasis> file. The dataLogDir
+ parameters indicates a different directory to use for the
+ transaction logs.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>[tbd: what is the other config param?]</emphasis></para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+</article>
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/content/xdocs/zookeeperTutorial.xml
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/content/xdocs/zookeeperTutorial.xml b/zookeeper-docs/src/documentation/content/xdocs/zookeeperTutorial.xml
new file mode 100644
index 0000000..77cca8f
--- /dev/null
+++ b/zookeeper-docs/src/documentation/content/xdocs/zookeeperTutorial.xml
@@ -0,0 +1,712 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed 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.
+-->
+
+<!DOCTYPE article PUBLIC "-//OASIS//DTD Simplified DocBook XML V1.0//EN"
+"http://www.oasis-open.org/docbook/xml/simple/1.0/sdocbook.dtd">
+<article id="ar_Tutorial">
+ <title>Programming with ZooKeeper - A basic tutorial</title>
+
+ <articleinfo>
+ <legalnotice>
+ <para>Licensed 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 <ulink
+ url="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</ulink>.</para>
+
+ <para>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.</para>
+ </legalnotice>
+
+ <abstract>
+ <para>This article contains sample Java code for simple implementations of barrier
+ and consumers queues..</para>
+
+ </abstract>
+ </articleinfo>
+
+ <section id="ch_Introduction">
+ <title>Introduction</title>
+
+ <para>In this tutorial, we show simple implementations of barriers and
+ producer-consumer queues using ZooKeeper. We call the respective classes Barrier and Queue.
+ These examples assume that you have at least one ZooKeeper server running.</para>
+
+ <para>Both primitives use the following common excerpt of code:</para>
+
+ <programlisting>
+ static ZooKeeper zk = null;
+ static Integer mutex;
+
+ String root;
+
+ SyncPrimitive(String address) {
+ if(zk == null){
+ try {
+ System.out.println("Starting ZK:");
+ zk = new ZooKeeper(address, 3000, this);
+ mutex = new Integer(-1);
+ System.out.println("Finished starting ZK: " + zk);
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ zk = null;
+ }
+ }
+ }
+
+ synchronized public void process(WatchedEvent event) {
+ synchronized (mutex) {
+ mutex.notify();
+ }
+ }
+</programlisting>
+
+<para>Both classes extend SyncPrimitive. In this way, we execute steps that are
+common to all primitives in the constructor of SyncPrimitive. To keep the examples
+simple, we create a ZooKeeper object the first time we instantiate either a barrier
+object or a queue object, and we declare a static variable that is a reference
+to this object. The subsequent instances of Barrier and Queue check whether a
+ZooKeeper object exists. Alternatively, we could have the application creating a
+ZooKeeper object and passing it to the constructor of Barrier and Queue.</para>
+<para>
+We use the process() method to process notifications triggered due to watches.
+In the following discussion, we present code that sets watches. A watch is internal
+structure that enables ZooKeeper to notify a client of a change to a node. For example,
+if a client is waiting for other clients to leave a barrier, then it can set a watch and
+wait for modifications to a particular node, which can indicate that it is the end of the wait.
+This point becomes clear once we go over the examples.
+</para>
+</section>
+
+ <section id="sc_barriers"><title>Barriers</title>
+
+ <para>
+ A barrier is a primitive that enables a group of processes to synchronize the
+ beginning and the end of a computation. The general idea of this implementation
+ is to have a barrier node that serves the purpose of being a parent for individual
+ process nodes. Suppose that we call the barrier node "/b1". Each process "p" then
+ creates a node "/b1/p". Once enough processes have created their corresponding
+ nodes, joined processes can start the computation.
+ </para>
+
+ <para>In this example, each process instantiates a Barrier object, and its constructor takes as parameters:</para>
+
+ <itemizedlist><listitem><para>the address of a ZooKeeper server (e.g., "zoo1.foo.com:2181")</para></listitem>
+<listitem><para>the path of the barrier node on ZooKeeper (e.g., "/b1")</para></listitem>
+<listitem><para>the size of the group of processes</para></listitem>
+</itemizedlist>
+
+<para>The constructor of Barrier passes the address of the Zookeeper server to the
+constructor of the parent class. The parent class creates a ZooKeeper instance if
+one does not exist. The constructor of Barrier then creates a
+barrier node on ZooKeeper, which is the parent node of all process nodes, and
+we call root (<emphasis role="bold">Note:</emphasis> This is not the ZooKeeper root "/").</para>
+
+<programlisting>
+ /**
+ * Barrier constructor
+ *
+ * @param address
+ * @param root
+ * @param size
+ */
+ Barrier(String address, String root, int size) {
+ super(address);
+ this.root = root;
+ this.size = size;
+
+ // Create barrier node
+ if (zk != null) {
+ try {
+ Stat s = zk.exists(root, false);
+ if (s == null) {
+ zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ }
+ } catch (KeeperException e) {
+ System.out
+ .println("Keeper exception when instantiating queue: "
+ + e.toString());
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted exception");
+ }
+ }
+
+ // My node name
+ try {
+ name = new String(InetAddress.getLocalHost().getCanonicalHostName().toString());
+ } catch (UnknownHostException e) {
+ System.out.println(e.toString());
+ }
+
+ }
+</programlisting>
+<para>
+To enter the barrier, a process calls enter(). The process creates a node under
+the root to represent it, using its host name to form the node name. It then wait
+until enough processes have entered the barrier. A process does it by checking
+the number of children the root node has with "getChildren()", and waiting for
+notifications in the case it does not have enough. To receive a notification when
+there is a change to the root node, a process has to set a watch, and does it
+through the call to "getChildren()". In the code, we have that "getChildren()"
+has two parameters. The first one states the node to read from, and the second is
+a boolean flag that enables the process to set a watch. In the code the flag is true.
+</para>
+
+<programlisting>
+ /**
+ * Join barrier
+ *
+ * @return
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+
+ boolean enter() throws KeeperException, InterruptedException{
+ zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE,
+ CreateMode.EPHEMERAL_SEQUENTIAL);
+ while (true) {
+ synchronized (mutex) {
+ List<String> list = zk.getChildren(root, true);
+
+ if (list.size() < size) {
+ mutex.wait();
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+</programlisting>
+<para>
+Note that enter() throws both KeeperException and InterruptedException, so it is
+the reponsability of the application to catch and handle such exceptions.</para>
+
+<para>
+Once the computation is finished, a process calls leave() to leave the barrier.
+First it deletes its corresponding node, and then it gets the children of the root
+node. If there is at least one child, then it waits for a notification (obs: note
+that the second parameter of the call to getChildren() is true, meaning that
+ZooKeeper has to set a watch on the the root node). Upon reception of a notification,
+it checks once more whether the root node has any child.</para>
+
+<programlisting>
+ /**
+ * Wait until all reach barrier
+ *
+ * @return
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+
+ boolean leave() throws KeeperException, InterruptedException{
+ zk.delete(root + "/" + name, 0);
+ while (true) {
+ synchronized (mutex) {
+ List<String> list = zk.getChildren(root, true);
+ if (list.size() > 0) {
+ mutex.wait();
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+ }
+</programlisting>
+</section>
+<section id="sc_producerConsumerQueues"><title>Producer-Consumer Queues</title>
+<para>
+A producer-consumer queue is a distributed data estructure thata group of processes
+use to generate and consume items. Producer processes create new elements and add
+them to the queue. Consumer processes remove elements from the list, and process them.
+In this implementation, the elements are simple integers. The queue is represented
+by a root node, and to add an element to the queue, a producer process creates a new node,
+a child of the root node.
+</para>
+
+<para>
+The following excerpt of code corresponds to the constructor of the object. As
+with Barrier objects, it first calls the constructor of the parent class, SyncPrimitive,
+that creates a ZooKeeper object if one doesn't exist. It then verifies if the root
+node of the queue exists, and creates if it doesn't.
+</para>
+<programlisting>
+ /**
+ * Constructor of producer-consumer queue
+ *
+ * @param address
+ * @param name
+ */
+ Queue(String address, String name) {
+ super(address);
+ this.root = name;
+ // Create ZK node name
+ if (zk != null) {
+ try {
+ Stat s = zk.exists(root, false);
+ if (s == null) {
+ zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ }
+ } catch (KeeperException e) {
+ System.out
+ .println("Keeper exception when instantiating queue: "
+ + e.toString());
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted exception");
+ }
+ }
+ }
+</programlisting>
+
+<para>
+A producer process calls "produce()" to add an element to the queue, and passes
+an integer as an argument. To add an element to the queue, the method creates a
+new node using "create()", and uses the SEQUENCE flag to instruct ZooKeeper to
+append the value of the sequencer counter associated to the root node. In this way,
+we impose a total order on the elements of the queue, thus guaranteeing that the
+oldest element of the queue is the next one consumed.
+</para>
+
+<programlisting>
+ /**
+ * Add element to the queue.
+ *
+ * @param i
+ * @return
+ */
+
+ boolean produce(int i) throws KeeperException, InterruptedException{
+ ByteBuffer b = ByteBuffer.allocate(4);
+ byte[] value;
+
+ // Add child with value i
+ b.putInt(i);
+ value = b.array();
+ zk.create(root + "/element", value, Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT_SEQUENTIAL);
+
+ return true;
+ }
+</programlisting>
+<para>
+To consume an element, a consumer process obtains the children of the root node,
+reads the node with smallest counter value, and returns the element. Note that
+if there is a conflict, then one of the two contending processes won't be able to
+delete the node and the delete operation will throw an exception.</para>
+
+<para>
+A call to getChildren() returns the list of children in lexicographic order.
+As lexicographic order does not necessary follow the numerical order of the counter
+values, we need to decide which element is the smallest. To decide which one has
+the smallest counter value, we traverse the list, and remove the prefix "element"
+from each one.</para>
+
+<programlisting>
+ /**
+ * Remove first element from the queue.
+ *
+ * @return
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ int consume() throws KeeperException, InterruptedException{
+ int retvalue = -1;
+ Stat stat = null;
+
+ // Get the first element available
+ while (true) {
+ synchronized (mutex) {
+ List<String> list = zk.getChildren(root, true);
+ if (list.size() == 0) {
+ System.out.println("Going to wait");
+ mutex.wait();
+ } else {
+ Integer min = new Integer(list.get(0).substring(7));
+ for(String s : list){
+ Integer tempValue = new Integer(s.substring(7));
+ //System.out.println("Temporary value: " + tempValue);
+ if(tempValue < min) min = tempValue;
+ }
+ System.out.println("Temporary value: " + root + "/element" + min);
+ byte[] b = zk.getData(root + "/element" + min,
+ false, stat);
+ zk.delete(root + "/element" + min, 0);
+ ByteBuffer buffer = ByteBuffer.wrap(b);
+ retvalue = buffer.getInt();
+
+ return retvalue;
+ }
+ }
+ }
+ }
+ }
+</programlisting>
+
+</section>
+
+<section>
+<title>Complete example</title>
+<para>
+In the following section you can find a complete command line application to demonstrate the above mentioned
+recipes. Use the following command to run it.
+</para>
+<programlisting>
+ZOOBINDIR="[path_to_distro]/bin"
+. "$ZOOBINDIR"/zkEnv.sh
+java SyncPrimitive [Test Type] [ZK server] [No of elements] [Client type]
+</programlisting>
+
+<section>
+<title>Queue test</title>
+<para>Start a producer to create 100 elements</para>
+<programlisting>
+java SyncPrimitive qTest localhost 100 p
+</programlisting>
+
+<para>Start a consumer to consume 100 elements</para>
+<programlisting>
+java SyncPrimitive qTest localhost 100 c
+</programlisting>
+</section>
+
+<section>
+<title>Barrier test</title>
+<para>Start a barrier with 2 participants (start as many times as many participants you'd like to enter)</para>
+<programlisting>
+java SyncPrimitive bTest localhost 2
+</programlisting>
+</section>
+
+<section id="sc_sourceListing"><title>Source Listing</title>
+<example id="eg_SyncPrimitive_java">
+<title>SyncPrimitive.Java</title>
+<programlisting>
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+
+public class SyncPrimitive implements Watcher {
+
+ static ZooKeeper zk = null;
+ static Integer mutex;
+
+ String root;
+
+ SyncPrimitive(String address) {
+ if(zk == null){
+ try {
+ System.out.println("Starting ZK:");
+ zk = new ZooKeeper(address, 3000, this);
+ mutex = new Integer(-1);
+ System.out.println("Finished starting ZK: " + zk);
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ zk = null;
+ }
+ }
+ //else mutex = new Integer(-1);
+ }
+
+ synchronized public void process(WatchedEvent event) {
+ synchronized (mutex) {
+ //System.out.println("Process: " + event.getType());
+ mutex.notify();
+ }
+ }
+
+ /**
+ * Barrier
+ */
+ static public class Barrier extends SyncPrimitive {
+ int size;
+ String name;
+
+ /**
+ * Barrier constructor
+ *
+ * @param address
+ * @param root
+ * @param size
+ */
+ Barrier(String address, String root, int size) {
+ super(address);
+ this.root = root;
+ this.size = size;
+
+ // Create barrier node
+ if (zk != null) {
+ try {
+ Stat s = zk.exists(root, false);
+ if (s == null) {
+ zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ }
+ } catch (KeeperException e) {
+ System.out
+ .println("Keeper exception when instantiating queue: "
+ + e.toString());
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted exception");
+ }
+ }
+
+ // My node name
+ try {
+ name = new String(InetAddress.getLocalHost().getCanonicalHostName().toString());
+ } catch (UnknownHostException e) {
+ System.out.println(e.toString());
+ }
+
+ }
+
+ /**
+ * Join barrier
+ *
+ * @return
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+
+ boolean enter() throws KeeperException, InterruptedException{
+ zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE,
+ CreateMode.EPHEMERAL_SEQUENTIAL);
+ while (true) {
+ synchronized (mutex) {
+ List<String> list = zk.getChildren(root, true);
+
+ if (list.size() < size) {
+ mutex.wait();
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Wait until all reach barrier
+ *
+ * @return
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+
+ boolean leave() throws KeeperException, InterruptedException{
+ zk.delete(root + "/" + name, 0);
+ while (true) {
+ synchronized (mutex) {
+ List<String> list = zk.getChildren(root, true);
+ if (list.size() > 0) {
+ mutex.wait();
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Producer-Consumer queue
+ */
+ static public class Queue extends SyncPrimitive {
+
+ /**
+ * Constructor of producer-consumer queue
+ *
+ * @param address
+ * @param name
+ */
+ Queue(String address, String name) {
+ super(address);
+ this.root = name;
+ // Create ZK node name
+ if (zk != null) {
+ try {
+ Stat s = zk.exists(root, false);
+ if (s == null) {
+ zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ }
+ } catch (KeeperException e) {
+ System.out
+ .println("Keeper exception when instantiating queue: "
+ + e.toString());
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted exception");
+ }
+ }
+ }
+
+ /**
+ * Add element to the queue.
+ *
+ * @param i
+ * @return
+ */
+
+ boolean produce(int i) throws KeeperException, InterruptedException{
+ ByteBuffer b = ByteBuffer.allocate(4);
+ byte[] value;
+
+ // Add child with value i
+ b.putInt(i);
+ value = b.array();
+ zk.create(root + "/element", value, Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT_SEQUENTIAL);
+
+ return true;
+ }
+
+
+ /**
+ * Remove first element from the queue.
+ *
+ * @return
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ int consume() throws KeeperException, InterruptedException{
+ int retvalue = -1;
+ Stat stat = null;
+
+ // Get the first element available
+ while (true) {
+ synchronized (mutex) {
+ List<String> list = zk.getChildren(root, true);
+ if (list.size() == 0) {
+ System.out.println("Going to wait");
+ mutex.wait();
+ } else {
+ Integer min = new Integer(list.get(0).substring(7));
+ String minNode = list.get(0);
+ for(String s : list){
+ Integer tempValue = new Integer(s.substring(7));
+ //System.out.println("Temporary value: " + tempValue);
+ if(tempValue < min) {
+ min = tempValue;
+ minNode = s;
+ }
+ }
+ System.out.println("Temporary value: " + root + "/" + minNode);
+ byte[] b = zk.getData(root + "/" + minNode,
+ false, stat);
+ zk.delete(root + "/" + minNode, 0);
+ ByteBuffer buffer = ByteBuffer.wrap(b);
+ retvalue = buffer.getInt();
+
+ return retvalue;
+ }
+ }
+ }
+ }
+ }
+
+ public static void main(String args[]) {
+ if (args[0].equals("qTest"))
+ queueTest(args);
+ else
+ barrierTest(args);
+
+ }
+
+ public static void queueTest(String args[]) {
+ Queue q = new Queue(args[1], "/app1");
+
+ System.out.println("Input: " + args[1]);
+ int i;
+ Integer max = new Integer(args[2]);
+
+ if (args[3].equals("p")) {
+ System.out.println("Producer");
+ for (i = 0; i < max; i++)
+ try{
+ q.produce(10 + i);
+ } catch (KeeperException e){
+
+ } catch (InterruptedException e){
+
+ }
+ } else {
+ System.out.println("Consumer");
+
+ for (i = 0; i < max; i++) {
+ try{
+ int r = q.consume();
+ System.out.println("Item: " + r);
+ } catch (KeeperException e){
+ i--;
+ } catch (InterruptedException e){
+
+ }
+ }
+ }
+ }
+
+ public static void barrierTest(String args[]) {
+ Barrier b = new Barrier(args[1], "/b1", new Integer(args[2]));
+ try{
+ boolean flag = b.enter();
+ System.out.println("Entered barrier: " + args[2]);
+ if(!flag) System.out.println("Error when entering the barrier");
+ } catch (KeeperException e){
+
+ } catch (InterruptedException e){
+
+ }
+
+ // Generate random integer
+ Random rand = new Random();
+ int r = rand.nextInt(100);
+ // Loop for rand iterations
+ for (int i = 0; i < r; i++) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+
+ }
+ }
+ try{
+ b.leave();
+ } catch (KeeperException e){
+
+ } catch (InterruptedException e){
+
+ }
+ System.out.println("Left barrier");
+ }
+}
+</programlisting></example>
+</section>
+</section>
+
+</article>
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/2pc.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/2pc.jpg b/zookeeper-docs/src/documentation/resources/images/2pc.jpg
new file mode 100755
index 0000000..fe4488f
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/2pc.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/bk-overview.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/bk-overview.jpg b/zookeeper-docs/src/documentation/resources/images/bk-overview.jpg
new file mode 100644
index 0000000..6e12fb4
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/bk-overview.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/favicon.ico
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/favicon.ico b/zookeeper-docs/src/documentation/resources/images/favicon.ico
new file mode 100644
index 0000000..161bcf7
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/favicon.ico differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/hadoop-logo.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/hadoop-logo.jpg b/zookeeper-docs/src/documentation/resources/images/hadoop-logo.jpg
new file mode 100644
index 0000000..809525d
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/hadoop-logo.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/state_dia.dia
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/state_dia.dia b/zookeeper-docs/src/documentation/resources/images/state_dia.dia
new file mode 100755
index 0000000..4a58a00
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/state_dia.dia differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/state_dia.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/state_dia.jpg b/zookeeper-docs/src/documentation/resources/images/state_dia.jpg
new file mode 100755
index 0000000..b6f4a8b
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/state_dia.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zkarch.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zkarch.jpg b/zookeeper-docs/src/documentation/resources/images/zkarch.jpg
new file mode 100644
index 0000000..a0e5fcc
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zkarch.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zkcomponents.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zkcomponents.jpg b/zookeeper-docs/src/documentation/resources/images/zkcomponents.jpg
new file mode 100644
index 0000000..7690578
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zkcomponents.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zknamespace.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zknamespace.jpg b/zookeeper-docs/src/documentation/resources/images/zknamespace.jpg
new file mode 100644
index 0000000..05534bc
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zknamespace.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zkperfRW-3.2.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zkperfRW-3.2.jpg b/zookeeper-docs/src/documentation/resources/images/zkperfRW-3.2.jpg
new file mode 100644
index 0000000..594b50b
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zkperfRW-3.2.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zkperfRW.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zkperfRW.jpg b/zookeeper-docs/src/documentation/resources/images/zkperfRW.jpg
new file mode 100644
index 0000000..ad3019f
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zkperfRW.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zkperfreliability.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zkperfreliability.jpg b/zookeeper-docs/src/documentation/resources/images/zkperfreliability.jpg
new file mode 100644
index 0000000..232bba8
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zkperfreliability.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zkservice.jpg
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zkservice.jpg b/zookeeper-docs/src/documentation/resources/images/zkservice.jpg
new file mode 100644
index 0000000..1ec9154
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zkservice.jpg differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/resources/images/zookeeper_small.gif
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/resources/images/zookeeper_small.gif b/zookeeper-docs/src/documentation/resources/images/zookeeper_small.gif
new file mode 100644
index 0000000..4e8014f
Binary files /dev/null and b/zookeeper-docs/src/documentation/resources/images/zookeeper_small.gif differ
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/src/documentation/skinconf.xml
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/skinconf.xml b/zookeeper-docs/src/documentation/skinconf.xml
new file mode 100644
index 0000000..43f3a49
--- /dev/null
+++ b/zookeeper-docs/src/documentation/skinconf.xml
@@ -0,0 +1,360 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed 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.
+-->
+
+<!--
+Skin configuration file. This file contains details of your project,
+which will be used to configure the chosen Forrest skin.
+-->
+
+<!DOCTYPE skinconfig PUBLIC "-//APACHE//DTD Skin Configuration V0.6-3//EN" "http://forrest.apache.org/dtd/skinconfig-v06-3.dtd">
+<skinconfig>
+ <!-- To enable lucene search add provider="lucene" (default is google).
+ Add box-location="alt" to move the search box to an alternate location
+ (if the skin supports it) and box-location="all" to show it in all
+ available locations on the page. Remove the <search> element to show
+ no search box. @domain will enable sitesearch for the specific domain with google.
+ In other words google will search the @domain for the query string.
+
+ -->
+ <search name="ZooKeeper" domain="zookeeper.apache.org" provider="google"/>
+
+ <!-- Disable the print link? If enabled, invalid HTML 4.0.1 -->
+ <disable-print-link>true</disable-print-link>
+ <!-- Disable the PDF link? -->
+ <disable-pdf-link>false</disable-pdf-link>
+ <!-- Disable the POD link? -->
+ <disable-pod-link>true</disable-pod-link>
+ <!-- Disable the Text link? FIXME: NOT YET IMPLEMENETED. -->
+ <disable-txt-link>true</disable-txt-link>
+ <!-- Disable the xml source link? -->
+ <!-- The xml source link makes it possible to access the xml rendition
+ of the source frim the html page, and to have it generated statically.
+ This can be used to enable other sites and services to reuse the
+ xml format for their uses. Keep this disabled if you don't want other
+ sites to easily reuse your pages.-->
+ <disable-xml-link>true</disable-xml-link>
+
+ <!-- Disable navigation icons on all external links? -->
+ <disable-external-link-image>true</disable-external-link-image>
+
+ <!-- Disable w3c compliance links?
+ Use e.g. align="center" to move the compliance links logos to
+ an alternate location default is left.
+ (if the skin supports it) -->
+ <disable-compliance-links>true</disable-compliance-links>
+
+ <!-- Render mailto: links unrecognisable by spam harvesters? -->
+ <obfuscate-mail-links>false</obfuscate-mail-links>
+
+ <!-- Disable the javascript facility to change the font size -->
+ <disable-font-script>true</disable-font-script>
+
+ <!-- project logo -->
+ <project-name>ZooKeeper</project-name>
+ <project-description>ZooKeeper: distributed coordination</project-description>
+ <project-url>http://zookeeper.apache.org/</project-url>
+ <project-logo>images/zookeeper_small.gif</project-logo>
+
+ <!-- group logo -->
+ <group-name>Hadoop</group-name>
+ <group-description>Apache Hadoop</group-description>
+ <group-url>http://hadoop.apache.org/</group-url>
+ <group-logo>images/hadoop-logo.jpg</group-logo>
+
+ <!-- optional host logo (e.g. sourceforge logo)
+ default skin: renders it at the bottom-left corner -->
+ <host-url></host-url>
+ <host-logo></host-logo>
+
+ <!-- relative url of a favicon file, normally favicon.ico -->
+ <favicon-url>images/favicon.ico</favicon-url>
+
+ <!-- The following are used to construct a copyright statement -->
+ <year></year>
+ <vendor>The Apache Software Foundation.</vendor>
+ <copyright-link>http://www.apache.org/licenses/</copyright-link>
+
+ <!-- Some skins use this to form a 'breadcrumb trail' of links.
+ Use location="alt" to move the trail to an alternate location
+ (if the skin supports it).
+ Omit the location attribute to display the trail in the default location.
+ Use location="none" to not display the trail (if the skin supports it).
+ For some skins just set the attributes to blank.
+ -->
+ <trail>
+ <link1 name="Apache" href="http://www.apache.org/"/>
+ <link2 name="ZooKeeper" href="http://zookeeper.apache.org/"/>
+ <link3 name="ZooKeeper" href="http://zookeeper.apache.org/"/>
+ </trail>
+
+ <!-- Configure the TOC, i.e. the Table of Contents.
+ @max-depth
+ how many "section" levels need to be included in the
+ generated Table of Contents (TOC).
+ @min-sections
+ Minimum required to create a TOC.
+ @location ("page","menu","page,menu", "none")
+ Where to show the TOC.
+ -->
+ <toc max-depth="2" min-sections="1" location="page"/>
+
+ <!-- Heading types can be clean|underlined|boxed -->
+ <headings type="clean"/>
+
+ <!-- The optional feedback element will be used to construct a
+ feedback link in the footer with the page pathname appended:
+ <a href="@href">{@to}</a>
+ <feedback to="webmaster@foo.com"
+ href="mailto:webmaster@foo.com?subject=Feedback " >
+ Send feedback about the website to:
+ </feedback>
+ -->
+ <!--
+ extra-css - here you can define custom css-elements that are
+ a. overriding the fallback elements or
+ b. adding the css definition from new elements that you may have
+ used in your documentation.
+ -->
+ <extra-css>
+ <!--Example of b.
+ To define the css definition of a new element that you may have used
+ in the class attribute of a <p> node.
+ e.g. <p class="quote"/>
+ -->
+ p.quote {
+ margin-left: 2em;
+ padding: .5em;
+ background-color: #f0f0f0;
+ font-family: monospace;
+ }
+
+ pre.code {
+ margin-left: 0em;
+ padding: 0.5em;
+ background-color: #f0f0f0;
+ font-family: monospace;
+ }
+
+<!-- patricks
+ .code {
+ font-family: "Courier New", Courier, monospace;
+ font-size: 110%;
+ }
+-->
+
+ </extra-css>
+
+ <colors>
+ <!-- These values are used for the generated CSS files. -->
+
+ <!-- Krysalis -->
+<!--
+ <color name="header" value="#FFFFFF"/>
+
+ <color name="tab-selected" value="#a5b6c6" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="tab-unselected" value="#F7F7F7" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="subtab-selected" value="#a5b6c6" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="subtab-unselected" value="#a5b6c6" link="#000000" vlink="#000000" hlink="#000000"/>
+
+ <color name="heading" value="#a5b6c6"/>
+ <color name="subheading" value="#CFDCED"/>
+
+ <color name="navstrip" value="#CFDCED" font="#000000" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="toolbox" value="#a5b6c6"/>
+ <color name="border" value="#a5b6c6"/>
+
+ <color name="menu" value="#F7F7F7" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="dialog" value="#F7F7F7"/>
+
+ <color name="body" value="#ffffff" link="#0F3660" vlink="#009999" hlink="#000066"/>
+
+ <color name="table" value="#a5b6c6"/>
+ <color name="table-cell" value="#ffffff"/>
+ <color name="highlight" value="#ffff00"/>
+ <color name="fixme" value="#cc6600"/>
+ <color name="note" value="#006699"/>
+ <color name="warning" value="#990000"/>
+ <color name="code" value="#a5b6c6"/>
+
+ <color name="footer" value="#a5b6c6"/>
+-->
+
+ <!-- Forrest -->
+<!--
+ <color name="header" value="#294563"/>
+
+ <color name="tab-selected" value="#4a6d8c" link="#0F3660" vlink="#0F3660" hlink="#000066"/>
+ <color name="tab-unselected" value="#b5c7e7" link="#0F3660" vlink="#0F3660" hlink="#000066"/>
+ <color name="subtab-selected" value="#4a6d8c" link="#0F3660" vlink="#0F3660" hlink="#000066"/>
+ <color name="subtab-unselected" value="#4a6d8c" link="#0F3660" vlink="#0F3660" hlink="#000066"/>
+
+ <color name="heading" value="#294563"/>
+ <color name="subheading" value="#4a6d8c"/>
+
+ <color name="navstrip" value="#cedfef" font="#0F3660" link="#0F3660" vlink="#0F3660" hlink="#000066"/>
+ <color name="toolbox" value="#4a6d8c"/>
+ <color name="border" value="#294563"/>
+
+ <color name="menu" value="#4a6d8c" font="#cedfef" link="#ffffff" vlink="#ffffff" hlink="#ffcf00"/>
+ <color name="dialog" value="#4a6d8c"/>
+
+ <color name="body" value="#ffffff" link="#0F3660" vlink="#009999" hlink="#000066"/>
+
+ <color name="table" value="#7099C5"/>
+ <color name="table-cell" value="#f0f0ff"/>
+ <color name="highlight" value="#ffff00"/>
+ <color name="fixme" value="#cc6600"/>
+ <color name="note" value="#006699"/>
+ <color name="warning" value="#990000"/>
+ <color name="code" value="#CFDCED"/>
+
+ <color name="footer" value="#cedfef"/>
+-->
+
+ <!-- Collabnet -->
+<!--
+ <color name="header" value="#003366"/>
+
+ <color name="tab-selected" value="#dddddd" link="#555555" vlink="#555555" hlink="#555555"/>
+ <color name="tab-unselected" value="#999999" link="#ffffff" vlink="#ffffff" hlink="#ffffff"/>
+ <color name="subtab-selected" value="#cccccc" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="subtab-unselected" value="#cccccc" link="#555555" vlink="#555555" hlink="#555555"/>
+
+ <color name="heading" value="#003366"/>
+ <color name="subheading" value="#888888"/>
+
+ <color name="navstrip" value="#dddddd" font="#555555"/>
+ <color name="toolbox" value="#dddddd" font="#555555"/>
+ <color name="border" value="#999999"/>
+
+ <color name="menu" value="#ffffff"/>
+ <color name="dialog" value="#eeeeee"/>
+
+ <color name="body" value="#ffffff"/>
+
+ <color name="table" value="#ccc"/>
+ <color name="table-cell" value="#ffffff"/>
+ <color name="highlight" value="#ffff00"/>
+ <color name="fixme" value="#cc6600"/>
+ <color name="note" value="#006699"/>
+ <color name="warning" value="#990000"/>
+ <color name="code" value="#003366"/>
+
+ <color name="footer" value="#ffffff"/>
+-->
+ <!-- Lenya using pelt-->
+<!--
+ <color name="header" value="#ffffff"/>
+
+ <color name="tab-selected" value="#4C6C8F" link="#ffffff" vlink="#ffffff" hlink="#ffffff"/>
+ <color name="tab-unselected" value="#E5E4D9" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="subtab-selected" value="#000000" link="#000000" vlink="#000000" hlink="#000000"/>
+ <color name="subtab-unselected" value="#E5E4D9" link="#000000" vlink="#000000" hlink="#000000"/>
+
+ <color name="heading" value="#E5E4D9"/>
+ <color name="subheading" value="#000000"/>
+ <color name="published" value="#4C6C8F" font="#FFFFFF"/>
+ <color name="feedback" value="#4C6C8F" font="#FFFFFF" align="center"/>
+ <color name="navstrip" value="#E5E4D9" font="#000000"/>
+
+ <color name="toolbox" value="#CFDCED" font="#000000"/>
+
+ <color name="border" value="#999999"/>
+ <color name="menu" value="#4C6C8F" font="#ffffff" link="#ffffff" vlink="#ffffff" hlink="#ffffff" current="#FFCC33" />
+ <color name="menuheading" value="#cfdced" font="#000000" />
+ <color name="searchbox" value="#E5E4D9" font="#000000"/>
+
+ <color name="dialog" value="#CFDCED"/>
+ <color name="body" value="#ffffff" />
+
+ <color name="table" value="#ccc"/>
+ <color name="table-cell" value="#ffffff"/>
+ <color name="highlight" value="#ffff00"/>
+ <color name="fixme" value="#cc6600"/>
+ <color name="note" value="#006699"/>
+ <color name="warning" value="#990000"/>
+ <color name="code" value="#003366"/>
+
+ <color name="footer" value="#E5E4D9"/>
+-->
+ </colors>
+
+ <!-- Settings specific to PDF output. -->
+ <pdf>
+ <!--
+ Supported page sizes are a0, a1, a2, a3, a4, a5, executive,
+ folio, legal, ledger, letter, quarto, tabloid (default letter).
+ Supported page orientations are portrait, landscape (default
+ portrait).
+ Supported text alignments are left, right, justify (default left).
+ -->
+ <page size="letter" orientation="portrait" text-align="left"/>
+
+ <!--
+ Margins can be specified for top, bottom, inner, and outer
+ edges. If double-sided="false", the inner edge is always left
+ and the outer is always right. If double-sided="true", the
+ inner edge will be left on odd pages, right on even pages,
+ the outer edge vice versa.
+ Specified below are the default settings.
+ -->
+ <margins double-sided="false">
+ <top>1in</top>
+ <bottom>1in</bottom>
+ <inner>1.25in</inner>
+ <outer>1in</outer>
+ </margins>
+
+ <!--
+ Print the URL text next to all links going outside the file
+ -->
+ <show-external-urls>false</show-external-urls>
+
+ <!--
+ Disable the copyright footer on each page of the PDF.
+ A footer is composed for each page. By default, a "credit" with role=pdf
+ will be used, as explained below. Otherwise a copyright statement
+ will be generated. This latter can be disabled.
+ -->
+ <disable-copyright-footer>false</disable-copyright-footer>
+ </pdf>
+
+ <!-- Credits are typically rendered as a set of small clickable
+ images in the page footer.
+ Use box-location="alt" to move the credit to an alternate location
+ (if the skin supports it).
+ -->
+ <credits>
+ <credit box-location="alt">
+ <name>Built with Apache Forrest</name>
+ <url>http://forrest.apache.org/</url>
+ <image>images/built-with-forrest-button.png</image>
+ <width>88</width>
+ <height>31</height>
+ </credit>
+ <!-- A credit with @role="pdf" will be used to compose a footer
+ for each page in the PDF, using either "name" or "url" or both.
+ -->
+ <!--
+ <credit role="pdf">
+ <name>Built with Apache Forrest</name>
+ <url>http://forrest.apache.org/</url>
+ </credit>
+ -->
+ </credits>
+
+</skinconfig>
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-docs/status.xml
----------------------------------------------------------------------
diff --git a/zookeeper-docs/status.xml b/zookeeper-docs/status.xml
new file mode 100644
index 0000000..3ac3fda
--- /dev/null
+++ b/zookeeper-docs/status.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2002-2004 The Apache Software Foundation
+
+ Licensed 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.
+-->
+<status>
+
+ <developers>
+ <person name="Joe Bloggs" email="joe@joescompany.org" id="JB" />
+ <!-- Add more people here -->
+ </developers>
+
+ <changes>
+ <!-- Add new releases here -->
+ <release version="0.1" date="unreleased">
+ <!-- Some action types have associated images. By default, images are
+ defined for 'add', 'fix', 'remove', 'update' and 'hack'. If you add
+ src/documentation/resources/images/<foo>.jpg images, these will
+ automatically be used for entries of type <foo>. -->
+
+ <action dev="JB" type="add" context="admin">
+ Initial Import
+ </action>
+ <!-- Sample action:
+ <action dev="JB" type="fix" due-to="Joe Contributor"
+ due-to-email="joec@apache.org" fixes-bug="123">
+ Fixed a bug in the Foo class.
+ </action>
+ -->
+ </release>
+ </changes>
+
+ <todo>
+ <actions priority="high">
+ <action context="docs" dev="JB">
+ Customize this template project with your project's details. This
+ TODO list is generated from 'status.xml'.
+ </action>
+ <action context="docs" dev="JB">
+ Add lots of content. XML content goes in
+ <code>src/documentation/content/xdocs</code>, or wherever the
+ <code>${project.xdocs-dir}</code> property (set in
+ <code>forrest.properties</code>) points.
+ </action>
+ <action context="feedback" dev="JB">
+ Mail <link
+ href="mailto:forrest-dev@xml.apache.org">forrest-dev@xml.apache.org</link>
+ with feedback.
+ </action>
+ </actions>
+ <!-- Add todo items. @context is an arbitrary string. Eg:
+ <actions priority="high">
+ <action context="code" dev="SN">
+ </action>
+ </actions>
+ <actions priority="medium">
+ <action context="docs" dev="open">
+ </action>
+ </actions>
+ -->
+ </todo>
+
+</status>
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/c1efa954/zookeeper-it/.empty
----------------------------------------------------------------------
diff --git a/zookeeper-it/.empty b/zookeeper-it/.empty
new file mode 100644
index 0000000..e69de29
|